diff --git a/src/ast/basic.rs b/src/ast/basic.rs index 5056f21..3528b7d 100644 --- a/src/ast/basic.rs +++ b/src/ast/basic.rs @@ -89,3 +89,19 @@ impl HasSpan for BoundedSeparated { self.span } } + +impl BoundedSeparated { + pub fn new(span: Span) -> Self { + Self { + elems: vec![], + trailing: None, + span, + } + } + + pub fn then(mut self, elem: E) -> Self { + self.elems + .push((Space::empty(self.span), elem, Space::empty(self.span))); + self + } +} diff --git a/src/desugar/call.rs b/src/desugar/call.rs index 70cd2c4..b09b7a3 100644 --- a/src/desugar/call.rs +++ b/src/desugar/call.rs @@ -7,14 +7,12 @@ impl Call { match self { Self::Arg { expr, - s0, - s1, + s0: _, + s1: _, arg, - s2, + s2: _, span, } => { - // `expr s0 ( s1 arg s2 )` - // -> `'{ s0 call: expr, arg: s1 arg s2 }` let call = TableLitElem::Named { name: Ident::new("call", span), s0: Space::empty(span), @@ -25,25 +23,17 @@ impl Call { let arg = TableLitElem::Named { name: Ident::new("arg", span), s0: Space::empty(span), - s1, + s1: Space::empty(span), value: arg, span, }; - let elems = vec![ - (s0, call, Space::empty(span)), - (Space::empty(span), arg, s2), - ]; - let new = Expr::Lit(Lit::Table(TableLit(BoundedSeparated { - elems, - trailing: None, - span, - }))); + let new = Expr::Lit(Lit::Table(TableLit( + BoundedSeparated::new(span).then(call).then(arg), + ))); (new, true) } Self::NoArg { expr, s0, s1, span } => { - // `expr s0 ( s1 )` - // -> `expr s0 ( s1 nil )` let new = Expr::Call(Self::Arg { expr, s0, @@ -61,8 +51,6 @@ impl Call { constr, span, } => { - // `expr s0 {..}` - // -> `expr s0 ( {..} )` let new = Expr::Call(Self::Arg { expr, s0, diff --git a/src/desugar/field.rs b/src/desugar/field.rs index 30dfc5b..84005b7 100644 --- a/src/desugar/field.rs +++ b/src/desugar/field.rs @@ -1,5 +1,5 @@ use crate::ast::{ - BoundedSeparated, Call, Expr, Field, Line, Lit, Space, StringLit, TableConstr, TableConstrElem, + BoundedSeparated, Call, Expr, Field, Lit, Space, StringLit, TableConstr, TableConstrElem, TableLitElem, }; use crate::builtin::Builtin; @@ -9,34 +9,21 @@ impl Field { match self { Self::Access { expr, - s0, - s1, + s0: _, + s1: _, index, - s2, + s2: _, span, } => { - // ` expr s0 [ s1 index s2 ]` - // -> `'get s0 { expr, s1 index s2 }` - let elems = vec![ - ( - Space::empty(span), - TableConstrElem::Lit(TableLitElem::Positional(expr)), - Space::empty(span), - ), - ( - s1, - TableConstrElem::Lit(TableLitElem::Positional(index)), - s2, - ), - ]; + let constr = TableConstr( + BoundedSeparated::new(span) + .then(TableConstrElem::Lit(TableLitElem::Positional(expr))) + .then(TableConstrElem::Lit(TableLitElem::Positional(index))), + ); let new = Expr::Call(Call::Constr { expr: Box::new(Expr::Lit(Lit::Builtin(Builtin::Get, span))), - s0, - constr: TableConstr(BoundedSeparated { - elems, - trailing: None, - span, - }), + s0: Space::empty(span), + constr, span, }); (new, true) @@ -44,42 +31,25 @@ impl Field { Self::Assign { expr, - s0, - s1, + s0: _, + s1: _, index, - s2, - s3, - s4, + s2: _, + s3: _, + s4: _, value, span, } => { - // `expr s0 [ s1 index s2 ] s3 = s4 value` - // -> `'set s0 { expr, s1 index s2, s3 s4 value }` - let elems = vec![ - ( - Space::empty(span), - TableConstrElem::Lit(TableLitElem::Positional(expr)), - Space::empty(span), - ), - ( - s1, - TableConstrElem::Lit(TableLitElem::Positional(index)), - s2, - ), - ( - s3.then_line(Line::Empty).then(s4), - TableConstrElem::Lit(TableLitElem::Positional(value)), - Space::empty(span), - ), - ]; + let constr = TableConstr( + BoundedSeparated::new(span) + .then(TableConstrElem::Lit(TableLitElem::Positional(expr))) + .then(TableConstrElem::Lit(TableLitElem::Positional(index))) + .then(TableConstrElem::Lit(TableLitElem::Positional(value))), + ); let new = Expr::Call(Call::Constr { expr: Box::new(Expr::Lit(Lit::Builtin(Builtin::Set, span))), - s0, - constr: TableConstr(BoundedSeparated { - elems, - trailing: None, - span, - }), + s0: Space::empty(span), + constr, span, }); (new, true) diff --git a/src/desugar/func_def.rs b/src/desugar/func_def.rs index 7a6b362..4f3c396 100644 --- a/src/desugar/func_def.rs +++ b/src/desugar/func_def.rs @@ -8,66 +8,46 @@ impl FuncDef { pub fn desugar(self) -> (Expr, bool) { match self { Self::AnonNoArg { - s0, - s1, - s2, + s0: _, + s1: _, + s2: _, body, span, } => { - // `function s0 ( s1 ) s2 body` - // -> `{ '{ quote: body }, scope: 'scope() }` - let quote = Expr::Lit(Lit::Table(TableLit(BoundedSeparated { - elems: vec![( - Space::empty(span), - TableLitElem::Named { - name: Ident::new("quote", span), - s0: Space::empty(span), - s1: Space::empty(span), - value: body, - span, - }, - Space::empty(span), - )], - trailing: None, + let quote = TableLit(BoundedSeparated::new(span).then(TableLitElem::Named { + name: Ident::new("quote", span), + s0: Space::empty(span), + s1: Space::empty(span), + value: body, span, - }))); + })); + let quote = Box::new(Expr::Lit(Lit::Table(quote))); let scope = Expr::Call(Call::NoArg { expr: Box::new(Expr::Lit(Lit::Builtin(Builtin::Scope, span))), s0: Space::empty(span), s1: Space::empty(span), span, }); - let new = Expr::TableConstr(TableConstr(BoundedSeparated { - elems: vec![ - ( - Space::empty(span), - TableConstrElem::Lit(TableLitElem::Positional(Box::new(quote))), - Space::empty(span), - ), - ( - Space::empty(span), - TableConstrElem::Lit(TableLitElem::Named { - name: Ident::new("scope", span), - s0: Space::empty(span), - s1: Space::empty(span), - value: Box::new(scope), - span, - }), - Space::empty(span), - ), - ], - trailing: None, - span, - })); + let new = Expr::TableConstr(TableConstr( + BoundedSeparated::new(span) + .then(TableConstrElem::Lit(TableLitElem::Positional(quote))) + .then(TableConstrElem::Lit(TableLitElem::Named { + name: Ident::new("scope", span), + s0: Space::empty(span), + s1: Space::empty(span), + value: Box::new(scope), + span, + })), + )); (new, true) } Self::AnonArg { - s0, - s1, + s0: _, + s1: _, arg, - s2, - s3, + s2: _, + s3: _, body, span, } => { @@ -87,28 +67,14 @@ impl FuncDef { value: Box::new(arg_call), span, }); - let body_elems = vec![ - ( - Space::empty(span), - TableLitElem::Positional(Box::new(arg_assign)), - Space::empty(span), - ), - ( - Space::empty(span), - TableLitElem::Positional(body), - Space::empty(span), - ), - ]; - let body = Expr::Lit(Lit::Table(TableLit(BoundedSeparated { - elems: body_elems, - trailing: None, - span, - }))); + let body = BoundedSeparated::new(span) + .then(TableLitElem::Positional(Box::new(arg_assign))) + .then(TableLitElem::Positional(body)); let new = Expr::FuncDef(Self::AnonNoArg { s0: Space::empty(span), s1: Space::empty(span), s2: Space::empty(span), - body: Box::new(body), + body: Box::new(Expr::Lit(Lit::Table(TableLit(body)))), span, }); (new, true) diff --git a/src/desugar/table_constr.rs b/src/desugar/table_constr.rs index aa37214..2bb4eff 100644 --- a/src/desugar/table_constr.rs +++ b/src/desugar/table_constr.rs @@ -28,11 +28,9 @@ impl TableConstr { value: Box::new(Expr::Lit(Lit::Table(TableLit(elems)))), span, }; - let mut expr = Expr::Lit(Lit::Table(TableLit(BoundedSeparated { - elems: vec![(Space::empty(span), raw_elem, Space::empty(span))], - trailing: None, - span, - }))); + let mut expr = Expr::Lit(Lit::Table(TableLit( + BoundedSeparated::new(span).then(raw_elem), + ))); // `sl [ s0 index s1 ] s2 = s3 value sr` // -> `expr s0 [ s1 index s2 ] s3 = s4 s5 value` diff --git a/src/desugar/table_destr.rs b/src/desugar/table_destr.rs index 7152010..8d68a00 100644 --- a/src/desugar/table_destr.rs +++ b/src/desugar/table_destr.rs @@ -31,49 +31,31 @@ impl TableDestr { let Self { local, pattern, - s0, - s1, + s0: _, + s1: _, value, span, } = self; - let mut elems = vec![ - ( - Space::empty(span), - TableConstrElem::Lit(TableLitElem::Positional(Box::new(Expr::TableConstr( - pattern_to_constr(pattern), - )))), - s0, - ), - ( - s1, - TableConstrElem::Lit(TableLitElem::Positional(value)), - Space::empty(span), - ), - ]; - if let Some(local) = local { - elems.push(( - Space::empty(span), - TableConstrElem::Lit(TableLitElem::Named { - name: Ident::new("local", span), - s0: Space::empty(span), - s1: Space::empty(span), - value: Box::new(Expr::Lit(Lit::Bool(true, span))), - span, - }), - local, - )) + let mut constr = BoundedSeparated::new(span) + .then(TableConstrElem::Lit(TableLitElem::Positional(Box::new( + Expr::TableConstr(pattern_to_constr(pattern)), + )))) + .then(TableConstrElem::Lit(TableLitElem::Positional(value))); + if local.is_some() { + constr = constr.then(TableConstrElem::Lit(TableLitElem::Named { + name: Ident::new("local", span), + s0: Space::empty(span), + s1: Space::empty(span), + value: Box::new(Expr::Lit(Lit::Bool(true, span))), + span, + })); } - let constr = TableConstr(BoundedSeparated { - elems, - trailing: None, - span, - }); let new = Expr::Call(Call::Constr { expr: Box::new(Expr::Lit(Lit::Builtin(Builtin::Destructure, span))), s0: Space::empty(span), - constr, + constr: TableConstr(constr), span, }); (new, true) diff --git a/src/desugar/var.rs b/src/desugar/var.rs index 2ea1997..7019702 100644 --- a/src/desugar/var.rs +++ b/src/desugar/var.rs @@ -1,5 +1,5 @@ use crate::ast::{ - BoundedSeparated, Call, Expr, Field, Line, Lit, Space, StringLit, TableConstr, TableConstrElem, + BoundedSeparated, Call, Expr, Field, Lit, Space, StringLit, TableConstr, TableConstrElem, TableLitElem, Var, }; use crate::builtin::Builtin; @@ -66,48 +66,33 @@ impl Var { } Self::Assign { - local: Some(local), - s0, + local: Some(_), + s0: _, index, - s1, - s2, - s3, + s1: _, + s2: _, + s3: _, value, span, } => { - // `local [ s0 index s1 ] s2 = s3 value` - // --> `'setraw { 'scope(), local s0 index s1, s2 s3 value }` let scope = Expr::Call(Call::NoArg { expr: Box::new(Expr::Lit(Lit::Builtin(Builtin::Scope, span))), s0: Space::empty(span), s1: Space::empty(span), span, }); - let elems = vec![ - ( - Space::empty(span), - TableConstrElem::Lit(TableLitElem::Positional(Box::new(scope))), - Space::empty(span), - ), - ( - local.then_line(Line::Empty).then(s0), - TableConstrElem::Lit(TableLitElem::Positional(index)), - s1, - ), - ( - s2.then_line(Line::Empty).then(s3), - TableConstrElem::Lit(TableLitElem::Positional(value)), - Space::empty(span), - ), - ]; + let constr = TableConstr( + BoundedSeparated::new(span) + .then(TableConstrElem::Lit(TableLitElem::Positional(Box::new( + scope, + )))) + .then(TableConstrElem::Lit(TableLitElem::Positional(index))) + .then(TableConstrElem::Lit(TableLitElem::Positional(value))), + ); let new = Expr::Call(Call::Constr { expr: Box::new(Expr::Lit(Lit::Builtin(Builtin::SetRaw, span))), s0: Space::empty(span), - constr: TableConstr(BoundedSeparated { - elems, - trailing: None, - span, - }), + constr, span, }); (new, true)