diff --git a/src/eval/template.rs b/src/eval/capture.rs similarity index 63% rename from src/eval/template.rs rename to src/eval/capture.rs index 040685f89..b7052c70b 100644 --- a/src/eval/template.rs +++ b/src/eval/capture.rs @@ -1,29 +1,17 @@ use super::*; use crate::syntax::visit::*; -impl Eval for Spanned<&ExprTemplate> { - type Output = Value; - - fn eval(self, ctx: &mut EvalContext) -> Self::Output { - let mut template = self.v.clone(); - let mut visitor = CapturesVisitor::new(ctx); - visitor.visit_template(&mut template); - Value::Template(template) - } -} - /// A visitor that replaces all captured variables with their values. -struct CapturesVisitor<'a> { +#[derive(Debug)] +pub struct CapturesVisitor<'a> { external: &'a Scopes<'a>, internal: Scopes<'a>, } impl<'a> CapturesVisitor<'a> { - fn new(ctx: &'a EvalContext) -> Self { - Self { - external: &ctx.scopes, - internal: Scopes::default(), - } + /// Create a new visitor for the given external scopes. + pub fn new(external: &'a Scopes) -> Self { + Self { external, internal: Scopes::default() } } } @@ -43,7 +31,7 @@ impl<'a> Visitor<'a> for CapturesVisitor<'a> { fn visit_expr(&mut self, expr: &'a mut Expr) { if let Expr::Ident(ident) = expr { // Find out whether the identifier is not locally defined, but - // captured, and if so, replace it with it's value. + // captured, and if so, replace it with its value. if self.internal.get(ident).is_none() { if let Some(value) = self.external.get(ident) { *expr = Expr::CapturedValue(value.clone()); diff --git a/src/eval/mod.rs b/src/eval/mod.rs index 9e45a67ba..af3303afc 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -3,13 +3,14 @@ #[macro_use] mod value; mod call; +mod capture; mod context; mod ops; mod scope; mod state; -mod template; pub use call::*; +pub use capture::*; pub use context::*; pub use scope::*; pub use state::*; @@ -208,6 +209,17 @@ impl Eval for Spanned<&ExprDict> { } } +impl Eval for Spanned<&ExprTemplate> { + type Output = Value; + + fn eval(self, ctx: &mut EvalContext) -> Self::Output { + let mut template = self.v.clone(); + let mut visitor = CapturesVisitor::new(&ctx.scopes); + visitor.visit_template(&mut template); + Value::Template(template) + } +} + impl Eval for Spanned<&ExprBlock> { type Output = Value; diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index 16e691a9f..d1fc6b779 100644 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -12,6 +12,7 @@ pub use ident::*; pub use node::*; pub use span::*; pub use token::*; +pub use visit::Visitor; use crate::pretty::{Pretty, Printer};