tada/src/desugar/func_def.rs

128 lines
4.2 KiB
Rust

use crate::ast::{
BoundedSeparated, Call, Expr, FuncDef, Ident, Lit, Space, TableConstrElem, TableDestr,
TableLitElem, Var,
};
use crate::builtin::Builtin;
impl FuncDef {
pub fn desugar(self) -> (Expr, bool) {
match self {
Self::AnonNoArg {
s0: _,
s1: _,
s2: _,
body,
span,
} => {
let quote = BoundedSeparated::new(span)
.then(TableLitElem::named(Ident::new("quote", span), body, span))
.table_lit();
let scope = Call::no_arg(Lit::Builtin(Builtin::Scope, span).expr().boxed(), span);
let new = BoundedSeparated::new(span)
.then(TableConstrElem::positional(Box::new(quote.lit().expr())))
.then(TableConstrElem::named(
Ident::new("scope", span),
scope.expr().boxed(),
span,
))
.table_constr();
(new.expr(), true)
}
Self::AnonArg {
s0: _,
s1: _,
arg,
s2: _,
s3: _,
body,
span,
} => {
let arg_call = Call::no_arg(Lit::Builtin(Builtin::Arg, span).expr().boxed(), span);
let arg_assign = Var::assign_ident(true, arg, arg_call.expr().boxed(), span);
let body = BoundedSeparated::new(span)
.then(TableLitElem::Positional(arg_assign.expr().boxed()))
.then(TableLitElem::Positional(body))
.table_lit();
let new = Self::AnonNoArg {
s0: Space::empty(span),
s1: Space::empty(span),
s2: Space::empty(span),
body: body.lit().expr().boxed(),
span,
};
(new.expr(), true)
}
Self::AnonDestr {
s0: _,
pattern,
s1: _,
body,
span,
} => {
let arg_call = Call::no_arg(Lit::Builtin(Builtin::Arg, span).expr().boxed(), span);
let arg_destr = TableDestr::new(true, pattern, arg_call.expr().boxed(), span);
let body = BoundedSeparated::new(span)
.then(TableLitElem::Positional(arg_destr.expr().boxed()))
.then(TableLitElem::Positional(body))
.table_lit();
let new = Self::AnonNoArg {
s0: Space::empty(span),
s1: Space::empty(span),
s2: Space::empty(span),
body: body.lit().expr().boxed(),
span,
};
(new.expr(), true)
}
Self::NamedNoArg {
local,
s0: _,
name,
s1: _,
s2: _,
s3: _,
body,
span,
} => {
let anon = Self::anon_no_arg(body, span);
let new = Var::assign_ident(local.is_some(), name, anon.expr().boxed(), span);
(new.expr(), true)
}
Self::NamedArg {
local,
s0: _,
name,
s1: _,
s2: _,
arg,
s3: _,
s4: _,
body,
span,
} => {
let anon = Self::anon_arg(arg, body, span);
let new = Var::assign_ident(local.is_some(), name, anon.expr().boxed(), span);
(new.expr(), true)
}
Self::NamedDestr {
local,
s0: _,
name,
s1: _,
pattern,
s2: _,
body,
span,
} => {
let anon = Self::anon_destr(pattern, body, span);
let new = Var::assign_ident(local.is_some(), name, anon.expr().boxed(), span);
(new.expr(), true)
}
}
}
}