diff --git a/CMakeLists.txt b/CMakeLists.txt index 3dbb8bc..c21a4e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,7 +73,8 @@ target_compile_options(lib${PROJECT_NAME} PRIVATE ${warnings}) # tests # -add_executable(${PROJECT_NAME}-bytecode-test src/bytecode/tests.cc) +add_executable(${PROJECT_NAME}-bytecode-test src/bytecode/tests.cc + src/bytecode/constant.hh) target_link_libraries(${PROJECT_NAME}-bytecode-test lib${PROJECT_NAME} gtest_main) add_test(NAME tyche_bytecode_test COMMAND ${PROJECT_NAME}-bytecode-test) diff --git a/TODO.md b/TODO.md index 5b92b3f..2fb18a7 100644 --- a/TODO.md +++ b/TODO.md @@ -11,8 +11,7 @@ Improvements: - [x] Fixed int type (based on opcode) -- [ ] Constant type (only floats and strings for now) -- [ ] Debug output bytecode format +- [x] Constant type (only floats and strings for now) After some additional development: - [ ] Bytecode debugging info diff --git a/src/bytecode/bytecode.cc b/src/bytecode/bytecode.cc index 5dbe173..58950d1 100644 --- a/src/bytecode/bytecode.cc +++ b/src/bytecode/bytecode.cc @@ -39,16 +39,17 @@ uint32_t Bytecode::n_functions() const return cache_.n_functions; } -float Bytecode::get_constant_float(uint32_t idx) const +ConstantValue Bytecode::get_constant(uint32_t idx) const { uint32_t constant_idx = byte_array_.get_uint32(cache_.constants_idx_addr + (idx * CONST_RECORD_SZ)); - return byte_array_.get_float(cache_.constants_start_addr + constant_idx); -} - -std::string Bytecode::get_constant_string(uint32_t idx) const -{ - uint32_t constant_idx = byte_array_.get_uint32(cache_.constants_idx_addr + (idx * CONST_RECORD_SZ)); - return byte_array_.get_string(cache_.constants_start_addr + constant_idx).first; + switch ((ConstantType) byte_array_.get_byte(cache_.constants_start_addr + constant_idx)) { + case CONST_TYPE_FLOAT: + return byte_array_.get_float(cache_.constants_start_addr + constant_idx + 1); + case CONST_TYPE_STRING: + return byte_array_.get_string(cache_.constants_start_addr + constant_idx + 1).first; + default: + throw BytecodeParsingError("Invalid bytecode format (invalid constant type)"); + } } Bytecode::FunctionDef Bytecode::get_function_def(uint32_t function_id) const @@ -100,9 +101,14 @@ ByteArray Bytecode::generate(BytecodePrototype const& bp) for (auto const& constant: bp.constants) { constant_indexes.append_uint32(idx); std::visit(overloaded { - [&](int32_t i) { raw_constants.append_int32(i); }, - [&](float f) { raw_constants.append_float(f); }, - [&](std::string const& s) { raw_constants.append_string(s); }, + [&](float f) { + raw_constants.append_byte(CONST_TYPE_FLOAT); + raw_constants.append_float(f); + }, + [&](std::string const& s) { + raw_constants.append_byte(CONST_TYPE_STRING); + raw_constants.append_string(s); + }, }, constant); idx = raw_constants.size(); } diff --git a/src/bytecode/bytecode.hh b/src/bytecode/bytecode.hh index 6fb489f..a6001c6 100644 --- a/src/bytecode/bytecode.hh +++ b/src/bytecode/bytecode.hh @@ -13,15 +13,14 @@ public: [[nodiscard]] uint32_t n_constants() const; [[nodiscard]] uint32_t n_functions() const; - [[nodiscard]] float get_constant_float(uint32_t idx) const; - [[nodiscard]] std::string get_constant_string(uint32_t idx) const; + [[nodiscard]] ConstantValue get_constant(uint32_t idx) const; struct FunctionDef { uint16_t n_params, locals; }; [[nodiscard]] FunctionDef get_function_def(uint32_t function_id) const; [[nodiscard]] uint32_t get_function_sz(uint32_t function_id) const; [[nodiscard]] uint8_t get_code_byte(uint32_t function_id, uint32_t idx) const; - [[nodiscard]] int8_t get_code_int8(uint32_t function_id, uint32_t idx) const; + [[nodiscard]] int8_t get_code_int8(uint32_t function_id, uint32_t idx) const; [[nodiscard]] int16_t get_code_int16(uint32_t function_id, uint32_t idx) const; [[nodiscard]] int32_t get_code_int32(uint32_t function_id, uint32_t idx) const; diff --git a/src/bytecode/bytecodeprototype.hh b/src/bytecode/bytecodeprototype.hh index 880027b..d7159fb 100644 --- a/src/bytecode/bytecodeprototype.hh +++ b/src/bytecode/bytecodeprototype.hh @@ -5,12 +5,11 @@ #include #include #include +#include "constant.hh" namespace tyche { struct BytecodePrototype { - using ConstantValue = std::variant; - struct Function { uint16_t n_pars; uint16_t n_locals; diff --git a/src/bytecode/constant.hh b/src/bytecode/constant.hh new file mode 100644 index 0000000..5972d46 --- /dev/null +++ b/src/bytecode/constant.hh @@ -0,0 +1,15 @@ +#ifndef TYCHE_CONSTANT_HH +#define TYCHE_CONSTANT_HH + +#include +#include + +namespace tyche { + +using ConstantValue = std::variant; + +enum ConstantType : uint8_t { CONST_TYPE_FLOAT = 1, CONST_TYPE_STRING = 2 }; + +} + +#endif //TYCHE_CONSTANT_HH diff --git a/src/bytecode/tests.cc b/src/bytecode/tests.cc index 7c39152..83f764c 100644 --- a/src/bytecode/tests.cc +++ b/src/bytecode/tests.cc @@ -57,7 +57,7 @@ TEST(Bytecode, Constants) // index 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // constant index 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // function undex - 0x58, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, // raw constants + 0x58, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, // raw constants 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // raw code 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -66,11 +66,11 @@ TEST(Bytecode, Constants) // constant indexes 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, // constant values - 0x33, 0x33, 0x29, 0x42, // float: 42.3f - 'H', 'E', 'L', 'L', 'O', 0x00 + CONST_TYPE_FLOAT, 0x33, 0x33, 0x29, 0x42, // float: 42.3f + CONST_TYPE_STRING, 'H', 'E', 'L', 'L', 'O', 0x00 }; ByteArray ba = Bytecode::generate(bp); @@ -142,8 +142,8 @@ TEST(Bytecode, Parsing) ASSERT_EQ(bc.n_constants(), 2); ASSERT_EQ(bc.n_functions(), 2); - ASSERT_FLOAT_EQ(bc.get_constant_float(0), 3.14f); - ASSERT_EQ(bc.get_constant_string(1), "HELLO"); + ASSERT_FLOAT_EQ(std::get(bc.get_constant(0)), 3.14f); + ASSERT_EQ(std::get(bc.get_constant(1)), "HELLO"); Bytecode::FunctionDef f1 = bc.get_function_def(0); ASSERT_EQ(f1.n_params, 0);