diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/eval/mod.rs | 48 | ||||
| -rw-r--r-- | src/parse/collection.rs | 2 | ||||
| -rw-r--r-- | src/parse/mod.rs | 2 | ||||
| -rw-r--r-- | src/syntax/expr.rs | 92 |
4 files changed, 75 insertions, 69 deletions
diff --git a/src/eval/mod.rs b/src/eval/mod.rs index efc77f69..c7b87aef 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -172,14 +172,14 @@ impl Eval for Spanned<&Expr> { Expr::Percent(v) => Value::Relative(Relative::new(v / 100.0)), Expr::Color(v) => Value::Color(Color::Rgba(*v)), Expr::Str(v) => Value::Str(v.clone()), - Expr::Call(v) => v.with_span(self.span).eval(ctx), - Expr::Unary(v) => v.with_span(self.span).eval(ctx), - Expr::Binary(v) => v.with_span(self.span).eval(ctx), Expr::Array(v) => Value::Array(v.with_span(self.span).eval(ctx)), Expr::Dict(v) => Value::Dict(v.with_span(self.span).eval(ctx)), Expr::Template(v) => Value::Template(v.clone()), - Expr::Group(v) => v.as_ref().with_span(self.span).eval(ctx), - Expr::Block(v) => v.as_ref().with_span(self.span).eval(ctx), + Expr::Call(v) => v.with_span(self.span).eval(ctx), + Expr::Unary(v) => v.with_span(self.span).eval(ctx), + Expr::Binary(v) => v.with_span(self.span).eval(ctx), + Expr::Group(v) => v.as_ref().eval(ctx), + Expr::Block(v) => v.as_ref().eval(ctx), Expr::Let(v) => { let value = match &v.expr { Some(expr) => expr.as_ref().eval(ctx), @@ -192,6 +192,25 @@ impl Eval for Spanned<&Expr> { } } +impl Eval for Spanned<&ExprArray> { + type Output = ValueArray; + + fn eval(self, ctx: &mut EvalContext) -> Self::Output { + self.v.iter().map(|expr| expr.as_ref().eval(ctx)).collect() + } +} + +impl Eval for Spanned<&ExprDict> { + type Output = ValueDict; + + fn eval(self, ctx: &mut EvalContext) -> Self::Output { + self.v + .iter() + .map(|Named { name, expr }| (name.v.0.clone(), expr.as_ref().eval(ctx))) + .collect() + } +} + impl Eval for Spanned<&ExprUnary> { type Output = Value; @@ -230,22 +249,3 @@ impl Eval for Spanned<&ExprBinary> { } } } - -impl Eval for Spanned<&ExprArray> { - type Output = ValueArray; - - fn eval(self, ctx: &mut EvalContext) -> Self::Output { - self.v.iter().map(|expr| expr.as_ref().eval(ctx)).collect() - } -} - -impl Eval for Spanned<&ExprDict> { - type Output = ValueDict; - - fn eval(self, ctx: &mut EvalContext) -> Self::Output { - self.v - .iter() - .map(|Named { name, expr }| (name.v.0.clone(), expr.as_ref().eval(ctx))) - .collect() - } -} diff --git a/src/parse/collection.rs b/src/parse/collection.rs index ca05b998..9addcef0 100644 --- a/src/parse/collection.rs +++ b/src/parse/collection.rs @@ -93,7 +93,7 @@ impl State { fn into_expr(self) -> Expr { match self { Self::Unknown => Expr::Array(vec![]), - Self::Expr(expr) => Expr::Group(Box::new(expr.v)), + Self::Expr(expr) => Expr::Group(Box::new(expr)), Self::Array(array) => Expr::Array(array), Self::Dict(dict) => Expr::Dict(dict), } diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 7c92185d..0a656366 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -222,7 +222,7 @@ fn bracket_body(p: &mut Parser) -> Tree { fn block(p: &mut Parser) -> Option<Expr> { p.push_mode(TokenMode::Code); p.start_group(Group::Brace); - let expr = expr(p); + let expr = p.span_if(expr); while !p.eof() { p.diag_unexpected(); } diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs index 79533918..79713cf1 100644 --- a/src/syntax/expr.rs +++ b/src/syntax/expr.rs @@ -28,22 +28,22 @@ pub enum Expr { Color(RgbaColor), /// A string literal: `"hello!"`. Str(String), - /// An invocation of a function: `[foo ...]`, `foo(...)`. - Call(ExprCall), - /// A unary operation: `-x`. - Unary(ExprUnary), - /// A binary operation: `a + b`, `a / b`. - Binary(ExprBinary), /// An array expression: `(1, "hi", 12cm)`. Array(ExprArray), /// A dictionary expression: `(color: #f79143, pattern: dashed)`. Dict(ExprDict), /// A template expression: `[*Hi* there!]`. Template(ExprTemplate), + /// A unary operation: `-x`. + Unary(ExprUnary), + /// A binary operation: `a + b`, `a / b`. + Binary(ExprBinary), + /// An invocation of a function: `[foo ...]`, `foo(...)`. + Call(ExprCall), /// A grouped expression: `(1 + 2)`. - Group(Box<Expr>), + Group(ExprGroup), /// A block expression: `{1 + 2}`. - Block(Box<Expr>), + Block(ExprBlock), /// A let expression: `let x = 1`. Let(ExprLet), } @@ -61,9 +61,6 @@ impl Pretty for Expr { Self::Percent(v) => write!(p, "{}%", v).unwrap(), Self::Color(v) => write!(p, "{}", v).unwrap(), Self::Str(v) => write!(p, "{:?}", &v).unwrap(), - Self::Call(v) => v.pretty(p), - Self::Unary(v) => v.pretty(p), - Self::Binary(v) => v.pretty(p), Self::Array(v) => v.pretty(p), Self::Dict(v) => v.pretty(p), Self::Template(v) => { @@ -71,14 +68,17 @@ impl Pretty for Expr { v.pretty(p); p.push_str("]"); } + Self::Unary(v) => v.pretty(p), + Self::Binary(v) => v.pretty(p), + Self::Call(v) => v.pretty(p), Self::Group(v) => { p.push_str("("); - v.pretty(p); + v.v.pretty(p); p.push_str(")"); } Self::Block(v) => { p.push_str("{"); - v.pretty(p); + v.v.pretty(p); p.push_str("}"); } Self::Let(v) => v.pretty(p), @@ -86,6 +86,38 @@ impl Pretty for Expr { } } +/// An array expression: `(1, "hi", 12cm)`. +pub type ExprArray = SpanVec<Expr>; + +impl Pretty for ExprArray { + fn pretty(&self, p: &mut Printer) { + p.push_str("("); + p.join(self, ", ", |item, p| item.v.pretty(p)); + if self.len() == 1 { + p.push_str(","); + } + p.push_str(")"); + } +} + +/// A dictionary expression: `(color: #f79143, pattern: dashed)`. +pub type ExprDict = Vec<Named>; + +impl Pretty for ExprDict { + fn pretty(&self, p: &mut Printer) { + p.push_str("("); + if self.is_empty() { + p.push_str(":"); + } else { + p.join(self, ", ", |named, p| named.pretty(p)); + } + p.push_str(")"); + } +} + +/// A template expression: `[*Hi* there!]`. +pub type ExprTemplate = Tree; + /// An invocation of a function: `[foo ...]`, `foo(...)`. #[derive(Debug, Clone, PartialEq)] pub struct ExprCall { @@ -271,37 +303,11 @@ impl Pretty for BinOp { } } -/// An array expression: `(1, "hi", 12cm)`. -pub type ExprArray = SpanVec<Expr>; +/// A grouped expression: `(1 + 2)`. +pub type ExprGroup = Box<Spanned<Expr>>; -impl Pretty for ExprArray { - fn pretty(&self, p: &mut Printer) { - p.push_str("("); - p.join(self, ", ", |item, p| item.v.pretty(p)); - if self.len() == 1 { - p.push_str(","); - } - p.push_str(")"); - } -} - -/// A dictionary expression: `(color: #f79143, pattern: dashed)`. -pub type ExprDict = Vec<Named>; - -impl Pretty for ExprDict { - fn pretty(&self, p: &mut Printer) { - p.push_str("("); - if self.is_empty() { - p.push_str(":"); - } else { - p.join(self, ", ", |named, p| named.pretty(p)); - } - p.push_str(")"); - } -} - -/// A template expression: `[*Hi* there!]`. -pub type ExprTemplate = Tree; +/// A block expression: `{1 + 2}`. +pub type ExprBlock = Box<Spanned<Expr>>; /// A let expression: `let x = 1`. #[derive(Debug, Clone, PartialEq)] |
