mirror of
https://git.sfja.dk/Mikkel/slige.git
synced 2025-01-18 12:46:31 +00:00
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
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<Value> stack;
|
||||
std::vector<Value> statics;
|
||||
heap::Heap heap;
|
||||
SourcePos current_pos = { 0, 1, 1 };
|
||||
int64_t instruction_counter = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user