#pragma once #include "common.hpp" class VM { public: VM() {} VM(StackFrame&& stack, Function&& fun, Array&& code, Array&& constants, Array&& closure, Dict&& globals, Value&& res) : _stack(std::move(stack)), _fun(std::move(fun)), _code(std::move(code)), _constants(std::move(constants)), _closure(std::move(closure)), _globals(std::move(globals)), _res(std::move(res)) {} VM(VM&& vm) : _stack(std::move(vm._stack)), _fun(std::move(vm._fun)), _code(std::move(vm._code)), _constants(std::move(vm._constants)), _closure(std::move(vm._closure)), _globals(std::move(vm._globals)), _res(std::move(vm._res)) {} VM(const VM&) = delete; static Result create(const Module& mod, const Dict& globals) { auto fun = TRY(mod.fun()); auto nil = Value(TRY(Nil::create())); auto stack = TRY(StackFrame::create(nil, fun)); auto code = TRY(fun.code()); auto constants = TRY(fun.constants()); auto closure = TRY(fun.closure()); auto globals_copy = TRY(globals.copy()); return VM(std::move(stack), std::move(fun), std::move(code), std::move(constants), std::move(closure), std::move(globals_copy), std::move(nil)); } Result run(); Result step(); Result vm_mov(Opcode& oc); Result vm_add(Opcode& oc); Result vm_mul(Opcode& oc); Result vm_sub(Opcode& oc); Result vm_div(Opcode& oc); Result vm_call(Opcode& oc); Result vm_selfcall(Opcode& oc); Result vm_call_lisp(Opcode& oc, Function& fun); Result vm_call_stdlib(Opcode& oc, StdlibFunction& fun); Result vm_ret(Opcode& oc); Result vm_equal(Opcode& oc); Result vm_less(Opcode& oc); Result vm_less_equal(Opcode& oc); Result vm_jump(Opcode& oc); Result vm_make_closure(Opcode& oc); 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: StackFrame _stack; Function _fun; Array _code; Array _constants; Array _closure; Dict _globals; Value _res; };