summaryrefslogtreecommitdiff
path: root/src/eval/template.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-01-30 10:24:51 +0100
committerLaurenz <laurmaedje@gmail.com>2021-01-30 10:24:51 +0100
commitac24075469f171fe83a976b9a97b9b1ea078a7e3 (patch)
treee89155de4670efa636b71f4a9a5e5f422c76214d /src/eval/template.rs
parent2036663ed25b5885a87eb3a80caec3fa2e258d77 (diff)
Moves captures visitor into separate file 🚚
Diffstat (limited to 'src/eval/template.rs')
-rw-r--r--src/eval/template.rs56
1 files changed, 0 insertions, 56 deletions
diff --git a/src/eval/template.rs b/src/eval/template.rs
deleted file mode 100644
index 040685f8..00000000
--- a/src/eval/template.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-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> {
- external: &'a Scopes<'a>,
- internal: Scopes<'a>,
-}
-
-impl<'a> CapturesVisitor<'a> {
- fn new(ctx: &'a EvalContext) -> Self {
- Self {
- external: &ctx.scopes,
- internal: Scopes::default(),
- }
- }
-}
-
-impl<'a> Visitor<'a> for CapturesVisitor<'a> {
- fn visit_scope_pre(&mut self) {
- self.internal.push();
- }
-
- fn visit_scope_post(&mut self) {
- self.internal.pop();
- }
-
- fn visit_def(&mut self, id: &mut Ident) {
- self.internal.define(id.as_str(), Value::None);
- }
-
- 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.
- if self.internal.get(ident).is_none() {
- if let Some(value) = self.external.get(ident) {
- *expr = Expr::CapturedValue(value.clone());
- }
- }
- } else {
- walk_expr(self, expr);
- }
- }
-}