161 lines
4.7 KiB
C++
161 lines
4.7 KiB
C++
#include "gtest/gtest.h"
|
|
#include "gmock/gmock.h"
|
|
|
|
#include <cstring>
|
|
#include <functional>
|
|
|
|
#include "bytearray.hh"
|
|
#include "bytecodeprototype.hh"
|
|
#include "bytecode.hh"
|
|
|
|
using namespace tyche;
|
|
|
|
static void print(std::vector<uint8_t> const& data)
|
|
{
|
|
for (size_t i = 0; i < data.size(); ++i) {
|
|
if (i % 16 == 0)
|
|
printf("%04X : ", i);
|
|
printf("%02X ", data.at(i));
|
|
if (i % 16 == 15)
|
|
printf("\n");
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
TEST(ByteArray, ByteArray)
|
|
{
|
|
auto test = [](std::function<void(ByteArray&)> const& f, std::vector<uint8_t> const& expected) {
|
|
ByteArray ba;
|
|
f(ba);
|
|
ASSERT_EQ(ba.data().size(), expected.size());
|
|
ASSERT_EQ(std::memcmp(ba.data().data(), expected.data(), ba.data().size()), 0);
|
|
};
|
|
|
|
#define TESTX(a, ...) test([](ByteArray& ba) { a; }, std::vector<uint8_t>({ __VA_ARGS__ }));
|
|
|
|
TESTX(ba.set_byte(1, 0xab), 0x00, 0xab)
|
|
|
|
ByteArray ba;
|
|
ba.set_byte(1, 0xab); ASSERT_EQ(ba.get_byte(1), 0xab);
|
|
|
|
ba.set_int(1, 12); ASSERT_EQ(ba.get_int(1), std::make_pair(12, 1));
|
|
ba.set_int(1, -12); ASSERT_EQ(ba.get_int(1), std::make_pair(-12, 1));
|
|
ba.set_int(1, 5000); ASSERT_EQ(ba.get_int(1), std::make_pair(5000, 2));
|
|
ba.set_int(1, 5000300); ASSERT_EQ(ba.get_int(1), std::make_pair(5000300, 4));
|
|
ba.set_int(1, -5000300); ASSERT_EQ(ba.get_int(1), std::make_pair(-5000300, 4));
|
|
|
|
ba.set_float(1, 3.14); ASSERT_FLOAT_EQ(ba.get_float(1).first, 3.14);
|
|
ba.set_float(1, -3.14); ASSERT_FLOAT_EQ(ba.get_float(1).first, -3.14);
|
|
ba.set_float(1, -5000300.1324); ASSERT_FLOAT_EQ(ba.get_float(1).first, -5000300.1324);
|
|
|
|
ba.set_string(1, "Hello world!"); ASSERT_EQ(ba.get_string(1), std::make_pair("Hello world!", 13));
|
|
|
|
#undef TESTX
|
|
}
|
|
|
|
TEST(Bytecode, Constants)
|
|
{
|
|
BytecodePrototype bp;
|
|
bp.constants.emplace_back(42);
|
|
bp.constants.emplace_back("HELLO");
|
|
|
|
std::vector<uint8_t> expected = {
|
|
// header
|
|
0x38, 0xc1, 0xb3, 0x74, // magic
|
|
0x01, 0x00, 0x00, 0x00, // version
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
|
|
// index
|
|
0x40, 0x00, 0x00, 0x00, 0x02, 0x00, // constants
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // functions
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
// constant indexes
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x01, 0x00, 0x00, 0x00,
|
|
|
|
// constant values
|
|
0x54, 'H', 'E', 'L', 'L', 'O', 0x00
|
|
};
|
|
|
|
ByteArray ba = Bytecode::generate(bp);
|
|
ASSERT_EQ(ba.data(), expected);
|
|
}
|
|
|
|
TEST(Bytecode, Code)
|
|
{
|
|
BytecodePrototype bp;
|
|
auto& f = bp.functions.emplace_back(0, 0);
|
|
f.code.append_byte(0x68);
|
|
f.code.append_int(42);
|
|
|
|
auto& f2 = bp.functions.emplace_back(2, 1);
|
|
f2.code.append_byte(0x42);
|
|
|
|
std::vector<uint8_t> expected = {
|
|
// header
|
|
0x38, 0xc1, 0xb3, 0x74, // magic
|
|
0x01, 0x00, 0x00, 0x00, // version
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00,
|
|
|
|
// index
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // constants
|
|
0x40, 0x00, 0x00, 0x00, 0x02, 0x00, // variables
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
// function definitions
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,
|
|
|
|
// code
|
|
0x68, 0x54, 0x42,
|
|
};
|
|
|
|
ByteArray ba = Bytecode::generate(bp);
|
|
ASSERT_EQ(ba.data(), expected);
|
|
}
|
|
|
|
TEST(Bytecode, Parsing)
|
|
{
|
|
// write bytecode
|
|
|
|
BytecodePrototype bp;
|
|
|
|
bp.constants.emplace_back(42);
|
|
bp.constants.emplace_back(3.14f);
|
|
bp.constants.emplace_back("HELLO");
|
|
|
|
auto& f = bp.functions.emplace_back(0, 0);
|
|
f.code.append_byte(0x68);
|
|
f.code.append_int(42);
|
|
|
|
auto& f2 = bp.functions.emplace_back(2, 1);
|
|
f2.code.append_byte(0x42);
|
|
|
|
ByteArray ba = Bytecode::generate(bp);
|
|
|
|
// read bytecode
|
|
|
|
Bytecode bc2(std::move(ba));
|
|
|
|
ASSERT_EQ(bc2.n_constants(), 3);
|
|
ASSERT_EQ(bc2.n_functions(), 2);
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
} |