diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-11-23 10:54:25 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-11-23 12:00:06 +0100 |
| commit | b2a3d3f235fb5a23322435b854460f52db772114 (patch) | |
| tree | 441ded5e4fcc0a702fe877fc6a3e3fedaaacabb5 /src/model | |
| parent | 65aa27014d090628cfef14b0679d86dd611188b9 (diff) | |
More general evaluation interface
Diffstat (limited to 'src/model')
| -rw-r--r-- | src/model/eval.rs | 25 | ||||
| -rw-r--r-- | src/model/func.rs | 8 | ||||
| -rw-r--r-- | src/model/items.rs | 4 | ||||
| -rw-r--r-- | src/model/vm.rs | 8 |
4 files changed, 23 insertions, 22 deletions
diff --git a/src/model/eval.rs b/src/model/eval.rs index 7c0cffb5..7f2cea63 100644 --- a/src/model/eval.rs +++ b/src/model/eval.rs @@ -13,7 +13,7 @@ use super::{ use crate::diag::{bail, error, At, SourceResult, StrResult, Trace, Tracepoint}; use crate::geom::{Abs, Angle, Em, Fr, Ratio}; use crate::syntax::ast::AstNode; -use crate::syntax::{ast, SourceId, Span, Spanned, Unit}; +use crate::syntax::{ast, Source, SourceId, Span, Spanned, Unit}; use crate::util::{format_eco, EcoString}; use crate::World; @@ -26,9 +26,10 @@ use crate::World; pub fn eval( world: Tracked<dyn World>, route: Tracked<Route>, - id: SourceId, + source: &Source, ) -> SourceResult<Module> { // Prevent cyclic evaluation. + let id = source.id(); if route.contains(id) { let path = world.source(id).path().display(); panic!("Tried to cyclicly evaluate {}", path); @@ -36,11 +37,10 @@ pub fn eval( // Evaluate the module. let route = unsafe { Route::insert(route, id) }; - let ast = world.source(id).ast()?; let std = &world.config().scope; let scopes = Scopes::new(Some(std)); - let mut vm = Vm::new(world, route.track(), Some(id), scopes); - let result = ast.eval(&mut vm); + let mut vm = Vm::new(world, route.track(), id, scopes); + let result = source.ast()?.eval(&mut vm); // Handle control flow. if let Some(flow) = vm.flow { @@ -59,9 +59,9 @@ pub struct Route { } impl Route { - /// Create a new, empty route. - pub fn new(id: Option<SourceId>) -> Self { - Self { id, parent: None } + /// Create a new route with just one entry. + pub fn new(id: SourceId) -> Self { + Self { id: Some(id), parent: None } } /// Insert a new id into the route. @@ -94,7 +94,7 @@ pub struct Module { } /// Evaluate an expression. -pub trait Eval { +pub(super) trait Eval { /// The output of evaluating the expression. type Output; @@ -1038,10 +1038,9 @@ fn import(vm: &mut Vm, path: &str, span: Span) -> SourceResult<Module> { } // Evaluate the file. - let module = - eval(vm.world, vm.route, id).trace(vm.world, || Tracepoint::Import, span)?; - - Ok(module) + let source = vm.world.source(id); + let point = || Tracepoint::Import; + eval(vm.world, vm.route, source).trace(vm.world, point, span) } impl Eval for ast::LoopBreak { diff --git a/src/model/func.rs b/src/model/func.rs index f313dcda..d84a8170 100644 --- a/src/model/func.rs +++ b/src/model/func.rs @@ -97,7 +97,9 @@ impl Func { args: Args, ) -> SourceResult<Value> { let route = Route::default(); - let mut vm = Vm::new(world, route.track(), None, Scopes::new(None)); + let id = SourceId::detached(); + let scopes = Scopes::new(None); + let mut vm = Vm::new(world, route.track(), id, scopes); self.call(&mut vm, args) } @@ -178,7 +180,7 @@ impl Hash for Native { #[derive(Hash)] pub struct Closure { /// The source file where the closure was defined. - pub location: Option<SourceId>, + pub location: SourceId, /// The name of the closure. pub name: Option<EcoString>, /// Captured values from outer scopes. @@ -219,7 +221,7 @@ impl Closure { } // Determine the route inside the closure. - let detached = vm.location.is_none(); + let detached = vm.location.is_detached(); let fresh = Route::new(self.location); let route = if detached { fresh.track() } else { vm.route }; diff --git a/src/model/items.rs b/src/model/items.rs index 771756fe..50ea8b60 100644 --- a/src/model/items.rs +++ b/src/model/items.rs @@ -42,7 +42,7 @@ macro_rules! item { #[derive(Copy, Clone)] pub struct LangItems { /// The root layout function. - pub root: fn( + pub layout: fn( content: &Content, world: Tracked<dyn World>, styles: StyleChain, @@ -104,7 +104,7 @@ impl Debug for LangItems { impl Hash for LangItems { fn hash<H: Hasher>(&self, state: &mut H) { - (self.root as usize).hash(state); + (self.layout as usize).hash(state); (self.em as usize).hash(state); (self.dir as usize).hash(state); self.space.hash(state); diff --git a/src/model/vm.rs b/src/model/vm.rs index db0bf77c..28885f29 100644 --- a/src/model/vm.rs +++ b/src/model/vm.rs @@ -15,7 +15,7 @@ pub struct Vm<'a> { /// The route of source ids the VM took to reach its current location. pub route: Tracked<'a, Route>, /// The current location. - pub location: Option<SourceId>, + pub location: SourceId, /// The stack of scopes. pub scopes: Scopes<'a>, /// A control flow event that is currently happening. @@ -29,7 +29,7 @@ impl<'a> Vm<'a> { pub fn new( world: Tracked<'a, dyn World>, route: Tracked<'a, Route>, - location: Option<SourceId>, + location: SourceId, scopes: Scopes<'a>, ) -> Self { Self { @@ -45,12 +45,12 @@ impl<'a> Vm<'a> { /// Resolve a user-entered path to be relative to the compilation /// environment's root. pub fn locate(&self, path: &str) -> StrResult<PathBuf> { - if let Some(id) = self.location { + if !self.location.is_detached() { if let Some(path) = path.strip_prefix('/') { return Ok(self.world.config().root.join(path).normalize()); } - if let Some(dir) = self.world.source(id).path().parent() { + if let Some(dir) = self.world.source(self.location).path().parent() { return Ok(dir.join(path).normalize()); } } |
