///|
#as_free_fn
pub fn CoreForm::compile(self : CoreForm) -> Inst {
fn then(exp, next) {
match exp {
SelfEval(v) | Quote(v) => Const(v, next)
Var(name) => Refer(name, next)
Lambda(parm_names, body) => {
let body = then(body, Return)
let name = match next {
Define(name, _) | Set(name, _) => Some(name)
_ => None
}
Close(parm_names, body, name, next)
}
Begin(bodys, bodye) => {
let bodyei = then(bodye, next)
bodys.rev_fold(init=bodyei, (acc, x) => then(x, acc))
}
If(ep, et, ef) => {
let eti = then(et, next)
let efi = match ef {
Some(ef) => then(ef, next)
None => next
}
then(ep, Branch(eti, efi))
}
Apply(f, args) => {
let length = args.length()
let fi = then(f, Apply)
let argsi = Args(
length,
args.rev_foldi(init=fi, (i, acc, x) => {
then(x, Push(length - 1 - i, acc))
}),
)
match next {
Return => argsi
_ => Save(argsi, next)
}
}
Set(name, e) => then(e, Set(name, next))
Define(name, e) => then(e, Define(name, next))
}
}
then(self, Return)
}