Implement access to previously defined functions in REPL

This commit is contained in:
Konstantin Nazarov 2024-09-01 14:31:25 +01:00
parent 5279b44441
commit 7d160da5d0
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
10 changed files with 50 additions and 40 deletions

View file

@ -224,7 +224,6 @@ Result<PodObject*> Arena::gc_module(PodModule* obj) {
auto nobj = TRY(alloc<PodModule>());
nobj->header.tag = Tag::Module;
nobj->name = TRY(gc_pod(obj->name.get()));
nobj->globals = TRY(gc_pod(obj->globals.get()));
nobj->fun = TRY(gc_pod(obj->fun.get()));
return nobj;

View file

@ -195,11 +195,6 @@ Result<short> Module::cmp(const Module& rhs) const {
auto lhs_fun = TRY(fun());
auto rhs_fun = TRY(rhs.fun());
res = TRY(lhs_fun.cmp(rhs_fun));
if (res != 0) return res;
auto lhs_globals = TRY(globals());
auto rhs_globals = TRY(rhs.globals());
res = TRY(lhs_globals.cmp(rhs_globals));
return res;
}
@ -347,13 +342,11 @@ StdlibFunctionId StdlibFunction::fun_id() const {
return StdlibFunctionId(_value->fun_id);
}
Result<Module> Module::create(const Value& name, const Function& fun,
const Dict& globals) {
Result<Module> Module::create(const Value& name, const Function& fun) {
auto pod = TRY(arena_alloc<PodModule>());
pod->header.tag = Tag::Module;
pod->name = name.pod();
pod->fun = fun.pod();
pod->globals = globals.pod();
return Module(TRY(MkGcRoot(pod)));
}
@ -364,10 +357,6 @@ Result<Function> Module::fun() const {
return Function::create((PodFunction*)_value->fun.get());
}
Result<Dict> Module::globals() const {
return Dict::create((PodDict*)_value->globals.get());
}
Result<Value> reverse(Value& val) {
if (val.is<Nil>()) return Value(TRY(Nil::create()));
if (!val.is<Pair>()) return ERROR(TypeMismatch);

View file

@ -994,12 +994,10 @@ class Module : public Object {
return Module(TRY(MkGcRoot(obj)));
}
static Result<Module> create(const Value& name, const Function& fun,
const Dict& globals);
static Result<Module> create(const Value& name, const Function& fun);
Result<Value> name() const;
Result<Function> fun() const;
Result<Dict> globals() const;
virtual Result<Value> copy_value() const final;
Result<Module> copy() const;

View file

@ -8,14 +8,13 @@ struct Context {
Context(Value&& fname, Array&& constants, Dict&& constants_dict,
Dict&& variables_dict, Array&& closures, Dict&& closures_dict,
Dict&& globals_dict, Context* parent, bool toplevel)
Context* parent, bool toplevel)
: fname(std::move(fname)),
constants(std::move(constants)),
constants_dict(std::move(constants_dict)),
variables_dict(std::move(variables_dict)),
closures(std::move(closures)),
closures_dict(std::move(closures_dict)),
globals_dict(std::move(globals_dict)),
maxreg(0),
parent(parent),
toplevel(toplevel) {}
@ -27,12 +26,10 @@ struct Context {
auto variables_dict = TRY(Dict::create());
auto closures = TRY(Array::create());
auto closures_dict = TRY(Dict::create());
auto globals_dict = TRY(Dict::create());
return Context(std::move(fname), std::move(constants),
std::move(constants_dict), std::move(variables_dict),
std::move(closures), std::move(closures_dict),
std::move(globals_dict), 0, true);
std::move(closures), std::move(closures_dict), 0, true);
}
static Result<Context> create(Context& parent) {
@ -42,12 +39,11 @@ struct Context {
auto variables_dict = TRY(Dict::create());
auto closures = TRY(Array::create());
auto closures_dict = TRY(Dict::create());
auto globals_dict = TRY(Dict::create());
return Context(std::move(fname), std::move(constants),
std::move(constants_dict), std::move(variables_dict),
std::move(closures), std::move(closures_dict),
std::move(globals_dict), &parent, false);
std::move(closures), std::move(closures_dict), &parent,
false);
}
uint64_t alloc_reg() {
@ -143,18 +139,12 @@ struct Context {
return i;
}
Result<void> add_global(const Value& name, const Value& value) {
globals_dict = TRY(globals_dict.insert(name, value));
return Result<void>();
}
Value fname;
Array constants;
Dict constants_dict;
Dict variables_dict;
Array closures;
Dict closures_dict;
Dict globals_dict;
uint64_t maxreg;
Context* parent;
bool toplevel;
@ -196,7 +186,7 @@ Result<Value> Compiler::compile(Value& expr) {
auto fun = TRY(Function::create(name, 0, context.constants, ex.code,
TRY(Array::create())));
auto mod = TRY(Module::create(name, fun, context.globals_dict));
auto mod = TRY(Module::create(name, fun));
return Value(std::move(mod));
}
@ -216,7 +206,7 @@ Result<Value> Compiler::compile(Value& expr) {
auto fun = TRY(Function::create(name, 0, context.constants, ex.code,
TRY(Array::create())));
auto mod = TRY(Module::create(name, fun, context.globals_dict));
auto mod = TRY(Module::create(name, fun));
return Value(std::move(mod));
}
@ -634,12 +624,14 @@ Result<Expression> Compiler::compile_fn(Context& context, Symbol& op,
Expression ex_res = TRY(Expression::create());
if (ctx.closures.size() == 0) {
if (context.toplevel && !name.is<Nil>()) {
context.add_global(name, TRY(fun.copy()));
}
int64_t c = TRY(context.add_const(TRY(fun.copy())));
if (context.toplevel && !name.is<Nil>()) {
int64_t gname = TRY(context.add_const(name));
TRY(ex_res.add_opcode(Oc::GlobalStore, {1, (int64_t)gname},
{1, (int64_t)c}));
}
uint64_t reg = context.alloc_reg();
TRY(ex_res.add_opcode(Oc::Mov, {0, (int64_t)reg}, {1, (int64_t)c}));

View file

@ -80,6 +80,8 @@ op_t get_op(Oc op) {
return op_t{"setglobal", OpcodeType::Reg2};
case Oc::GlobalLoad:
return op_t{"global-load", OpcodeType::Reg2};
case Oc::GlobalStore:
return op_t{"global-store", OpcodeType::Reg2};
case Oc::MakeClosure:
return op_t{"make-closure", OpcodeType::Reg2};
case Oc::ClosureLoad:

View file

@ -61,6 +61,7 @@ enum class Oc : uint8_t {
SetJump,
// Globals
GlobalLoad,
GlobalStore,
// Closures
MakeClosure,
ClosureLoad,

View file

@ -183,7 +183,6 @@ class PodModule final : public PodObject {
OffPtr<PodObject> name;
OffPtr<PodObject> fun;
OffPtr<PodObject> globals;
};
class PodStack final : public PodObject {

View file

@ -28,9 +28,17 @@ Result<Value> run_string(const String& src) {
}
Result<void> run_repl() {
Dict globals = TRY(Dict::create());
while (true) {
auto src = TRY(read_line("vli> "));
auto res = TRY(run_string(src));
auto parsed = TRY(read_multiple(src));
auto compiled = TRY(compile(parsed));
Module& mod = *compiled.to<Module>();
auto vm = TRY(VM::create());
auto res = TRY(vm.run(mod, globals));
globals = TRY(vm.globals());
if (!res.is<Nil>()) {
debug_print(res);
}

View file

@ -249,6 +249,15 @@ Result<void> VM::vm_global_load(Opcode& oc) {
return Result<void>();
}
Result<void> VM::vm_global_store(Opcode& oc) {
Value sym = TRY(get(oc.arg1().is_const, (uint64_t)oc.arg1().arg));
Value val = TRY(get(oc.arg2().is_const, (uint64_t)oc.arg2().arg));
_globals = TRY(_globals.insert(sym, val));
_pc++;
return Result<void>();
}
Result<void> VM::step() {
auto opcode = TRY(_code.get(_pc));
if (!opcode.is<Opcode>()) return ERROR(TypeMismatch);
@ -302,6 +311,9 @@ Result<void> VM::step() {
case Oc::GlobalLoad:
TRY(vm_global_load(oc));
break;
case Oc::GlobalStore:
TRY(vm_global_store(oc));
break;
default:
return ERROR(NotImplemented);
}
@ -311,14 +323,14 @@ Result<void> VM::step() {
// Result<Value> Int64::copy() const { return Value(Int64(TRY(_value.copy())));
// }
Result<Value> VM::run(const Module& mod) {
Result<Value> VM::run(const Module& mod, const Dict& globals) {
_fun = TRY(mod.fun());
_pc = 0;
_base = 0;
_code = TRY(_fun.code());
_constants = TRY(_fun.constants());
_closure = TRY(_fun.closure());
_globals = TRY(mod.globals());
_globals = TRY(globals.copy());
while (true) {
auto rc = step();
@ -331,3 +343,7 @@ Result<Value> VM::run(const Module& mod) {
}
return ERROR(NotImplemented);
}
Result<Value> VM::run(const Module& mod) {
return run(mod, TRY(Dict::create()));
}

View file

@ -18,6 +18,7 @@ class VM {
}
Result<Value> run(const Module& mod);
Result<Value> run(const Module& mod, const Dict& globals);
Result<void> step();
Result<void> vm_mov(Opcode& oc);
@ -40,12 +41,17 @@ class VM {
Result<void> vm_closure_load(Opcode& oc);
Result<void> vm_global_load(Opcode& oc);
Result<void> vm_global_store(Opcode& oc);
Result<Value> get(bool is_const, uint64_t idx);
Result<Value> getconst(uint64_t idx);
Result<Value> getreg(uint64_t idx);
Result<void> setreg(uint64_t idx, const Value& value);
Result<Dict> globals() {
return _globals.copy();
}
private:
Stack _stack;
Stack _callstack;