diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-06-09 00:37:13 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-06-09 00:37:13 +0200 |
| commit | 5afb42ad89abb518a01a09051f0f9b6f75bd383e (patch) | |
| tree | b12368a287f22de711df8d759c20ee742ed5b4c2 /src/eval | |
| parent | d69dfa84ec957ac4037f60a3335416a9f73b97c8 (diff) | |
Lists with indent-based parsing
- Unordered lists with indent-based parsing and basic layout using stacks
- Headings are now also indent based
- Removes syntax functions since they will be superseded by select & transform
Diffstat (limited to 'src/eval')
| -rw-r--r-- | src/eval/capture.rs | 39 | ||||
| -rw-r--r-- | src/eval/mod.rs | 25 | ||||
| -rw-r--r-- | src/eval/scope.rs | 3 | ||||
| -rw-r--r-- | src/eval/value.rs | 16 |
4 files changed, 32 insertions, 51 deletions
diff --git a/src/eval/capture.rs b/src/eval/capture.rs index 74da4747..64275e93 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, Node}; +use crate::syntax::{Expr, Ident}; /// A visitor that captures variable slots. #[derive(Debug)] @@ -26,37 +26,20 @@ 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) => self.process(ident), - expr => visit_expr(self, expr), + if let Expr::Ident(ident) = node { + // Find out whether the name is not locally defined and if so if it + // can be captured. + 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)); + } + } + } else { + visit_expr(self, node); } } diff --git a/src/eval/mod.rs b/src/eval/mod.rs index c480ddfe..d1307b6d 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -218,24 +218,23 @@ pub trait Eval { } impl Eval for Tree { - type Output = NodeMap; + type Output = ExprMap; fn eval(&self, ctx: &mut EvalContext) -> Self::Output { - let mut map = NodeMap::new(); - - for node in self { - let value = if let Some(call) = node.desugar() { - call.eval(ctx) - } else if let Node::Expr(expr) = node { - expr.eval(ctx) - } else { - continue; - }; + struct ExprVisitor<'a, 'b> { + ctx: &'a mut EvalContext<'b>, + map: ExprMap, + } - map.insert(node as *const _, value); + impl<'ast> Visit<'ast> for ExprVisitor<'_, '_> { + fn visit_expr(&mut self, node: &'ast Expr) { + self.map.insert(node as *const _, node.eval(self.ctx)); + } } - map + let mut visitor = ExprVisitor { ctx, map: ExprMap::new() }; + visitor.visit_tree(self); + visitor.map } } diff --git a/src/eval/scope.rs b/src/eval/scope.rs index e5afb6b0..3f7c4c62 100644 --- a/src/eval/scope.rs +++ b/src/eval/scope.rs @@ -33,8 +33,7 @@ impl<'a> Scopes<'a> { /// Exit the topmost scope. /// - /// # Panics - /// Panics if no scope was entered. + /// This panics if no scope was entered. pub fn exit(&mut self) { self.top = self.scopes.pop().expect("no pushed scope"); } diff --git a/src/eval/value.rs b/src/eval/value.rs index e2ff5383..94f7f569 100644 --- a/src/eval/value.rs +++ b/src/eval/value.rs @@ -9,7 +9,7 @@ use super::EvalContext; use crate::color::{Color, RgbaColor}; use crate::exec::ExecContext; use crate::geom::{Angle, Length, Linear, Relative}; -use crate::syntax::{Node, Span, Spanned, Tree}; +use crate::syntax::{Expr, Span, Spanned, Tree}; /// A computational value. #[derive(Debug, Clone, PartialEq)] @@ -148,7 +148,7 @@ pub enum TemplateNode { /// The syntax tree of the corresponding template expression. tree: Rc<Tree>, /// The evaluated expressions for the `tree`. - map: NodeMap, + map: ExprMap, }, /// A template that was converted from a string. Str(String), @@ -163,13 +163,13 @@ impl PartialEq for TemplateNode { } } -/// A map from nodes to the values they evaluated to. +/// A map from expressions to the values they evaluated to. /// -/// The raw pointers point into the nodes contained in some [`Tree`]. Since the -/// lifetime is erased, the tree could go out of scope while the hash map still -/// lives. Although this could lead to lookup panics, it is not unsafe since the -/// pointers are never dereferenced. -pub type NodeMap = HashMap<*const Node, Value>; +/// The raw pointers point into the expressions contained in some [`Tree`]. +/// Since the lifetime is erased, the tree could go out of scope while the hash +/// map still lives. Although this could lead to lookup panics, it is not unsafe +/// since the pointers are never dereferenced. +pub type ExprMap = HashMap<*const Expr, Value>; /// A reference-counted dynamic template node that can implement custom /// behaviour. |
