123 lines
3.0 KiB
C++
123 lines
3.0 KiB
C++
#include "gtest/gtest.h"
|
|
|
|
#include "../bytecode/bytecodeprototype.hh"
|
|
#include "../common/bytearray.hh"
|
|
#include "../bytecode/bytecode.hh"
|
|
#include "../assembler/assembler.hh"
|
|
#include "code.hh"
|
|
#include "stack.hh"
|
|
#include "vm.hh"
|
|
|
|
using namespace tyche;
|
|
using namespace tyche::bc;
|
|
using namespace tyche::vm;
|
|
|
|
TEST(Code, ImportSingleAndDebug)
|
|
{
|
|
BytecodePrototype bp;
|
|
|
|
bp.constants.emplace_back(3.14f);
|
|
bp.constants.emplace_back("HELLO");
|
|
|
|
bp.functions.emplace_back(0, 0);
|
|
bp.functions.at(0).code.append_byte(0xa0); // pushi
|
|
bp.functions.at(0).code.append_int8(42);
|
|
|
|
bp.functions.emplace_back(2, 1);
|
|
bp.functions.at(1).code.append_byte(0x1a); // appnd
|
|
|
|
ByteArray ba = Bytecode::generate(bp);
|
|
|
|
Code code;
|
|
code.import_bytecode(std::move(ba));
|
|
printf("%s\n", code.disassemble().c_str());
|
|
}
|
|
|
|
TEST(Stack, PushPullGet)
|
|
{
|
|
Stack stack;
|
|
stack.push(Value::CreateInteger(10));
|
|
stack.push(Value::CreateInteger(20));
|
|
stack.push(Value::CreateInteger(30));
|
|
|
|
ASSERT_EQ(stack.size(), 3);
|
|
ASSERT_EQ(stack.at(0).as_integer(), 10);
|
|
ASSERT_EQ(stack.at(1).as_integer(), 20);
|
|
ASSERT_EQ(stack.at(-1).as_integer(), 30);
|
|
ASSERT_EQ(stack.at(-2).as_integer(), 20);
|
|
}
|
|
|
|
TEST(Stack, FramePointer)
|
|
{
|
|
Stack stack;
|
|
stack.push(Value::CreateInteger(10));
|
|
stack.push(Value::CreateInteger(20));
|
|
stack.push_fp();
|
|
stack.push(Value::CreateInteger(30));
|
|
stack.push(Value::CreateInteger(40));
|
|
stack.push(Value::CreateInteger(50));
|
|
|
|
ASSERT_EQ(stack.size(), 3);
|
|
ASSERT_EQ(stack.at(0).as_integer(), 30);
|
|
ASSERT_EQ(stack.at(1).as_integer(), 40);
|
|
ASSERT_EQ(stack.at(-1).as_integer(), 50);
|
|
ASSERT_EQ(stack.at(-2).as_integer(), 40);
|
|
|
|
stack.pop_fp();
|
|
|
|
ASSERT_EQ(stack.size(), 2);
|
|
ASSERT_EQ(stack.at(0).as_integer(), 10);
|
|
ASSERT_EQ(stack.at(1).as_integer(), 20);
|
|
ASSERT_EQ(stack.at(-1).as_integer(), 20);
|
|
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);
|
|
}
|
|
|
|
TEST(VM, SumIntegers)
|
|
{
|
|
ASSERT_EQ(VM().load_bytecode(as::Assembler(R"(
|
|
.func 0
|
|
pushi 2
|
|
pushi 3
|
|
sum
|
|
ret
|
|
)").assemble()).call(0).to_integer(-1), 5);
|
|
}
|
|
|
|
TEST(VM, SubtractIntegers)
|
|
{
|
|
ASSERT_EQ(VM().load_bytecode(as::Assembler(R"(
|
|
.func 0
|
|
pushi 2
|
|
pushi 3
|
|
sub
|
|
ret
|
|
)").assemble()).call(0).to_integer(-1), -1);
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
}
|