From 06ca740d01b428f12f6bd327257cd05dce737b03 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Tue, 9 Feb 2021 19:46:57 +0100 Subject: =?UTF-8?q?Split=20evaluation=20and=20execution=20=F0=9F=94=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/syntax/expr.rs | 397 +++++++++++++++++++++++++++++++++++----------------- src/syntax/ident.rs | 35 +++-- src/syntax/mod.rs | 7 +- src/syntax/node.rs | 8 +- src/syntax/span.rs | 17 ++- src/syntax/token.rs | 2 +- src/syntax/visit.rs | 108 +++++++------- 7 files changed, 353 insertions(+), 221 deletions(-) (limited to 'src/syntax') diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs index 3160e0e4..f431ba8d 100644 --- a/src/syntax/expr.rs +++ b/src/syntax/expr.rs @@ -1,3 +1,5 @@ +use std::rc::Rc; + use super::*; use crate::color::RgbaColor; use crate::geom::{AngularUnit, LengthUnit}; @@ -5,29 +7,10 @@ use crate::geom::{AngularUnit, LengthUnit}; /// An expression. #[derive(Debug, Clone, PartialEq)] pub enum Expr { - /// The none literal: `none`. - None, - /// A identifier literal: `left`. + /// A literal. + Lit(Lit), + /// An identifier: `left`. Ident(Ident), - /// A boolean literal: `true`, `false`. - Bool(bool), - /// An integer literal: `120`. - Int(i64), - /// A floating-point literal: `1.2`, `10e-4`. - Float(f64), - /// A length literal: `12pt`, `3cm`. - Length(f64, LengthUnit), - /// An angle literal: `1.5rad`, `90deg`. - Angle(f64, AngularUnit), - /// A percent literal: `50%`. - /// - /// _Note_: `50%` is stored as `50.0` here, but as `0.5` in the - /// corresponding [value](crate::geom::Relative). - Percent(f64), - /// A color literal: `#ffccee`. - Color(RgbaColor), - /// A string literal: `"hello!"`. - Str(String), /// An array expression: `(1, "hi", 12cm)`. Array(ExprArray), /// A dictionary expression: `(color: #f79143, pattern: dashed)`. @@ -52,11 +35,92 @@ pub enum Expr { For(ExprFor), } +impl Expr { + /// The source code location. + pub fn span(&self) -> Span { + match self { + Self::Lit(v) => v.span, + Self::Ident(v) => v.span, + Self::Array(v) => v.span, + Self::Dict(v) => v.span, + Self::Template(v) => v.span, + Self::Group(v) => v.span, + Self::Block(v) => v.span, + Self::Unary(v) => v.span, + Self::Binary(v) => v.span, + Self::Call(v) => v.span, + Self::Let(v) => v.span, + Self::If(v) => v.span, + Self::For(v) => v.span, + } + } +} + impl Pretty for Expr { fn pretty(&self, p: &mut Printer) { match self { - Self::None => p.push_str("none"), + Self::Lit(v) => v.pretty(p), Self::Ident(v) => v.pretty(p), + Self::Array(v) => v.pretty(p), + Self::Dict(v) => v.pretty(p), + Self::Template(v) => v.pretty(p), + Self::Group(v) => v.pretty(p), + Self::Block(v) => v.pretty(p), + Self::Unary(v) => v.pretty(p), + Self::Binary(v) => v.pretty(p), + Self::Call(v) => v.pretty(p), + Self::Let(v) => v.pretty(p), + Self::If(v) => v.pretty(p), + Self::For(v) => v.pretty(p), + } + } +} + +/// A literal. +#[derive(Debug, Clone, PartialEq)] +pub struct Lit { + /// The source code location. + pub span: Span, + /// The kind of literal. + pub kind: LitKind, +} + +impl Pretty for Lit { + fn pretty(&self, p: &mut Printer) { + self.kind.pretty(p); + } +} + +/// A kind of literal. +#[derive(Debug, Clone, PartialEq)] +pub enum LitKind { + /// The none literal: `none`. + None, + /// A boolean literal: `true`, `false`. + Bool(bool), + /// An integer literal: `120`. + Int(i64), + /// A floating-point literal: `1.2`, `10e-4`. + Float(f64), + /// A length literal: `12pt`, `3cm`. + Length(f64, LengthUnit), + /// An angle literal: `1.5rad`, `90deg`. + Angle(f64, AngularUnit), + /// A percent literal: `50%`. + /// + /// _Note_: `50%` is stored as `50.0` here, but as `0.5` in the + /// corresponding [value](crate::geom::Relative). + Percent(f64), + /// A color literal: `#ffccee`. + Color(RgbaColor), + /// A string literal: `"hello!"`. + Str(String), +} + +impl Pretty for LitKind { + fn pretty(&self, p: &mut Printer) { + match self { + Self::None => p.push_str("none"), Self::Bool(v) => v.pretty(p), Self::Int(v) => v.pretty(p), Self::Float(v) => v.pretty(p), @@ -71,33 +135,24 @@ impl Pretty for Expr { } Self::Color(v) => v.pretty(p), Self::Str(v) => v.pretty(p), - Self::Array(v) => v.pretty(p), - Self::Dict(v) => v.pretty(p), - Self::Template(v) => pretty_template(v, p), - Self::Group(v) => { - p.push('('); - v.v.pretty(p); - p.push(')'); - } - Self::Block(v) => v.pretty(p), - Self::Unary(v) => v.pretty(p), - Self::Binary(v) => v.pretty(p), - Self::Call(v) => v.pretty(p), - Self::Let(v) => v.pretty(p), - Self::If(v) => v.pretty(p), - Self::For(v) => v.pretty(p), } } } /// An array expression: `(1, "hi", 12cm)`. -pub type ExprArray = SpanVec; +#[derive(Debug, Clone, PartialEq)] +pub struct ExprArray { + /// The source code location. + pub span: Span, + /// The entries of the array. + pub items: Vec, +} impl Pretty for ExprArray { fn pretty(&self, p: &mut Printer) { p.push('('); - p.join(self, ", ", |item, p| item.v.pretty(p)); - if self.len() == 1 { + p.join(&self.items, ", ", |item, p| item.pretty(p)); + if self.items.len() == 1 { p.push(','); } p.push(')'); @@ -105,15 +160,21 @@ impl Pretty for ExprArray { } /// A dictionary expression: `(color: #f79143, pattern: dashed)`. -pub type ExprDict = Vec; +#[derive(Debug, Clone, PartialEq)] +pub struct ExprDict { + /// The source code location. + pub span: Span, + /// The named dictionary entries. + pub items: Vec, +} impl Pretty for ExprDict { fn pretty(&self, p: &mut Printer) { p.push('('); - if self.is_empty() { + if self.items.is_empty() { p.push(':'); } else { - p.join(self, ", ", |named, p| named.pretty(p)); + p.join(&self.items, ", ", |named, p| named.pretty(p)); } p.push(')'); } @@ -123,43 +184,73 @@ impl Pretty for ExprDict { #[derive(Debug, Clone, PartialEq)] pub struct Named { /// The name: `pattern`. - pub name: Spanned, + pub name: Ident, /// The right-hand side of the pair: `dashed`. - pub expr: Spanned, + pub expr: Expr, +} + +impl Named { + /// The source code location. + pub fn span(&self) -> Span { + self.name.span.join(self.expr.span()) + } } impl Pretty for Named { fn pretty(&self, p: &mut Printer) { - self.name.v.pretty(p); + self.name.pretty(p); p.push_str(": "); - self.expr.v.pretty(p); + self.expr.pretty(p); } } /// A template expression: `[*Hi* there!]`. -pub type ExprTemplate = Tree; +#[derive(Debug, Clone, PartialEq)] +pub struct ExprTemplate { + /// The source code location. + pub span: Span, + /// The contents of the template. + pub tree: Rc, +} -/// Pretty print a template. -pub fn pretty_template(template: &ExprTemplate, p: &mut Printer) { - if let [Spanned { v: Node::Expr(Expr::Call(call)), .. }] = template.as_slice() { - pretty_func_template(call, p, false) - } else { - p.push('['); - template.pretty(p); - p.push(']'); +impl Pretty for ExprTemplate { + fn pretty(&self, p: &mut Printer) { + if let [Node::Expr(Expr::Call(call))] = self.tree.as_slice() { + call.pretty_bracketed(p, false); + } else { + p.push('['); + self.tree.pretty(p); + p.push(']'); + } } } /// A grouped expression: `(1 + 2)`. -pub type ExprGroup = SpanBox; +#[derive(Debug, Clone, PartialEq)] +pub struct ExprGroup { + /// The source code location. + pub span: Span, + /// The wrapped expression. + pub expr: Box, +} + +impl Pretty for ExprGroup { + fn pretty(&self, p: &mut Printer) { + p.push('('); + self.expr.pretty(p); + p.push(')'); + } +} /// A block expression: `{ #let x = 1; x + 2 }`. #[derive(Debug, Clone, PartialEq)] pub struct ExprBlock { + /// The source code location. + pub span: Span, /// The list of expressions contained in the block. - pub exprs: SpanVec, + pub exprs: Vec, /// Whether the block should create a scope. - pub scopes: bool, + pub scoping: bool, } impl Pretty for ExprBlock { @@ -168,7 +259,7 @@ impl Pretty for ExprBlock { if self.exprs.len() > 1 { p.push(' '); } - p.join(&self.exprs, "; ", |expr, p| expr.v.pretty(p)); + p.join(&self.exprs, "; ", |expr, p| expr.pretty(p)); if self.exprs.len() > 1 { p.push(' '); } @@ -179,19 +270,21 @@ impl Pretty for ExprBlock { /// A unary operation: `-x`. #[derive(Debug, Clone, PartialEq)] pub struct ExprUnary { + /// The source code location. + pub span: Span, /// The operator: `-`. - pub op: Spanned, + pub op: UnOp, /// The expression to operator on: `x`. - pub expr: SpanBox, + pub expr: Box, } impl Pretty for ExprUnary { fn pretty(&self, p: &mut Printer) { - self.op.v.pretty(p); - if self.op.v == UnOp::Not { + self.op.pretty(p); + if self.op == UnOp::Not { p.push(' '); } - self.expr.v.pretty(p); + self.expr.pretty(p); } } @@ -244,21 +337,23 @@ impl Pretty for UnOp { /// A binary operation: `a + b`. #[derive(Debug, Clone, PartialEq)] pub struct ExprBinary { + /// The source code location. + pub span: Span, /// The left-hand side of the operation: `a`. - pub lhs: SpanBox, + pub lhs: Box, /// The operator: `+`. - pub op: Spanned, + pub op: BinOp, /// The right-hand side of the operation: `b`. - pub rhs: SpanBox, + pub rhs: Box, } impl Pretty for ExprBinary { fn pretty(&self, p: &mut Printer) { - self.lhs.v.pretty(p); + self.lhs.pretty(p); p.push(' '); - self.op.v.pretty(p); + self.op.pretty(p); p.push(' '); - self.rhs.v.pretty(p); + self.rhs.pretty(p); } } @@ -407,71 +502,83 @@ pub enum Associativity { /// An invocation of a function: `foo(...)`, `#[foo ...]`. #[derive(Debug, Clone, PartialEq)] pub struct ExprCall { + /// The source code location. + pub span: Span, /// The callee of the function. - pub callee: SpanBox, + pub callee: Box, /// The arguments to the function. - pub args: Spanned, + pub args: ExprArgs, } impl Pretty for ExprCall { fn pretty(&self, p: &mut Printer) { - self.callee.v.pretty(p); + self.callee.pretty(p); p.push('('); - self.args.v.pretty(p); + self.args.pretty(p); p.push(')'); } } -/// Pretty print a function template, with body or chaining when possible. -pub fn pretty_func_template(call: &ExprCall, p: &mut Printer, chained: bool) { - if chained { - p.push_str(" | "); - } else { - p.push_str("#["); - } +impl ExprCall { + /// Pretty print a function template, with body or chaining when possible. + pub fn pretty_bracketed(&self, p: &mut Printer, chained: bool) { + if chained { + p.push_str(" | "); + } else { + p.push_str("#["); + } - // Function name. - call.callee.v.pretty(p); + // Function name. + self.callee.pretty(p); - // Find out whether this can be written with a body or as a chain. - // - // Example: Transforms "#[v [Hi]]" => "#[v][Hi]". - if let [head @ .., Argument::Pos(Spanned { v: Expr::Template(template), .. })] = - call.args.v.as_slice() - { - // Previous arguments. - if !head.is_empty() { - p.push(' '); - p.join(head, ", ", |item, p| item.pretty(p)); - } + let mut write_args = |items: &[Argument]| { + if !items.is_empty() { + p.push(' '); + p.join(items, ", ", |item, p| item.pretty(p)); + } + }; + + match self.args.items.as_slice() { + // This can written as a chain. + // + // Example: Transforms "#[v][[f]]" => "#[v | f]". + [head @ .., Argument::Pos(Expr::Call(call))] => { + write_args(head); + call.pretty_bracketed(p, true); + } - // Find out whether this can written as a chain. - // - // Example: Transforms "#[v][[f]]" => "#[v | f]". - if let [Spanned { v: Node::Expr(Expr::Call(call)), .. }] = template.as_slice() { - return pretty_func_template(call, p, true); - } else { - p.push_str("]["); - template.pretty(p); + // This can be written with a body. + // + // Example: Transforms "#[v [Hi]]" => "#[v][Hi]". + [head @ .., Argument::Pos(Expr::Template(template))] => { + write_args(head); + p.push(']'); + template.pretty(p); + } + + items => { + write_args(items); + p.push(']'); + } } - } else if !call.args.v.is_empty() { - p.push(' '); - call.args.v.pretty(p); } - - // Either end of header or end of body. - p.push(']'); } /// The arguments to a function: `12, draw: false`. /// /// In case of a bracketed invocation with a body, the body is _not_ /// included in the span for the sake of clearer error messages. -pub type ExprArgs = Vec; +#[derive(Debug, Clone, PartialEq)] +pub struct ExprArgs { + /// The source code location. + pub span: Span, + /// The positional and named arguments. + pub items: Vec, +} -impl Pretty for Vec { +impl Pretty for ExprArgs { fn pretty(&self, p: &mut Printer) { - p.join(self, ", ", |item, p| item.pretty(p)); + p.join(&self.items, ", ", |item, p| item.pretty(p)); } } @@ -479,15 +586,25 @@ impl Pretty for Vec { #[derive(Debug, Clone, PartialEq)] pub enum Argument { /// A positional arguments. - Pos(Spanned), + Pos(Expr), /// A named argument. Named(Named), } +impl Argument { + /// The source code location. + pub fn span(&self) -> Span { + match self { + Self::Pos(expr) => expr.span(), + Self::Named(named) => named.span(), + } + } +} + impl Pretty for Argument { fn pretty(&self, p: &mut Printer) { match self { - Self::Pos(expr) => expr.v.pretty(p), + Self::Pos(expr) => expr.pretty(p), Self::Named(named) => named.pretty(p), } } @@ -496,19 +613,21 @@ impl Pretty for Argument { /// A let expression: `#let x = 1`. #[derive(Debug, Clone, PartialEq)] pub struct ExprLet { - /// The pattern to assign to. - pub pat: Spanned, + /// The source code location. + pub span: Span, + /// The binding to assign to. + pub binding: Ident, /// The expression the pattern is initialized with. - pub init: Option>, + pub init: Option>, } impl Pretty for ExprLet { fn pretty(&self, p: &mut Printer) { p.push_str("#let "); - self.pat.v.pretty(p); + self.binding.pretty(p); if let Some(init) = &self.init { p.push_str(" = "); - init.v.pretty(p); + init.pretty(p); } } } @@ -516,23 +635,25 @@ impl Pretty for ExprLet { /// An if expression: `#if x { y } #else { z }`. #[derive(Debug, Clone, PartialEq)] pub struct ExprIf { + /// The source code location. + pub span: Span, /// The condition which selects the body to evaluate. - pub condition: SpanBox, + pub condition: Box, /// The expression to evaluate if the condition is true. - pub if_body: SpanBox, + pub if_body: Box, /// The expression to evaluate if the condition is false. - pub else_body: Option>, + pub else_body: Option>, } impl Pretty for ExprIf { fn pretty(&self, p: &mut Printer) { p.push_str("#if "); - self.condition.v.pretty(p); + self.condition.pretty(p); p.push(' '); - self.if_body.v.pretty(p); + self.if_body.pretty(p); if let Some(expr) = &self.else_body { p.push_str(" #else "); - expr.v.pretty(p); + expr.pretty(p); } } } @@ -540,22 +661,24 @@ impl Pretty for ExprIf { /// A for expression: `#for x #in y { z }`. #[derive(Debug, Clone, PartialEq)] pub struct ExprFor { + /// The source code location. + pub span: Span, /// The pattern to assign to. - pub pat: Spanned, + pub pattern: ForPattern, /// The expression to iterate over. - pub iter: SpanBox, + pub iter: Box, /// The expression to evaluate for each iteration. - pub body: SpanBox, + pub body: Box, } impl Pretty for ExprFor { fn pretty(&self, p: &mut Printer) { p.push_str("#for "); - self.pat.v.pretty(p); + self.pattern.pretty(p); p.push_str(" #in "); - self.iter.v.pretty(p); + self.iter.pretty(p); p.push(' '); - self.body.v.pretty(p); + self.body.pretty(p); } } @@ -568,6 +691,16 @@ pub enum ForPattern { KeyValue(Ident, Ident), } +impl ForPattern { + /// The source code location. + pub fn span(&self) -> Span { + match self { + Self::Value(v) => v.span, + Self::KeyValue(k, v) => k.span.join(v.span), + } + } +} + impl Pretty for ForPattern { fn pretty(&self, p: &mut Printer) { match self { diff --git a/src/syntax/ident.rs b/src/syntax/ident.rs index c4cc19bc..731a2789 100644 --- a/src/syntax/ident.rs +++ b/src/syntax/ident.rs @@ -2,6 +2,7 @@ use std::ops::Deref; use unicode_xid::UnicodeXID; +use super::Span; use crate::pretty::{Pretty, Printer}; /// An Unicode identifier with a few extra permissible characters. @@ -12,13 +13,21 @@ use crate::pretty::{Pretty, Printer}; /// /// [uax31]: http://www.unicode.org/reports/tr31/ #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] -pub struct Ident(pub String); +pub struct Ident { + /// The source code location. + pub span: Span, + /// The identifier string. + pub string: String, +} impl Ident { /// Create a new identifier from a string checking that it is a valid. - pub fn new(ident: impl AsRef + Into) -> Option { - if is_ident(ident.as_ref()) { - Some(Self(ident.into())) + pub fn new( + string: impl AsRef + Into, + span: impl Into, + ) -> Option { + if is_ident(string.as_ref()) { + Some(Self { span: span.into(), string: string.into() }) } else { None } @@ -26,19 +35,13 @@ impl Ident { /// Return a reference to the underlying string. pub fn as_str(&self) -> &str { - self - } -} - -impl Pretty for Ident { - fn pretty(&self, p: &mut Printer) { - p.push_str(self.as_str()); + self.string.as_str() } } impl AsRef for Ident { fn as_ref(&self) -> &str { - self + self.as_str() } } @@ -46,7 +49,13 @@ impl Deref for Ident { type Target = str; fn deref(&self) -> &Self::Target { - self.0.as_str() + self.as_str() + } +} + +impl Pretty for Ident { + fn pretty(&self, p: &mut Printer) { + p.push_str(self.as_str()); } } diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index 8bb6931a..a8ed2457 100644 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -16,12 +16,12 @@ pub use token::*; use crate::pretty::{Pretty, Printer}; /// The abstract syntax tree. -pub type Tree = SpanVec; +pub type Tree = Vec; impl Pretty for Tree { fn pretty(&self, p: &mut Printer) { for node in self { - node.v.pretty(p); + node.pretty(p); } } } @@ -133,9 +133,8 @@ mod tests { roundtrip("#[v 1]"); roundtrip("#[v 1, 2][*Ok*]"); roundtrip("#[v 1 | f 2]"); - roundtrip("{#[v]}"); + test("{#[v]}", "{v()}"); test("#[v 1, #[f 2]]", "#[v 1 | f 2]"); - test("#[v 1, 2][#[f 3]]", "#[v 1, 2 | f 3]"); // Keywords. roundtrip("#let x = 1 + 2"); diff --git a/src/syntax/node.rs b/src/syntax/node.rs index b4866068..fe9767a1 100644 --- a/src/syntax/node.rs +++ b/src/syntax/node.rs @@ -37,7 +37,7 @@ impl Pretty for Node { Self::Expr(expr) => { if let Expr::Call(call) = expr { // Format function templates appropriately. - pretty_func_template(call, p, false) + call.pretty_bracketed(p, false) } else { expr.pretty(p); } @@ -49,15 +49,15 @@ impl Pretty for Node { /// A section heading: `= Introduction`. #[derive(Debug, Clone, PartialEq)] pub struct NodeHeading { - /// The section depth (numer of equals signs minus 1, capped at 5). - pub level: Spanned, + /// The section depth (numer of equals signs minus 1). + pub level: usize, /// The contents of the heading. pub contents: Tree, } impl Pretty for NodeHeading { fn pretty(&self, p: &mut Printer) { - for _ in 0 ..= self.level.v { + for _ in 0 ..= self.level { p.push('='); } self.contents.pretty(p); diff --git a/src/syntax/span.rs b/src/syntax/span.rs index 5087dffa..65b1d637 100644 --- a/src/syntax/span.rs +++ b/src/syntax/span.rs @@ -19,14 +19,15 @@ impl WithSpan for T {} /// Span offsetting. pub trait Offset { /// Offset all spans contained in `Self` by the given position. - fn offset(self, by: Pos) -> Self; + fn offset(self, by: impl Into) -> Self; } /// A vector of spanned values of type `T`. pub type SpanVec = Vec>; impl Offset for SpanVec { - fn offset(mut self, by: Pos) -> Self { + fn offset(mut self, by: impl Into) -> Self { + let by = by.into(); for spanned in &mut self { spanned.span = spanned.span.offset(by); } @@ -34,9 +35,6 @@ impl Offset for SpanVec { } } -/// A box of a spanned value of type `T`. -pub type SpanBox = Box>; - /// A value with the span it corresponds to in the source code. #[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] #[cfg_attr(feature = "serde", derive(serde::Serialize))] @@ -90,7 +88,7 @@ impl Spanned> { } impl Offset for Spanned { - fn offset(self, by: Pos) -> Self { + fn offset(self, by: impl Into) -> Self { self.map_span(|span| span.offset(by)) } } @@ -174,7 +172,8 @@ impl Span { } impl Offset for Span { - fn offset(self, by: Pos) -> Self { + fn offset(self, by: impl Into) -> Self { + let by = by.into(); Self { start: self.start.offset(by), end: self.end.offset(by), @@ -236,8 +235,8 @@ impl Pos { } impl Offset for Pos { - fn offset(self, by: Self) -> Self { - Pos(self.0 + by.0) + fn offset(self, by: impl Into) -> Self { + Pos(self.0 + by.into().0) } } diff --git a/src/syntax/token.rs b/src/syntax/token.rs index 5e69a350..411e835f 100644 --- a/src/syntax/token.rs +++ b/src/syntax/token.rs @@ -123,7 +123,7 @@ pub enum Token<'s> { /// A percentage: `50%`. /// /// _Note_: `50%` is stored as `50.0` here, as in the corresponding - /// [literal](super::Expr::Percent). + /// [literal](super::LitKind::Percent). Percent(f64), /// A color value: `#20d82a`. Color(RgbaColor), diff --git a/src/syntax/visit.rs b/src/syntax/visit.rs index 3a289eb1..70159d2d 100644 --- a/src/syntax/visit.rs +++ b/src/syntax/visit.rs @@ -3,17 +3,17 @@ use super::*; macro_rules! visit { - ($(fn $name:ident($v:ident, $item:ident: &$ty:ty) $body:block)*) => { + ($(fn $name:ident($v:ident, $node:ident: &$ty:ty) $body:block)*) => { /// Traverses the syntax tree. pub trait Visit<'ast> { - $(fn $name(&mut self, $item: &'ast $ty) { - $name(self, $item); + $(fn $name(&mut self, $node: &'ast $ty) { + $name(self, $node); })* } $(visit! { @concat!("Walk a node of type [`", stringify!($ty), "`]."), - pub fn $name<'ast, V>($v: &mut V, $item: &'ast $ty) + pub fn $name<'ast, V>($v: &mut V, $node: &'ast $ty) where V: Visit<'ast> + ?Sized $body @@ -27,14 +27,14 @@ macro_rules! visit { } visit! { - fn visit_tree(v, item: &Tree) { - for node in item { - v.visit_node(&node.v); + fn visit_tree(v, node: &Tree) { + for node in node { + v.visit_node(&node); } } - fn visit_node(v, item: &Node) { - match item { + fn visit_node(v, node: &Node) { + match node { Node::Strong => {} Node::Emph => {} Node::Space => {} @@ -47,18 +47,10 @@ visit! { } } - fn visit_expr(v, item: &Expr) { - match item { - Expr::None => {} + fn visit_expr(v, node: &Expr) { + match node { + Expr::Lit(_) => {} Expr::Ident(_) => {} - Expr::Bool(_) => {} - Expr::Int(_) => {} - Expr::Float(_) => {} - Expr::Length(_, _) => {} - Expr::Angle(_, _) => {} - Expr::Percent(_) => {} - Expr::Color(_) => {} - Expr::Str(_) => {} Expr::Array(e) => v.visit_array(e), Expr::Dict(e) => v.visit_dict(e), Expr::Template(e) => v.visit_template(e), @@ -73,75 +65,75 @@ visit! { } } - fn visit_array(v, item: &ExprArray) { - for expr in item { - v.visit_expr(&expr.v); + fn visit_array(v, node: &ExprArray) { + for expr in &node.items { + v.visit_expr(&expr); } } - fn visit_dict(v, item: &ExprDict) { - for named in item { - v.visit_expr(&named.expr.v); + fn visit_dict(v, node: &ExprDict) { + for named in &node.items { + v.visit_expr(&named.expr); } } - fn visit_template(v, item: &ExprTemplate) { - v.visit_tree(item); + fn visit_template(v, node: &ExprTemplate) { + v.visit_tree(&node.tree); } - fn visit_group(v, item: &ExprGroup) { - v.visit_expr(&item.v); + fn visit_group(v, node: &ExprGroup) { + v.visit_expr(&node.expr); } - fn visit_block(v, item: &ExprBlock) { - for expr in &item.exprs { - v.visit_expr(&expr.v); + fn visit_block(v, node: &ExprBlock) { + for expr in &node.exprs { + v.visit_expr(&expr); } } - fn visit_binary(v, item: &ExprBinary) { - v.visit_expr(&item.lhs.v); - v.visit_expr(&item.rhs.v); + fn visit_binary(v, node: &ExprBinary) { + v.visit_expr(&node.lhs); + v.visit_expr(&node.rhs); } - fn visit_unary(v, item: &ExprUnary) { - v.visit_expr(&item.expr.v); + fn visit_unary(v, node: &ExprUnary) { + v.visit_expr(&node.expr); } - fn visit_call(v, item: &ExprCall) { - v.visit_expr(&item.callee.v); - v.visit_args(&item.args.v); + fn visit_call(v, node: &ExprCall) { + v.visit_expr(&node.callee); + v.visit_args(&node.args); } - fn visit_args(v, item: &ExprArgs) { - for arg in item { + fn visit_args(v, node: &ExprArgs) { + for arg in &node.items { v.visit_arg(arg); } } - fn visit_arg(v, item: &Argument) { - match item { - Argument::Pos(expr) => v.visit_expr(&expr.v), - Argument::Named(named) => v.visit_expr(&named.expr.v), + fn visit_arg(v, node: &Argument) { + match node { + Argument::Pos(expr) => v.visit_expr(&expr), + Argument::Named(named) => v.visit_expr(&named.expr), } } - fn visit_let(v, item: &ExprLet) { - if let Some(init) = &item.init { - v.visit_expr(&init.v); + fn visit_let(v, node: &ExprLet) { + if let Some(init) = &node.init { + v.visit_expr(&init); } } - fn visit_if(v, item: &ExprIf) { - v.visit_expr(&item.condition.v); - v.visit_expr(&item.if_body.v); - if let Some(body) = &item.else_body { - v.visit_expr(&body.v); + fn visit_if(v, node: &ExprIf) { + v.visit_expr(&node.condition); + v.visit_expr(&node.if_body); + if let Some(body) = &node.else_body { + v.visit_expr(&body); } } - fn visit_for(v, item: &ExprFor) { - v.visit_expr(&item.iter.v); - v.visit_expr(&item.body.v); + fn visit_for(v, node: &ExprFor) { + v.visit_expr(&node.iter); + v.visit_expr(&node.body); } } -- cgit v1.2.3