summaryrefslogtreecommitdiff
path: root/src/eval/capture.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval/capture.rs')
-rw-r--r--src/eval/capture.rs36
1 files changed, 26 insertions, 10 deletions
diff --git a/src/eval/capture.rs b/src/eval/capture.rs
index c0354cd3..bee523ef 100644
--- a/src/eval/capture.rs
+++ b/src/eval/capture.rs
@@ -2,7 +2,7 @@ use std::rc::Rc;
use super::{Scope, Scopes, Value};
use crate::syntax::visit::{visit_expr, Visit};
-use crate::syntax::{Expr, Ident};
+use crate::syntax::{Expr, Ident, Node};
/// A visitor that captures variable slots.
#[derive(Debug)]
@@ -26,20 +26,36 @@ impl<'a> CapturesVisitor<'a> {
pub fn finish(self) -> Scope {
self.captures
}
+
+ /// Find out whether the name is not locally defined and if so if it can be
+ /// captured.
+ fn process(&mut self, name: &str) {
+ if self.internal.get(name).is_none() {
+ if let Some(slot) = self.external.get(name) {
+ self.captures.def_slot(name, Rc::clone(slot));
+ }
+ }
+ }
}
impl<'ast> Visit<'ast> for CapturesVisitor<'_> {
+ fn visit_node(&mut self, node: &'ast Node) {
+ match node {
+ Node::Text(_) => {}
+ Node::Space => {}
+ Node::Linebreak(_) => self.process(Node::LINEBREAK),
+ Node::Parbreak(_) => self.process(Node::PARBREAK),
+ Node::Strong(_) => self.process(Node::STRONG),
+ Node::Emph(_) => self.process(Node::EMPH),
+ Node::Heading(_) => self.process(Node::HEADING),
+ Node::Raw(_) => self.process(Node::RAW),
+ Node::Expr(expr) => self.visit_expr(expr),
+ }
+ }
+
fn visit_expr(&mut self, node: &'ast Expr) {
match node {
- Expr::Ident(ident) => {
- // Find out whether the identifier is not locally defined, but
- // captured, and if so, capture its value.
- if self.internal.get(ident).is_none() {
- if let Some(slot) = self.external.get(ident) {
- self.captures.def_slot(ident.as_str(), Rc::clone(slot));
- }
- }
- }
+ Expr::Ident(ident) => self.process(ident),
expr => visit_expr(self, expr),
}
}