diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-05-16 17:56:23 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-05-16 17:56:36 +0200 |
| commit | a741bd6b83d1e374c8218b5439e26522499cc4ae (patch) | |
| tree | 796ef8b8ae2186a082f37a2aa4732c9bba7d2bdf /src/eval | |
| parent | 6536e9e069616b862ebb774c7bef1b886c069350 (diff) | |
Absolute paths
Diffstat (limited to 'src/eval')
| -rw-r--r-- | src/eval/func.rs | 21 | ||||
| -rw-r--r-- | src/eval/mod.rs | 8 |
2 files changed, 23 insertions, 6 deletions
diff --git a/src/eval/func.rs b/src/eval/func.rs index 4c5761ab..f15b0241 100644 --- a/src/eval/func.rs +++ b/src/eval/func.rs @@ -5,6 +5,7 @@ use std::sync::Arc; use super::{Args, Eval, Flow, Scope, Scopes, Value}; use crate::diag::{StrResult, TypResult}; use crate::model::{Content, NodeId, StyleMap}; +use crate::source::SourceId; use crate::syntax::ast::Expr; use crate::util::EcoString; use crate::Context; @@ -174,6 +175,8 @@ pub trait Node: 'static { /// A user-defined closure. #[derive(Hash)] pub struct Closure { + /// The location where the closure was defined. + pub location: Option<SourceId>, /// The name of the closure. pub name: Option<EcoString>, /// Captured values from outer scopes. @@ -212,18 +215,28 @@ impl Closure { // Backup the old control flow state. let prev_flow = ctx.flow.take(); + let detached = ctx.route.is_empty(); + if detached { + ctx.route = self.location.into_iter().collect(); + } // Evaluate the body. - let mut value = self.body.eval(ctx, &mut scp)?; + let result = self.body.eval(ctx, &mut scp); + + // Restore the old control flow state. + let flow = std::mem::replace(&mut ctx.flow, prev_flow); + if detached { + ctx.route.clear(); + } // Handle control flow. - match std::mem::replace(&mut ctx.flow, prev_flow) { - Some(Flow::Return(_, Some(explicit))) => value = explicit, + match flow { + Some(Flow::Return(_, Some(explicit))) => return Ok(explicit), Some(Flow::Return(_, None)) => {} Some(flow) => return Err(flow.forbidden())?, None => {} } - Ok(value) + result } } diff --git a/src/eval/mod.rs b/src/eval/mod.rs index b35cf1ef..79060137 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -707,6 +707,7 @@ impl Eval for ClosureExpr { // Define the actual function. Ok(Value::Func(Func::from_closure(Closure { + location: ctx.route.last().copied(), name, captured, params, @@ -765,6 +766,7 @@ impl Eval for ShowExpr { let body = self.body(); let span = body.span(); let func = Func::from_closure(Closure { + location: ctx.route.last().copied(), name: None, captured, params, @@ -945,9 +947,11 @@ impl Eval for IncludeExpr { /// Process an import of a module relative to the current location. fn import(ctx: &mut Context, path: &str, span: Span) -> TypResult<Module> { // Load the source file. - let full = ctx.complete_path(path); + let full = ctx.locate(&path).at(span)?; let id = ctx.sources.load(&full).map_err(|err| match err.kind() { - std::io::ErrorKind::NotFound => error!(span, "file not found"), + std::io::ErrorKind::NotFound => { + error!(span, "file not found (searched at {})", full.display()) + } _ => error!(span, "failed to load source file ({})", err), })?; |
