.
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
#include "../bytecode/bytecode.hh"
|
#include "../bytecode/bytecode.hh"
|
||||||
#include "code.hh"
|
#include "code.hh"
|
||||||
#include "stack.hh"
|
#include "stack.hh"
|
||||||
|
#include "vm.hh"
|
||||||
|
|
||||||
using namespace tyche;
|
using namespace tyche;
|
||||||
|
|
||||||
@@ -68,6 +69,27 @@ TEST(Stack, FramePointer)
|
|||||||
ASSERT_EQ(stack.at(-2).as_integer(), 10);
|
ASSERT_EQ(stack.at(-2).as_integer(), 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(VM, BasicCode)
|
||||||
|
{
|
||||||
|
// code (2+3)
|
||||||
|
BytecodePrototype bp;
|
||||||
|
bp.functions.emplace_back(0, 0);
|
||||||
|
bp.functions.at(0).code.append_byte((uint8_t) Instruction::PushInt8);
|
||||||
|
bp.functions.at(0).code.append_int8(2);
|
||||||
|
bp.functions.at(0).code.append_byte((uint8_t) Instruction::PushInt8);
|
||||||
|
bp.functions.at(0).code.append_int8(3);
|
||||||
|
bp.functions.at(0).code.append_byte((uint8_t) Instruction::Sum);
|
||||||
|
bp.functions.at(0).code.append_byte((uint8_t) Instruction::Return);
|
||||||
|
ByteArray ba = Bytecode::generate(bp);
|
||||||
|
|
||||||
|
VM vm;
|
||||||
|
vm.load_bytecode(std::move(ba));
|
||||||
|
vm.call(0);
|
||||||
|
|
||||||
|
int32_t result = vm.to_integer(-1);
|
||||||
|
ASSERT_EQ(result, 5);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
testing::InitGoogleTest(&argc, argv);
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
|||||||
26
src/vm/vm.cc
26
src/vm/vm.cc
@@ -25,6 +25,18 @@ void VM::call(size_t n_params)
|
|||||||
loc_.pop();
|
loc_.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t VM::to_integer(int index) const
|
||||||
|
{
|
||||||
|
Value i = stack_.at(index);
|
||||||
|
assert_type(i, Type::Integer);
|
||||||
|
return i.as_integer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VM::push_integer(int32_t value)
|
||||||
|
{
|
||||||
|
stack_.push(Value::CreateInteger(value));
|
||||||
|
}
|
||||||
|
|
||||||
void VM::run_until_return()
|
void VM::run_until_return()
|
||||||
{
|
{
|
||||||
size_t level = stack_.fp_level();
|
size_t level = stack_.fp_level();
|
||||||
@@ -37,9 +49,21 @@ void VM::step()
|
|||||||
{
|
{
|
||||||
Operation op = code_.operation(loc_.top());
|
Operation op = code_.operation(loc_.top());
|
||||||
switch (op.instruction) {
|
switch (op.instruction) {
|
||||||
// TODO
|
case Instruction::PushInt8:
|
||||||
|
case Instruction::PushInt16:
|
||||||
|
case Instruction::PushInt32:
|
||||||
|
push_integer(op.operator_);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw VMInvalidOpcode((uint8_t) op.instruction);
|
||||||
}
|
}
|
||||||
loc_.top() = op.next_location;
|
loc_.top() = op.next_location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VM::assert_type(Value const& val, Type type)
|
||||||
|
{
|
||||||
|
if (val.type() != type)
|
||||||
|
throw VMTypeError(type, val.type());
|
||||||
|
}
|
||||||
|
|
||||||
} // tyche
|
} // tyche
|
||||||
|
|||||||
@@ -13,10 +13,16 @@ public:
|
|||||||
|
|
||||||
void call(size_t n_params);
|
void call(size_t n_params);
|
||||||
|
|
||||||
|
[[nodiscard]] int32_t to_integer(int index) const;
|
||||||
|
|
||||||
|
void push_integer(int32_t value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void run_until_return();
|
void run_until_return();
|
||||||
void step();
|
void step();
|
||||||
|
|
||||||
|
static void assert_type(Value const& val, Type type);
|
||||||
|
|
||||||
Stack stack_;
|
Stack stack_;
|
||||||
Code code_;
|
Code code_;
|
||||||
std::stack<Location> loc_;
|
std::stack<Location> loc_;
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ public:
|
|||||||
explicit VMTypeError(Type expected, Type found) : VMRuntimeError("Type error") {} // TODO - print types
|
explicit VMTypeError(Type expected, Type found) : VMRuntimeError("Type error") {} // TODO - print types
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class VMInvalidOpcode : public VMRuntimeError
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit VMInvalidOpcode(uint8_t opcode) : VMRuntimeError("Invalid opcode " + std::to_string(opcode)) {}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user