diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-11-07 22:05:48 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-11-08 01:37:49 +0100 |
| commit | 95866d5fc9ae89a23c5754193c7de5d4fe4873b1 (patch) | |
| tree | ae408006c29ba31aa62dab7e48e9326316f89fed /src/eval/capture.rs | |
| parent | 8117ca9950a2027efae133f811a26a4a7bf86a8e (diff) | |
Tidy up AST
Diffstat (limited to 'src/eval/capture.rs')
| -rw-r--r-- | src/eval/capture.rs | 80 |
1 files changed, 7 insertions, 73 deletions
diff --git a/src/eval/capture.rs b/src/eval/capture.rs index e46103c8..786da36e 100644 --- a/src/eval/capture.rs +++ b/src/eval/capture.rs @@ -1,93 +1,27 @@ use std::rc::Rc; -use super::{Scope, Scopes, Value}; -use crate::syntax::ast::{ClosureParam, Expr, Imports}; -use crate::syntax::RedRef; +use super::{Scope, Scopes}; +use crate::syntax::{NodeKind, RedRef}; /// A visitor that captures variable slots. pub struct CapturesVisitor<'a> { external: &'a Scopes<'a>, - internal: Scopes<'a>, captures: Scope, } impl<'a> CapturesVisitor<'a> { /// Create a new visitor for the given external scopes. pub fn new(external: &'a Scopes) -> Self { - Self { - external, - internal: Scopes::new(None), - captures: Scope::new(), - } + Self { external, captures: Scope::new() } } pub fn visit(&mut self, node: RedRef) { - let expr: Option<Expr> = node.cast(); - - match expr.as_ref() { - Some(Expr::Let(expr)) => { - self.visit(expr.init_ref()); - let ident = expr.binding(); - self.internal.def_mut(ident.as_str(), Value::None); - } - Some(Expr::Closure(closure)) => { - for arg in closure.params() { - match arg { - ClosureParam::Pos(ident) | ClosureParam::Sink(ident) => { - self.internal.def_mut(ident.as_str(), Value::None); - } - ClosureParam::Named(name) => { - self.internal.def_mut(name.name().as_str(), Value::None); - } - } - } - self.visit(closure.body_ref()); - } - Some(Expr::For(forloop)) => { - let pattern = forloop.pattern(); - self.internal.def_mut(pattern.value().as_str(), Value::None); - - if let Some(key) = pattern.key() { - self.internal.def_mut(key.as_str(), Value::None); + match node.kind() { + NodeKind::Ident(ident) => { + if let Some(slot) = self.external.get(ident.as_str()) { + self.captures.def_slot(ident.as_str(), Rc::clone(slot)); } - self.visit(forloop.body_ref()); } - Some(Expr::Import(import)) => { - if let Imports::Idents(idents) = import.imports() { - for ident in idents { - self.internal.def_mut(ident.as_str(), Value::None); - } - } - } - Some(Expr::Ident(ident)) => { - if self.internal.get(ident.as_str()).is_none() { - if let Some(slot) = self.external.get(ident.as_str()) { - self.captures.def_slot(ident.as_str(), Rc::clone(slot)); - } - } - } - _ => {} - } - - match expr.as_ref() { - Some(Expr::Let(_)) | Some(Expr::For(_)) | Some(Expr::Closure(_)) => {} - - Some(Expr::Block(_)) => { - self.internal.enter(); - for child in node.children() { - self.visit(child); - } - self.internal.exit(); - } - - Some(Expr::Template(_)) => { - self.internal.enter(); - for child in node.children() { - self.visit(child); - } - self.internal.exit(); - } - _ => { for child in node.children() { self.visit(child); |
