diff options
| author | Laurenz <laurmaedje@gmail.com> | 2023-03-17 18:51:42 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2023-03-17 18:51:42 +0100 |
| commit | 9315e2f08ea20d021bf7a34c1aa9453499d063f7 (patch) | |
| tree | 7970f1bff307e530c606c6a042954d24b5579d5f /src | |
| parent | 59903270dc5a21c65df8a4d88068662287918b4c (diff) | |
Make parameters traceable
Diffstat (limited to 'src')
| -rw-r--r-- | src/eval/func.rs | 29 | ||||
| -rw-r--r-- | src/eval/mod.rs | 8 |
2 files changed, 18 insertions, 19 deletions
diff --git a/src/eval/func.rs b/src/eval/func.rs index af80ac92..14da5ff0 100644 --- a/src/eval/func.rs +++ b/src/eval/func.rs @@ -5,7 +5,6 @@ use std::hash::{Hash, Hasher}; use std::sync::Arc; use comemo::{Prehashed, Track, Tracked, TrackedMut}; -use ecow::EcoString; use once_cell::sync::Lazy; use super::{ @@ -14,7 +13,7 @@ use super::{ }; use crate::diag::{bail, SourceResult, StrResult}; use crate::model::{Introspector, NodeId, Selector, StabilityProvider, StyleMap, Vt}; -use crate::syntax::ast::{self, AstNode, Expr}; +use crate::syntax::ast::{self, AstNode, Expr, Ident}; use crate::syntax::{SourceId, Span, SyntaxNode}; use crate::util::hash128; use crate::World; @@ -294,14 +293,14 @@ pub(super) struct Closure { /// The source file where the closure was defined. pub location: SourceId, /// The name of the closure. - pub name: Option<EcoString>, + pub name: Option<Ident>, /// Captured values from outer scopes. pub captured: Scope, /// The parameter names and default values. Parameters with default value /// are named parameters. - pub params: Vec<(EcoString, Option<Value>)>, + pub params: Vec<(Ident, Option<Value>)>, /// The name of an argument sink where remaining arguments are placed. - pub sink: Option<EcoString>, + pub sink: Option<Ident>, /// The expression the closure should evaluate to. pub body: Expr, } @@ -329,14 +328,19 @@ impl Closure { let mut scopes = Scopes::new(None); scopes.top = closure.captured.clone(); + // Evaluate the body. + let vt = Vt { world, tracer, provider, introspector }; + let mut vm = Vm::new(vt, route, closure.location, scopes); + vm.depth = depth; + // Provide the closure itself for recursive calls. if let Some(name) = &closure.name { - scopes.top.define(name.clone(), Value::Func(this.clone())); + vm.define(name.clone(), Value::Func(this.clone())); } // Parse the arguments according to the parameter list. for (param, default) in &closure.params { - scopes.top.define( + vm.define( param.clone(), match default { Some(default) => { @@ -349,20 +353,15 @@ impl Closure { // Put the remaining arguments into the sink. if let Some(sink) = &closure.sink { - scopes.top.define(sink.clone(), args.take()); + vm.define(sink.clone(), args.take()); } // Ensure all arguments have been used. args.finish()?; - // Evaluate the body. - let vt = Vt { world, tracer, provider, introspector }; - let mut sub = Vm::new(vt, route, closure.location, scopes); - sub.depth = depth; - // Handle control flow. - let result = closure.body.eval(&mut sub); - match sub.flow { + let result = closure.body.eval(&mut vm); + match vm.flow { Some(Flow::Return(_, Some(explicit))) => return Ok(explicit), Some(Flow::Return(_, None)) => {} Some(flow) => bail!(flow.forbidden()), diff --git a/src/eval/mod.rs b/src/eval/mod.rs index a7f4b825..e6da6cba 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -1140,7 +1140,7 @@ impl Eval for ast::Closure { fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> { // The closure's name is defined by its let binding if there's one. - let name = self.name().map(ast::Ident::take); + let name = self.name(); // Collect captured variables. let captured = { @@ -1156,16 +1156,16 @@ impl Eval for ast::Closure { for param in self.params() { match param { ast::Param::Pos(name) => { - params.push((name.take(), None)); + params.push((name, None)); } ast::Param::Named(named) => { - params.push((named.name().take(), Some(named.expr().eval(vm)?))); + params.push((named.name(), Some(named.expr().eval(vm)?))); } ast::Param::Sink(name) => { if sink.is_some() { bail!(name.span(), "only one argument sink is allowed"); } - sink = Some(name.take()); + sink = Some(name); } } } |
