diff --git a/runtime/arch.hpp b/runtime/arch.hpp index 5443a62..33291b4 100644 --- a/runtime/arch.hpp +++ b/runtime/arch.hpp @@ -7,31 +7,42 @@ namespace sliger { // NOTICE: keep up to date with src/arch.ts enum class Op : uint32_t { - Nop = 0, - PushNull = 1, - PushInt = 2, - PushBool = 3, - PushString = 4, - PushPtr = 5, - Pop = 6, - LoadLocal = 7, - StoreLocal = 8, - Call = 9, - Return = 10, - Jump = 11, - JumpIfFalse = 12, - Add = 13, - Subtract = 14, - Multiply = 15, - Divide = 16, - Remainder = 17, - Equal = 18, - LessThan = 19, - And = 20, - Or = 21, - Xor = 22, - Not = 23, - SourceMap = 24, + Nop = 0x00, + PushNull = 0x01, + PushInt = 0x02, + PushBool = 0x03, + PushString = 0x04, + PushPtr = 0x05, + Pop = 0x06, + ReserveStatic = 0x07, + LoadStatic = 0x08, + StoreStatic = 0x09, + LoadLocal = 0x0a, + StoreLocal = 0x0b, + Call = 0x0c, + Return = 0x0d, + Jump = 0x0e, + JumpIfTrue = 0x0f, + Builtin = 0x10, + Add = 0x20, + Subtract = 0x21, + Multiply = 0x22, + Divide = 0x23, + Remainder = 0x24, + Equal = 0x25, + LessThan = 0x26, + And = 0x27, + Or = 0x28, + Xor = 0x29, + Not = 0x2a, + SourceMap = 0x30, +}; + +enum class Builtin : uint32_t { + StringConcat = 0x10, + StringEqual = 0x11, + ArraySet = 0x20, + StructSet = 0x30, }; } diff --git a/runtime/vm.cpp b/runtime/vm.cpp index d24c279..6d903dc 100644 --- a/runtime/vm.cpp +++ b/runtime/vm.cpp @@ -37,8 +37,8 @@ inline auto maybe_op_to_string(uint32_t value) -> std::string return "Return"; case Op::Jump: return "Jump"; - case Op::JumpIfFalse: - return "JumpIfFalse"; + case Op::JumpIfTrue: + return "JumpIfTrue"; case Op::Add: return "Add"; case Op::Subtract: @@ -87,8 +87,8 @@ void VM::run_n_instructions(size_t amount) void VM::run_instruction() { - std::cout << std::format(" {:>4}: {:<12}{}\n", this->pc, - maybe_op_to_string(this->program[this->pc]), stack_repr_string(4)); + /*std::cout << std::format(" {:>4}: {:<12}{}\n", this->pc,*/ + /* maybe_op_to_string(this->program[this->pc]), stack_repr_string(4));*/ auto op = eat_op(); switch (op) { case Op::Nop: @@ -132,7 +132,28 @@ void VM::run_instruction() this->stack.pop_back(); break; } + case Op::ReserveStatic: { + assert_program_has(1); + auto value = eat_uint32(); + this->statics.reserve(value); + break; + } + case Op::LoadStatic: { + assert_program_has(1); + auto loc = eat_uint32(); + auto value = this->statics.at(loc); + stack_push(value); + break; + } + case Op::StoreStatic: { + assert_program_has(1); + auto loc = eat_uint32(); + auto value = stack_pop(); + this->statics.at(loc) = value; + break; + } case Op::LoadLocal: { + assert_program_has(1); auto loc = eat_uint32(); assert_fn_stack_has(loc); auto value = fn_stack_at(loc); @@ -140,6 +161,7 @@ void VM::run_instruction() break; } case Op::StoreLocal: { + assert_program_has(1); auto loc = eat_uint32(); assert_fn_stack_has(loc + 1); auto value = stack_pop(); @@ -187,15 +209,21 @@ void VM::run_instruction() this->pc = addr.as_ptr().value; break; } - case Op::JumpIfFalse: { + case Op::JumpIfTrue: { assert_stack_has(2); auto addr = stack_pop(); auto cond = stack_pop(); - if (!cond.as_bool().value) { + if (cond.as_bool().value) { this->pc = addr.as_ptr().value; } break; } + case Op::Builtin: { + assert_program_has(1); + auto builtin_id = eat_uint32(); + run_builtin(static_cast(builtin_id)); + break; + } case Op::Add: { assert_stack_has(2); auto right = stack_pop().as_int().value; @@ -296,3 +324,36 @@ void VM::run_instruction() } this->instruction_counter += 1; } + +void VM::run_builtin(Builtin builtin_id) +{ + switch (builtin_id) { + case Builtin::StringConcat: { + assert_stack_has(2); + auto right = stack_pop(); + auto left = stack_pop(); + stack_push( + String(right.as_string().value + left.as_string().value)); + break; + } + case Builtin::StringEqual: { + assert_stack_has(2); + auto right = stack_pop(); + auto left = stack_pop(); + stack_push(Bool(right.as_string().value == left.as_string().value)); + break; + } + case Builtin::ArraySet: { + assert_stack_has(2); + std::cerr << std::format("not implemented\n"); + std::exit(1); + break; + } + case Builtin::StructSet: { + assert_stack_has(2); + std::cerr << std::format("not implemented\n"); + std::exit(1); + break; + } + } +} diff --git a/runtime/vm.hpp b/runtime/vm.hpp index 0ade960..c05d4fa 100644 --- a/runtime/vm.hpp +++ b/runtime/vm.hpp @@ -191,6 +191,8 @@ public: } private: + void run_builtin(Builtin builtin_id); + inline void step() { this->pc += 1; } inline auto eat_op() -> Op @@ -272,6 +274,7 @@ private: const uint32_t* program; size_t program_size; std::vector stack; + std::vector statics; heap::Heap heap; SourcePos current_pos = { 0, 1, 1 }; int64_t instruction_counter = 0;