summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-01-17 16:18:36 +0100
committerLaurenz <laurmaedje@gmail.com>2021-01-17 16:18:36 +0100
commitdd246e5bc944f90be7ba2981c2b73520a4bfbf45 (patch)
tree0fee09e170431ba88501ee165743a4d7010e6a84 /src
parent29be90bf95f2ea10c435e7b02f8c26626b956417 (diff)
Spans for group and block contents 📐
Diffstat (limited to 'src')
-rw-r--r--src/eval/mod.rs48
-rw-r--r--src/parse/collection.rs2
-rw-r--r--src/parse/mod.rs2
-rw-r--r--src/syntax/expr.rs92
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)]