Desugar table destructuring

This commit is contained in:
Joscha 2022-11-22 10:32:27 +01:00
parent d4797c5894
commit 830ffa92c4
4 changed files with 98 additions and 2 deletions

View file

@ -5,4 +5,5 @@ mod field;
mod lit;
mod program;
mod table_constr;
mod table_destr;
mod var;

View file

@ -22,6 +22,20 @@ impl<E> BoundedSeparated<E> {
(new, desugared)
}
pub fn map<E2>(self, f: impl Fn(E) -> E2) -> BoundedSeparated<E2> {
let elems = self
.elems
.into_iter()
.map(|(s0, e, s1)| (s0, f(e), s1))
.collect::<Vec<_>>();
BoundedSeparated {
elems,
trailing: self.trailing,
span: self.span,
}
}
pub fn remove_map<E1, E2>(
self,
f: impl Fn(E) -> Result<E1, E2>,

View file

@ -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,

View file

@ -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)
}
}