Implement access to previously defined functions in REPL
This commit is contained in:
parent
5279b44441
commit
7d160da5d0
10 changed files with 50 additions and 40 deletions
|
@ -224,7 +224,6 @@ Result<PodObject*> Arena::gc_module(PodModule* obj) {
|
||||||
auto nobj = TRY(alloc<PodModule>());
|
auto nobj = TRY(alloc<PodModule>());
|
||||||
nobj->header.tag = Tag::Module;
|
nobj->header.tag = Tag::Module;
|
||||||
nobj->name = TRY(gc_pod(obj->name.get()));
|
nobj->name = TRY(gc_pod(obj->name.get()));
|
||||||
nobj->globals = TRY(gc_pod(obj->globals.get()));
|
|
||||||
nobj->fun = TRY(gc_pod(obj->fun.get()));
|
nobj->fun = TRY(gc_pod(obj->fun.get()));
|
||||||
|
|
||||||
return nobj;
|
return nobj;
|
||||||
|
|
|
@ -195,11 +195,6 @@ Result<short> Module::cmp(const Module& rhs) const {
|
||||||
auto lhs_fun = TRY(fun());
|
auto lhs_fun = TRY(fun());
|
||||||
auto rhs_fun = TRY(rhs.fun());
|
auto rhs_fun = TRY(rhs.fun());
|
||||||
res = TRY(lhs_fun.cmp(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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,13 +342,11 @@ StdlibFunctionId StdlibFunction::fun_id() const {
|
||||||
return StdlibFunctionId(_value->fun_id);
|
return StdlibFunctionId(_value->fun_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<Module> Module::create(const Value& name, const Function& fun,
|
Result<Module> Module::create(const Value& name, const Function& fun) {
|
||||||
const Dict& globals) {
|
|
||||||
auto pod = TRY(arena_alloc<PodModule>());
|
auto pod = TRY(arena_alloc<PodModule>());
|
||||||
pod->header.tag = Tag::Module;
|
pod->header.tag = Tag::Module;
|
||||||
pod->name = name.pod();
|
pod->name = name.pod();
|
||||||
pod->fun = fun.pod();
|
pod->fun = fun.pod();
|
||||||
pod->globals = globals.pod();
|
|
||||||
|
|
||||||
return Module(TRY(MkGcRoot(pod)));
|
return Module(TRY(MkGcRoot(pod)));
|
||||||
}
|
}
|
||||||
|
@ -364,10 +357,6 @@ Result<Function> Module::fun() const {
|
||||||
return Function::create((PodFunction*)_value->fun.get());
|
return Function::create((PodFunction*)_value->fun.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<Dict> Module::globals() const {
|
|
||||||
return Dict::create((PodDict*)_value->globals.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
Result<Value> reverse(Value& val) {
|
Result<Value> reverse(Value& val) {
|
||||||
if (val.is<Nil>()) return Value(TRY(Nil::create()));
|
if (val.is<Nil>()) return Value(TRY(Nil::create()));
|
||||||
if (!val.is<Pair>()) return ERROR(TypeMismatch);
|
if (!val.is<Pair>()) return ERROR(TypeMismatch);
|
||||||
|
|
|
@ -994,12 +994,10 @@ class Module : public Object {
|
||||||
return Module(TRY(MkGcRoot(obj)));
|
return Module(TRY(MkGcRoot(obj)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result<Module> create(const Value& name, const Function& fun,
|
static Result<Module> create(const Value& name, const Function& fun);
|
||||||
const Dict& globals);
|
|
||||||
|
|
||||||
Result<Value> name() const;
|
Result<Value> name() const;
|
||||||
Result<Function> fun() const;
|
Result<Function> fun() const;
|
||||||
Result<Dict> globals() const;
|
|
||||||
|
|
||||||
virtual Result<Value> copy_value() const final;
|
virtual Result<Value> copy_value() const final;
|
||||||
Result<Module> copy() const;
|
Result<Module> copy() const;
|
||||||
|
|
|
@ -8,14 +8,13 @@ struct Context {
|
||||||
|
|
||||||
Context(Value&& fname, Array&& constants, Dict&& constants_dict,
|
Context(Value&& fname, Array&& constants, Dict&& constants_dict,
|
||||||
Dict&& variables_dict, Array&& closures, Dict&& closures_dict,
|
Dict&& variables_dict, Array&& closures, Dict&& closures_dict,
|
||||||
Dict&& globals_dict, Context* parent, bool toplevel)
|
Context* parent, bool toplevel)
|
||||||
: fname(std::move(fname)),
|
: fname(std::move(fname)),
|
||||||
constants(std::move(constants)),
|
constants(std::move(constants)),
|
||||||
constants_dict(std::move(constants_dict)),
|
constants_dict(std::move(constants_dict)),
|
||||||
variables_dict(std::move(variables_dict)),
|
variables_dict(std::move(variables_dict)),
|
||||||
closures(std::move(closures)),
|
closures(std::move(closures)),
|
||||||
closures_dict(std::move(closures_dict)),
|
closures_dict(std::move(closures_dict)),
|
||||||
globals_dict(std::move(globals_dict)),
|
|
||||||
maxreg(0),
|
maxreg(0),
|
||||||
parent(parent),
|
parent(parent),
|
||||||
toplevel(toplevel) {}
|
toplevel(toplevel) {}
|
||||||
|
@ -27,12 +26,10 @@ struct Context {
|
||||||
auto variables_dict = TRY(Dict::create());
|
auto variables_dict = TRY(Dict::create());
|
||||||
auto closures = TRY(Array::create());
|
auto closures = TRY(Array::create());
|
||||||
auto closures_dict = TRY(Dict::create());
|
auto closures_dict = TRY(Dict::create());
|
||||||
auto globals_dict = TRY(Dict::create());
|
|
||||||
|
|
||||||
return Context(std::move(fname), std::move(constants),
|
return Context(std::move(fname), std::move(constants),
|
||||||
std::move(constants_dict), std::move(variables_dict),
|
std::move(constants_dict), std::move(variables_dict),
|
||||||
std::move(closures), std::move(closures_dict),
|
std::move(closures), std::move(closures_dict), 0, true);
|
||||||
std::move(globals_dict), 0, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result<Context> create(Context& parent) {
|
static Result<Context> create(Context& parent) {
|
||||||
|
@ -42,12 +39,11 @@ struct Context {
|
||||||
auto variables_dict = TRY(Dict::create());
|
auto variables_dict = TRY(Dict::create());
|
||||||
auto closures = TRY(Array::create());
|
auto closures = TRY(Array::create());
|
||||||
auto closures_dict = TRY(Dict::create());
|
auto closures_dict = TRY(Dict::create());
|
||||||
auto globals_dict = TRY(Dict::create());
|
|
||||||
|
|
||||||
return Context(std::move(fname), std::move(constants),
|
return Context(std::move(fname), std::move(constants),
|
||||||
std::move(constants_dict), std::move(variables_dict),
|
std::move(constants_dict), std::move(variables_dict),
|
||||||
std::move(closures), std::move(closures_dict),
|
std::move(closures), std::move(closures_dict), &parent,
|
||||||
std::move(globals_dict), &parent, false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t alloc_reg() {
|
uint64_t alloc_reg() {
|
||||||
|
@ -143,18 +139,12 @@ struct Context {
|
||||||
return i;
|
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;
|
Value fname;
|
||||||
Array constants;
|
Array constants;
|
||||||
Dict constants_dict;
|
Dict constants_dict;
|
||||||
Dict variables_dict;
|
Dict variables_dict;
|
||||||
Array closures;
|
Array closures;
|
||||||
Dict closures_dict;
|
Dict closures_dict;
|
||||||
Dict globals_dict;
|
|
||||||
uint64_t maxreg;
|
uint64_t maxreg;
|
||||||
Context* parent;
|
Context* parent;
|
||||||
bool toplevel;
|
bool toplevel;
|
||||||
|
@ -196,7 +186,7 @@ Result<Value> Compiler::compile(Value& expr) {
|
||||||
auto fun = TRY(Function::create(name, 0, context.constants, ex.code,
|
auto fun = TRY(Function::create(name, 0, context.constants, ex.code,
|
||||||
TRY(Array::create())));
|
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));
|
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,
|
auto fun = TRY(Function::create(name, 0, context.constants, ex.code,
|
||||||
TRY(Array::create())));
|
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));
|
return Value(std::move(mod));
|
||||||
}
|
}
|
||||||
|
@ -634,12 +624,14 @@ Result<Expression> Compiler::compile_fn(Context& context, Symbol& op,
|
||||||
Expression ex_res = TRY(Expression::create());
|
Expression ex_res = TRY(Expression::create());
|
||||||
|
|
||||||
if (ctx.closures.size() == 0) {
|
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())));
|
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();
|
uint64_t reg = context.alloc_reg();
|
||||||
TRY(ex_res.add_opcode(Oc::Mov, {0, (int64_t)reg}, {1, (int64_t)c}));
|
TRY(ex_res.add_opcode(Oc::Mov, {0, (int64_t)reg}, {1, (int64_t)c}));
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,8 @@ op_t get_op(Oc op) {
|
||||||
return op_t{"setglobal", OpcodeType::Reg2};
|
return op_t{"setglobal", OpcodeType::Reg2};
|
||||||
case Oc::GlobalLoad:
|
case Oc::GlobalLoad:
|
||||||
return op_t{"global-load", OpcodeType::Reg2};
|
return op_t{"global-load", OpcodeType::Reg2};
|
||||||
|
case Oc::GlobalStore:
|
||||||
|
return op_t{"global-store", OpcodeType::Reg2};
|
||||||
case Oc::MakeClosure:
|
case Oc::MakeClosure:
|
||||||
return op_t{"make-closure", OpcodeType::Reg2};
|
return op_t{"make-closure", OpcodeType::Reg2};
|
||||||
case Oc::ClosureLoad:
|
case Oc::ClosureLoad:
|
||||||
|
|
|
@ -61,6 +61,7 @@ enum class Oc : uint8_t {
|
||||||
SetJump,
|
SetJump,
|
||||||
// Globals
|
// Globals
|
||||||
GlobalLoad,
|
GlobalLoad,
|
||||||
|
GlobalStore,
|
||||||
// Closures
|
// Closures
|
||||||
MakeClosure,
|
MakeClosure,
|
||||||
ClosureLoad,
|
ClosureLoad,
|
||||||
|
|
|
@ -183,7 +183,6 @@ class PodModule final : public PodObject {
|
||||||
|
|
||||||
OffPtr<PodObject> name;
|
OffPtr<PodObject> name;
|
||||||
OffPtr<PodObject> fun;
|
OffPtr<PodObject> fun;
|
||||||
OffPtr<PodObject> globals;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PodStack final : public PodObject {
|
class PodStack final : public PodObject {
|
||||||
|
|
10
src/vli.cpp
10
src/vli.cpp
|
@ -28,9 +28,17 @@ Result<Value> run_string(const String& src) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<void> run_repl() {
|
Result<void> run_repl() {
|
||||||
|
Dict globals = TRY(Dict::create());
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
auto src = TRY(read_line("vli> "));
|
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>()) {
|
if (!res.is<Nil>()) {
|
||||||
debug_print(res);
|
debug_print(res);
|
||||||
}
|
}
|
||||||
|
|
20
src/vm.cpp
20
src/vm.cpp
|
@ -249,6 +249,15 @@ Result<void> VM::vm_global_load(Opcode& oc) {
|
||||||
return Result<void>();
|
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() {
|
Result<void> VM::step() {
|
||||||
auto opcode = TRY(_code.get(_pc));
|
auto opcode = TRY(_code.get(_pc));
|
||||||
if (!opcode.is<Opcode>()) return ERROR(TypeMismatch);
|
if (!opcode.is<Opcode>()) return ERROR(TypeMismatch);
|
||||||
|
@ -302,6 +311,9 @@ Result<void> VM::step() {
|
||||||
case Oc::GlobalLoad:
|
case Oc::GlobalLoad:
|
||||||
TRY(vm_global_load(oc));
|
TRY(vm_global_load(oc));
|
||||||
break;
|
break;
|
||||||
|
case Oc::GlobalStore:
|
||||||
|
TRY(vm_global_store(oc));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return ERROR(NotImplemented);
|
return ERROR(NotImplemented);
|
||||||
}
|
}
|
||||||
|
@ -311,14 +323,14 @@ Result<void> VM::step() {
|
||||||
|
|
||||||
// Result<Value> Int64::copy() const { return Value(Int64(TRY(_value.copy())));
|
// 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());
|
_fun = TRY(mod.fun());
|
||||||
_pc = 0;
|
_pc = 0;
|
||||||
_base = 0;
|
_base = 0;
|
||||||
_code = TRY(_fun.code());
|
_code = TRY(_fun.code());
|
||||||
_constants = TRY(_fun.constants());
|
_constants = TRY(_fun.constants());
|
||||||
_closure = TRY(_fun.closure());
|
_closure = TRY(_fun.closure());
|
||||||
_globals = TRY(mod.globals());
|
_globals = TRY(globals.copy());
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
auto rc = step();
|
auto rc = step();
|
||||||
|
@ -331,3 +343,7 @@ Result<Value> VM::run(const Module& mod) {
|
||||||
}
|
}
|
||||||
return ERROR(NotImplemented);
|
return ERROR(NotImplemented);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<Value> VM::run(const Module& mod) {
|
||||||
|
return run(mod, TRY(Dict::create()));
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ class VM {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<Value> run(const Module& mod);
|
Result<Value> run(const Module& mod);
|
||||||
|
Result<Value> run(const Module& mod, const Dict& globals);
|
||||||
|
|
||||||
Result<void> step();
|
Result<void> step();
|
||||||
Result<void> vm_mov(Opcode& oc);
|
Result<void> vm_mov(Opcode& oc);
|
||||||
|
@ -40,12 +41,17 @@ class VM {
|
||||||
Result<void> vm_closure_load(Opcode& oc);
|
Result<void> vm_closure_load(Opcode& oc);
|
||||||
|
|
||||||
Result<void> vm_global_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> get(bool is_const, uint64_t idx);
|
||||||
Result<Value> getconst(uint64_t idx);
|
Result<Value> getconst(uint64_t idx);
|
||||||
Result<Value> getreg(uint64_t idx);
|
Result<Value> getreg(uint64_t idx);
|
||||||
Result<void> setreg(uint64_t idx, const Value& value);
|
Result<void> setreg(uint64_t idx, const Value& value);
|
||||||
|
|
||||||
|
Result<Dict> globals() {
|
||||||
|
return _globals.copy();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Stack _stack;
|
Stack _stack;
|
||||||
Stack _callstack;
|
Stack _callstack;
|
||||||
|
|
Loading…
Reference in a new issue