128 lines
4.2 KiB
Rust
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)
|
|
}
|
|
}
|
|
}
|
|
}
|