From 830ffa92c49f58507bc5ca591d03a1e3bda325f8 Mon Sep 17 00:00:00 2001 From: Joscha Date: Tue, 22 Nov 2022 10:32:27 +0100 Subject: [PATCH] Desugar table destructuring --- src/desugar.rs | 1 + src/desugar/basic.rs | 14 +++++++ src/desugar/expr.rs | 4 +- src/desugar/table_destr.rs | 81 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 src/desugar/table_destr.rs diff --git a/src/desugar.rs b/src/desugar.rs index db66687..e1d23c1 100644 --- a/src/desugar.rs +++ b/src/desugar.rs @@ -5,4 +5,5 @@ mod field; mod lit; mod program; mod table_constr; +mod table_destr; mod var; diff --git a/src/desugar/basic.rs b/src/desugar/basic.rs index 55526cf..6f9ec72 100644 --- a/src/desugar/basic.rs +++ b/src/desugar/basic.rs @@ -22,6 +22,20 @@ impl BoundedSeparated { (new, desugared) } + pub fn map(self, f: impl Fn(E) -> E2) -> BoundedSeparated { + let elems = self + .elems + .into_iter() + .map(|(s0, e, s1)| (s0, f(e), s1)) + .collect::>(); + + BoundedSeparated { + elems, + trailing: self.trailing, + span: self.span, + } + } + pub fn remove_map( self, f: impl Fn(E) -> Result, diff --git a/src/desugar/expr.rs b/src/desugar/expr.rs index 5f7cb02..7a8a197 100644 --- a/src/desugar/expr.rs +++ b/src/desugar/expr.rs @@ -12,9 +12,9 @@ impl Expr { Self::Field(field) => field.desugar(), Self::Var(var) => var.desugar(), Self::TableConstr(constr) => constr.desugar(), + Self::TableDestr(destr) => destr.desugar(), - Self::TableDestr(destr) => (Self::TableDestr(destr), false), // TODO Implement - Self::FuncDef(def) => (Self::FuncDef(def), false), // TODO Implement + Self::FuncDef(def) => (Self::FuncDef(def), false), // TODO Implement Self::Paren { s0, diff --git a/src/desugar/table_destr.rs b/src/desugar/table_destr.rs new file mode 100644 index 0000000..7152010 --- /dev/null +++ b/src/desugar/table_destr.rs @@ -0,0 +1,81 @@ +use crate::ast::{ + BoundedSeparated, Call, Expr, Ident, Lit, Space, StringLit, TableConstr, TableConstrElem, + TableDestr, TableLitElem, TablePattern, TablePatternElem, +}; +use crate::builtin::Builtin; + +fn pattern_to_constr(pattern: TablePattern) -> TableConstr { + TableConstr(pattern.0.map(|e| match e { + TablePatternElem::Positional(ident) => TableConstrElem::Lit(TableLitElem::Positional( + Box::new(Expr::Lit(Lit::String(StringLit::from_ident(ident)))), + )), + + TablePatternElem::Named { + name, + s0, + s1, + ident, + span, + } => TableConstrElem::Lit(TableLitElem::Named { + name, + s0, + s1, + value: Box::new(Expr::Lit(Lit::String(StringLit::from_ident(ident)))), + span, + }), + })) +} + +impl TableDestr { + pub fn desugar(self) -> (Expr, bool) { + let Self { + local, + pattern, + 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 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, + span, + }); + (new, true) + } +}