add builtins and statics to vm

This commit is contained in:
sfja 2024-12-11 00:18:51 +01:00
parent 916c2376a0
commit 4be4e50b7d
3 changed files with 106 additions and 31 deletions

View File

@ -7,31 +7,42 @@ namespace sliger {
// NOTICE: keep up to date with src/arch.ts // NOTICE: keep up to date with src/arch.ts
enum class Op : uint32_t { enum class Op : uint32_t {
Nop = 0, Nop = 0x00,
PushNull = 1, PushNull = 0x01,
PushInt = 2, PushInt = 0x02,
PushBool = 3, PushBool = 0x03,
PushString = 4, PushString = 0x04,
PushPtr = 5, PushPtr = 0x05,
Pop = 6, Pop = 0x06,
LoadLocal = 7, ReserveStatic = 0x07,
StoreLocal = 8, LoadStatic = 0x08,
Call = 9, StoreStatic = 0x09,
Return = 10, LoadLocal = 0x0a,
Jump = 11, StoreLocal = 0x0b,
JumpIfFalse = 12, Call = 0x0c,
Add = 13, Return = 0x0d,
Subtract = 14, Jump = 0x0e,
Multiply = 15, JumpIfTrue = 0x0f,
Divide = 16, Builtin = 0x10,
Remainder = 17, Add = 0x20,
Equal = 18, Subtract = 0x21,
LessThan = 19, Multiply = 0x22,
And = 20, Divide = 0x23,
Or = 21, Remainder = 0x24,
Xor = 22, Equal = 0x25,
Not = 23, LessThan = 0x26,
SourceMap = 24, And = 0x27,
Or = 0x28,
Xor = 0x29,
Not = 0x2a,
SourceMap = 0x30,
};
enum class Builtin : uint32_t {
StringConcat = 0x10,
StringEqual = 0x11,
ArraySet = 0x20,
StructSet = 0x30,
}; };
} }

View File

@ -37,8 +37,8 @@ inline auto maybe_op_to_string(uint32_t value) -> std::string
return "Return"; return "Return";
case Op::Jump: case Op::Jump:
return "Jump"; return "Jump";
case Op::JumpIfFalse: case Op::JumpIfTrue:
return "JumpIfFalse"; return "JumpIfTrue";
case Op::Add: case Op::Add:
return "Add"; return "Add";
case Op::Subtract: case Op::Subtract:
@ -87,8 +87,8 @@ void VM::run_n_instructions(size_t amount)
void VM::run_instruction() void VM::run_instruction()
{ {
std::cout << std::format(" {:>4}: {:<12}{}\n", this->pc, /*std::cout << std::format(" {:>4}: {:<12}{}\n", this->pc,*/
maybe_op_to_string(this->program[this->pc]), stack_repr_string(4)); /* maybe_op_to_string(this->program[this->pc]), stack_repr_string(4));*/
auto op = eat_op(); auto op = eat_op();
switch (op) { switch (op) {
case Op::Nop: case Op::Nop:
@ -132,7 +132,28 @@ void VM::run_instruction()
this->stack.pop_back(); this->stack.pop_back();
break; 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: { case Op::LoadLocal: {
assert_program_has(1);
auto loc = eat_uint32(); auto loc = eat_uint32();
assert_fn_stack_has(loc); assert_fn_stack_has(loc);
auto value = fn_stack_at(loc); auto value = fn_stack_at(loc);
@ -140,6 +161,7 @@ void VM::run_instruction()
break; break;
} }
case Op::StoreLocal: { case Op::StoreLocal: {
assert_program_has(1);
auto loc = eat_uint32(); auto loc = eat_uint32();
assert_fn_stack_has(loc + 1); assert_fn_stack_has(loc + 1);
auto value = stack_pop(); auto value = stack_pop();
@ -187,15 +209,21 @@ void VM::run_instruction()
this->pc = addr.as_ptr().value; this->pc = addr.as_ptr().value;
break; break;
} }
case Op::JumpIfFalse: { case Op::JumpIfTrue: {
assert_stack_has(2); assert_stack_has(2);
auto addr = stack_pop(); auto addr = stack_pop();
auto cond = stack_pop(); auto cond = stack_pop();
if (!cond.as_bool().value) { if (cond.as_bool().value) {
this->pc = addr.as_ptr().value; this->pc = addr.as_ptr().value;
} }
break; break;
} }
case Op::Builtin: {
assert_program_has(1);
auto builtin_id = eat_uint32();
run_builtin(static_cast<Builtin>(builtin_id));
break;
}
case Op::Add: { case Op::Add: {
assert_stack_has(2); assert_stack_has(2);
auto right = stack_pop().as_int().value; auto right = stack_pop().as_int().value;
@ -296,3 +324,36 @@ void VM::run_instruction()
} }
this->instruction_counter += 1; 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;
}
}
}

View File

@ -191,6 +191,8 @@ public:
} }
private: private:
void run_builtin(Builtin builtin_id);
inline void step() { this->pc += 1; } inline void step() { this->pc += 1; }
inline auto eat_op() -> Op inline auto eat_op() -> Op
@ -272,6 +274,7 @@ private:
const uint32_t* program; const uint32_t* program;
size_t program_size; size_t program_size;
std::vector<Value> stack; std::vector<Value> stack;
std::vector<Value> statics;
heap::Heap heap; heap::Heap heap;
SourcePos current_pos = { 0, 1, 1 }; SourcePos current_pos = { 0, 1, 1 };
int64_t instruction_counter = 0; int64_t instruction_counter = 0;