add builtins and statics to vm
This commit is contained in:
parent
916c2376a0
commit
4be4e50b7d
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user