Moves captures visitor into separate file 🚚

This commit is contained in:
Laurenz 2021-01-30 10:24:51 +01:00
parent 2036663ed2
commit ac24075469
3 changed files with 20 additions and 19 deletions

View File

@ -1,29 +1,17 @@
use super::*; use super::*;
use crate::syntax::visit::*; 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. /// A visitor that replaces all captured variables with their values.
struct CapturesVisitor<'a> { #[derive(Debug)]
pub struct CapturesVisitor<'a> {
external: &'a Scopes<'a>, external: &'a Scopes<'a>,
internal: Scopes<'a>, internal: Scopes<'a>,
} }
impl<'a> CapturesVisitor<'a> { impl<'a> CapturesVisitor<'a> {
fn new(ctx: &'a EvalContext) -> Self { /// Create a new visitor for the given external scopes.
Self { pub fn new(external: &'a Scopes) -> Self {
external: &ctx.scopes, Self { external, internal: Scopes::default() }
internal: Scopes::default(),
}
} }
} }
@ -43,7 +31,7 @@ impl<'a> Visitor<'a> for CapturesVisitor<'a> {
fn visit_expr(&mut self, expr: &'a mut Expr) { fn visit_expr(&mut self, expr: &'a mut Expr) {
if let Expr::Ident(ident) = expr { if let Expr::Ident(ident) = expr {
// Find out whether the identifier is not locally defined, but // 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 self.internal.get(ident).is_none() {
if let Some(value) = self.external.get(ident) { if let Some(value) = self.external.get(ident) {
*expr = Expr::CapturedValue(value.clone()); *expr = Expr::CapturedValue(value.clone());

View File

@ -3,13 +3,14 @@
#[macro_use] #[macro_use]
mod value; mod value;
mod call; mod call;
mod capture;
mod context; mod context;
mod ops; mod ops;
mod scope; mod scope;
mod state; mod state;
mod template;
pub use call::*; pub use call::*;
pub use capture::*;
pub use context::*; pub use context::*;
pub use scope::*; pub use scope::*;
pub use state::*; 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> { impl Eval for Spanned<&ExprBlock> {
type Output = Value; type Output = Value;

View File

@ -12,6 +12,7 @@ pub use ident::*;
pub use node::*; pub use node::*;
pub use span::*; pub use span::*;
pub use token::*; pub use token::*;
pub use visit::Visitor;
use crate::pretty::{Pretty, Printer}; use crate::pretty::{Pretty, Printer};