summaryrefslogtreecommitdiff
path: root/src/eval
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-06-09 00:37:13 +0200
committerLaurenz <laurmaedje@gmail.com>2021-06-09 00:37:13 +0200
commit5afb42ad89abb518a01a09051f0f9b6f75bd383e (patch)
treeb12368a287f22de711df8d759c20ee742ed5b4c2 /src/eval
parentd69dfa84ec957ac4037f60a3335416a9f73b97c8 (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.rs39
-rw-r--r--src/eval/mod.rs25
-rw-r--r--src/eval/scope.rs3
-rw-r--r--src/eval/value.rs16
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.