From 7d160da5d0df13dcc84c6de24a64f7cba0aa0558 Mon Sep 17 00:00:00 2001 From: Konstantin Nazarov Date: Sun, 1 Sep 2024 14:31:25 +0100 Subject: [PATCH] Implement access to previously defined functions in REPL --- src/arena.cpp | 1 - src/common.cpp | 13 +------------ src/common.hpp | 4 +--- src/compiler.cpp | 32 ++++++++++++-------------------- src/opcode.cpp | 2 ++ src/opcode.hpp | 1 + src/pod.hpp | 1 - src/vli.cpp | 10 +++++++++- src/vm.cpp | 20 ++++++++++++++++++-- src/vm.hpp | 6 ++++++ 10 files changed, 50 insertions(+), 40 deletions(-) diff --git a/src/arena.cpp b/src/arena.cpp index 838c8d0..2834774 100644 --- a/src/arena.cpp +++ b/src/arena.cpp @@ -224,7 +224,6 @@ Result Arena::gc_module(PodModule* obj) { auto nobj = TRY(alloc()); 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; diff --git a/src/common.cpp b/src/common.cpp index 3883360..d930da0 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -195,11 +195,6 @@ Result 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::create(const Value& name, const Function& fun, - const Dict& globals) { +Result Module::create(const Value& name, const Function& fun) { auto pod = TRY(arena_alloc()); 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 Module::fun() const { return Function::create((PodFunction*)_value->fun.get()); } -Result Module::globals() const { - return Dict::create((PodDict*)_value->globals.get()); -} - Result reverse(Value& val) { if (val.is()) return Value(TRY(Nil::create())); if (!val.is()) return ERROR(TypeMismatch); diff --git a/src/common.hpp b/src/common.hpp index d0a832b..c68059c 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -994,12 +994,10 @@ class Module : public Object { return Module(TRY(MkGcRoot(obj))); } - static Result create(const Value& name, const Function& fun, - const Dict& globals); + static Result create(const Value& name, const Function& fun); Result name() const; Result fun() const; - Result globals() const; virtual Result copy_value() const final; Result copy() const; diff --git a/src/compiler.cpp b/src/compiler.cpp index 2dc8613..4cacedf 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -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 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 add_global(const Value& name, const Value& value) { - globals_dict = TRY(globals_dict.insert(name, value)); - return Result(); - } - 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 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 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 Compiler::compile_fn(Context& context, Symbol& op, Expression ex_res = TRY(Expression::create()); if (ctx.closures.size() == 0) { - if (context.toplevel && !name.is()) { - context.add_global(name, TRY(fun.copy())); - } - int64_t c = TRY(context.add_const(TRY(fun.copy()))); + if (context.toplevel && !name.is()) { + 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})); diff --git a/src/opcode.cpp b/src/opcode.cpp index bf1edaa..2528c4e 100644 --- a/src/opcode.cpp +++ b/src/opcode.cpp @@ -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: diff --git a/src/opcode.hpp b/src/opcode.hpp index 2d77274..9a45255 100644 --- a/src/opcode.hpp +++ b/src/opcode.hpp @@ -61,6 +61,7 @@ enum class Oc : uint8_t { SetJump, // Globals GlobalLoad, + GlobalStore, // Closures MakeClosure, ClosureLoad, diff --git a/src/pod.hpp b/src/pod.hpp index ce4caa8..3773a62 100644 --- a/src/pod.hpp +++ b/src/pod.hpp @@ -183,7 +183,6 @@ class PodModule final : public PodObject { OffPtr name; OffPtr fun; - OffPtr globals; }; class PodStack final : public PodObject { diff --git a/src/vli.cpp b/src/vli.cpp index b79b2c7..d7ee81d 100644 --- a/src/vli.cpp +++ b/src/vli.cpp @@ -28,9 +28,17 @@ Result run_string(const String& src) { } Result 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(); + auto vm = TRY(VM::create()); + auto res = TRY(vm.run(mod, globals)); + globals = TRY(vm.globals()); + if (!res.is()) { debug_print(res); } diff --git a/src/vm.cpp b/src/vm.cpp index 3342e07..a718173 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -249,6 +249,15 @@ Result VM::vm_global_load(Opcode& oc) { return Result(); } +Result 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(); +} + Result VM::step() { auto opcode = TRY(_code.get(_pc)); if (!opcode.is()) return ERROR(TypeMismatch); @@ -302,6 +311,9 @@ Result 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 VM::step() { // Result Int64::copy() const { return Value(Int64(TRY(_value.copy()))); // } -Result VM::run(const Module& mod) { +Result 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 VM::run(const Module& mod) { } return ERROR(NotImplemented); } + +Result VM::run(const Module& mod) { + return run(mod, TRY(Dict::create())); +} diff --git a/src/vm.hpp b/src/vm.hpp index a65922e..9be2906 100644 --- a/src/vm.hpp +++ b/src/vm.hpp @@ -18,6 +18,7 @@ class VM { } Result run(const Module& mod); + Result run(const Module& mod, const Dict& globals); Result step(); Result vm_mov(Opcode& oc); @@ -40,12 +41,17 @@ class VM { Result vm_closure_load(Opcode& oc); Result vm_global_load(Opcode& oc); + Result vm_global_store(Opcode& oc); Result get(bool is_const, uint64_t idx); Result getconst(uint64_t idx); Result getreg(uint64_t idx); Result setreg(uint64_t idx, const Value& value); + Result globals() { + return _globals.copy(); + } + private: Stack _stack; Stack _callstack;