diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-01-26 21:13:52 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-01-26 21:13:52 +0100 |
| commit | e8470824352064fefbb5d0d30a728211d11cea53 (patch) | |
| tree | 128b49fd0609566584d1c2822db25303806e3e43 /src/syntax | |
| parent | aaa48403cdd3d8499584eeca4103865d6425ac1b (diff) | |
Multi-expression blocks 🛍️
Diffstat (limited to 'src/syntax')
| -rw-r--r-- | src/syntax/expr.rs | 51 | ||||
| -rw-r--r-- | src/syntax/span.rs | 3 |
2 files changed, 36 insertions, 18 deletions
diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs index 6be9d632..afeac988 100644 --- a/src/syntax/expr.rs +++ b/src/syntax/expr.rs @@ -75,11 +75,7 @@ impl Pretty for Expr { v.v.pretty(p); p.push_str(")"); } - Self::Block(v) => { - p.push_str("{"); - v.v.pretty(p); - p.push_str("}"); - } + Self::Block(v) => v.pretty(p), Self::Unary(v) => v.pretty(p), Self::Binary(v) => v.pretty(p), Self::Call(v) => v.pretty(p), @@ -139,10 +135,28 @@ impl Pretty for Named { pub type ExprTemplate = Tree; /// A grouped expression: `(1 + 2)`. -pub type ExprGroup = Box<Spanned<Expr>>; +pub type ExprGroup = SpanBox<Expr>; /// A block expression: `{1 + 2}`. -pub type ExprBlock = Box<Spanned<Expr>>; +#[derive(Debug, Clone, PartialEq)] +pub struct ExprBlock { + /// The list of expressions contained in the block. + pub exprs: SpanVec<Expr>, +} + +impl Pretty for ExprBlock { + fn pretty(&self, p: &mut Printer) { + p.push_str("{"); + if self.exprs.len() > 1 { + p.push_str(" "); + } + p.join(&self.exprs, "; ", |expr, p| expr.v.pretty(p)); + if self.exprs.len() > 1 { + p.push_str(" "); + } + p.push_str("}"); + } +} /// A unary operation: `-x`. #[derive(Debug, Clone, PartialEq)] @@ -150,7 +164,7 @@ pub struct ExprUnary { /// The operator: `-`. pub op: Spanned<UnOp>, /// The expression to operator on: `x`. - pub expr: Box<Spanned<Expr>>, + pub expr: SpanBox<Expr>, } impl Pretty for ExprUnary { @@ -213,11 +227,11 @@ impl Pretty for UnOp { #[derive(Debug, Clone, PartialEq)] pub struct ExprBinary { /// The left-hand side of the operation: `a`. - pub lhs: Box<Spanned<Expr>>, + pub lhs: SpanBox<Expr>, /// The operator: `+`. pub op: Spanned<BinOp>, /// The right-hand side of the operation: `b`. - pub rhs: Box<Spanned<Expr>>, + pub rhs: SpanBox<Expr>, } impl Pretty for ExprBinary { @@ -376,7 +390,7 @@ pub enum Associativity { #[derive(Debug, Clone, PartialEq)] pub struct ExprCall { /// The callee of the function. - pub callee: Box<Spanned<Expr>>, + pub callee: SpanBox<Expr>, /// The arguments to the function. pub args: Spanned<ExprArgs>, } @@ -466,17 +480,17 @@ impl Pretty for Argument { pub struct ExprLet { /// The pattern to assign to. pub pat: Spanned<Ident>, - /// The expression to assign to the pattern. - pub expr: Option<Box<Spanned<Expr>>>, + /// The expression the pattern is initialized with. + pub init: Option<SpanBox<Expr>>, } impl Pretty for ExprLet { fn pretty(&self, p: &mut Printer) { p.push_str("#let "); p.push_str(&self.pat.v); - if let Some(expr) = &self.expr { + if let Some(init) = &self.init { p.push_str(" = "); - expr.v.pretty(p); + init.v.pretty(p); } } } @@ -485,11 +499,11 @@ impl Pretty for ExprLet { #[derive(Debug, Clone, PartialEq)] pub struct ExprIf { /// The condition which selects the body to evaluate. - pub condition: Box<Spanned<Expr>>, + pub condition: SpanBox<Expr>, /// The expression to evaluate if the condition is true. - pub if_body: Box<Spanned<Expr>>, + pub if_body: SpanBox<Expr>, /// The expression to evaluate if the condition is false. - pub else_body: Option<Box<Spanned<Expr>>>, + pub else_body: Option<SpanBox<Expr>>, } impl Pretty for ExprIf { @@ -520,6 +534,7 @@ mod tests { #[test] fn test_pretty_print_expressions() { // Unary and binary operations. + test_pretty("{}", "{}"); test_pretty("{1 +}", "{1}"); test_pretty("{1++1}", "{1 + +1}"); test_pretty("{+-1}", "{+-1}"); diff --git a/src/syntax/span.rs b/src/syntax/span.rs index 21fa9ab8..5087dffa 100644 --- a/src/syntax/span.rs +++ b/src/syntax/span.rs @@ -34,6 +34,9 @@ impl<T> Offset for SpanVec<T> { } } +/// A box of a spanned value of type `T`. +pub type SpanBox<T> = Box<Spanned<T>>; + /// 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))] |
