Allow redefining local variables with "fn"
This commit is contained in:
parent
58af636293
commit
353102f8cd
2 changed files with 46 additions and 9 deletions
|
@ -820,16 +820,42 @@ Result<Expression> Compiler::compile_fn(Context& context, Symbol& op,
|
||||||
Oc::MakeClosure, {0, (int64_t)reg},
|
Oc::MakeClosure, {0, (int64_t)reg},
|
||||||
{0, (int64_t)reg + (int64_t)TRY(ctx.closures.size()) + 1}));
|
{0, (int64_t)reg + (int64_t)TRY(ctx.closures.size()) + 1}));
|
||||||
|
|
||||||
if (context.toplevel && !name.is<Nil>()) {
|
if (!name.is<Nil>()) {
|
||||||
|
if (context.toplevel) {
|
||||||
int64_t gname = TRY(context.add_const(name));
|
int64_t gname = TRY(context.add_const(name));
|
||||||
TRY(ex_res.add_opcode(Oc::GlobalStore, {1, (int64_t)gname},
|
TRY(ex_res.add_opcode(Oc::GlobalStore, {1, (int64_t)gname},
|
||||||
{0, (int64_t)reg}));
|
{0, (int64_t)reg}));
|
||||||
}
|
|
||||||
|
|
||||||
context.maxreg = reg + 1;
|
context.maxreg = reg + 1;
|
||||||
ex_res.reg = reg;
|
ex_res.reg = reg;
|
||||||
|
|
||||||
return ex_res;
|
return ex_res;
|
||||||
|
} else {
|
||||||
|
auto maybe_binding = context.get_var(name);
|
||||||
|
|
||||||
|
if (maybe_binding.has_value()) {
|
||||||
|
auto breg = maybe_binding.value();
|
||||||
|
TRY(ex_res.add_opcode(Oc::Mov, {0, (int64_t)breg}, {0, (int64_t)reg}));
|
||||||
|
ex_res.reg = reg;
|
||||||
|
|
||||||
|
context.maxreg = reg + 1;
|
||||||
|
return std::move(ex_res);
|
||||||
|
} else {
|
||||||
|
context.maxreg = reg + 1;
|
||||||
|
auto breg = TRY(context.add_var(name));
|
||||||
|
|
||||||
|
TRY(ex_res.add_opcode(Oc::Mov, {0, (int64_t)breg}, {0, (int64_t)reg}));
|
||||||
|
ex_res.reg = breg;
|
||||||
|
context.maxreg = breg + 1;
|
||||||
|
|
||||||
|
return std::move(ex_res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
context.maxreg = reg + 1;
|
||||||
|
ex_res.reg = reg;
|
||||||
|
|
||||||
|
return ex_res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<Expression> Compiler::compile_let(Context& context, Symbol& op,
|
Result<Expression> Compiler::compile_let(Context& context, Symbol& op,
|
||||||
|
@ -924,6 +950,7 @@ Result<Expression> Compiler::compile_body(Context& context, const Value& expr) {
|
||||||
if (cur.is<Nil>()) {
|
if (cur.is<Nil>()) {
|
||||||
ex_res.reg = expr.reg;
|
ex_res.reg = expr.reg;
|
||||||
} else {
|
} else {
|
||||||
|
// TODO: commenting this out means we waste registers
|
||||||
// context.maxreg = maxreg;
|
// context.maxreg = maxreg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,3 +65,13 @@
|
||||||
(+ x y))
|
(+ x y))
|
||||||
|
|
||||||
(assert (= (def-redef) 6))
|
(assert (= (def-redef) 6))
|
||||||
|
|
||||||
|
;; allow redefenition of variables with "fn"
|
||||||
|
|
||||||
|
(fn def-redef-fn ()
|
||||||
|
(def x 2)
|
||||||
|
(fn x (y) (+ x y))
|
||||||
|
(x 3)
|
||||||
|
)
|
||||||
|
|
||||||
|
(assert (= (def-redef-fn) 5))
|
||||||
|
|
Loading…
Reference in a new issue