This commit is contained in:
2026-04-29 11:37:32 -05:00
parent 9229d6c86e
commit 751b4bd547
7 changed files with 44 additions and 25 deletions

View File

@@ -73,7 +73,8 @@ target_compile_options(lib${PROJECT_NAME} PRIVATE ${warnings})
# tests # 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) target_link_libraries(${PROJECT_NAME}-bytecode-test lib${PROJECT_NAME} gtest_main)
add_test(NAME tyche_bytecode_test COMMAND ${PROJECT_NAME}-bytecode-test) add_test(NAME tyche_bytecode_test COMMAND ${PROJECT_NAME}-bytecode-test)

View File

@@ -11,8 +11,7 @@
Improvements: Improvements:
- [x] Fixed int type (based on opcode) - [x] Fixed int type (based on opcode)
- [ ] Constant type (only floats and strings for now) - [x] Constant type (only floats and strings for now)
- [ ] Debug output bytecode format
After some additional development: After some additional development:
- [ ] Bytecode debugging info - [ ] Bytecode debugging info

View File

@@ -39,16 +39,17 @@ uint32_t Bytecode::n_functions() const
return cache_.n_functions; 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)); 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); 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);
std::string Bytecode::get_constant_string(uint32_t idx) const case CONST_TYPE_STRING:
{ return byte_array_.get_string(cache_.constants_start_addr + constant_idx + 1).first;
uint32_t constant_idx = byte_array_.get_uint32(cache_.constants_idx_addr + (idx * CONST_RECORD_SZ)); default:
return byte_array_.get_string(cache_.constants_start_addr + constant_idx).first; throw BytecodeParsingError("Invalid bytecode format (invalid constant type)");
}
} }
Bytecode::FunctionDef Bytecode::get_function_def(uint32_t function_id) const 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) { for (auto const& constant: bp.constants) {
constant_indexes.append_uint32(idx); constant_indexes.append_uint32(idx);
std::visit(overloaded { std::visit(overloaded {
[&](int32_t i) { raw_constants.append_int32(i); }, [&](float f) {
[&](float f) { raw_constants.append_float(f); }, raw_constants.append_byte(CONST_TYPE_FLOAT);
[&](std::string const& s) { raw_constants.append_string(s); }, raw_constants.append_float(f);
},
[&](std::string const& s) {
raw_constants.append_byte(CONST_TYPE_STRING);
raw_constants.append_string(s);
},
}, constant); }, constant);
idx = raw_constants.size(); idx = raw_constants.size();
} }

View File

@@ -13,15 +13,14 @@ public:
[[nodiscard]] uint32_t n_constants() const; [[nodiscard]] uint32_t n_constants() const;
[[nodiscard]] uint32_t n_functions() const; [[nodiscard]] uint32_t n_functions() const;
[[nodiscard]] float get_constant_float(uint32_t idx) const; [[nodiscard]] ConstantValue get_constant(uint32_t idx) const;
[[nodiscard]] std::string get_constant_string(uint32_t idx) const;
struct FunctionDef { uint16_t n_params, locals; }; struct FunctionDef { uint16_t n_params, locals; };
[[nodiscard]] FunctionDef get_function_def(uint32_t function_id) const; [[nodiscard]] FunctionDef get_function_def(uint32_t function_id) const;
[[nodiscard]] uint32_t get_function_sz(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]] 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]] 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; [[nodiscard]] int32_t get_code_int32(uint32_t function_id, uint32_t idx) const;

View File

@@ -5,12 +5,11 @@
#include <string> #include <string>
#include <variant> #include <variant>
#include <vector> #include <vector>
#include "constant.hh"
namespace tyche { namespace tyche {
struct BytecodePrototype { struct BytecodePrototype {
using ConstantValue = std::variant<float, std::string>;
struct Function { struct Function {
uint16_t n_pars; uint16_t n_pars;
uint16_t n_locals; uint16_t n_locals;

15
src/bytecode/constant.hh Normal file
View File

@@ -0,0 +1,15 @@
#ifndef TYCHE_CONSTANT_HH
#define TYCHE_CONSTANT_HH
#include <string>
#include <variant>
namespace tyche {
using ConstantValue = std::variant<float, std::string>;
enum ConstantType : uint8_t { CONST_TYPE_FLOAT = 1, CONST_TYPE_STRING = 2 };
}
#endif //TYCHE_CONSTANT_HH

View File

@@ -57,7 +57,7 @@ TEST(Bytecode, Constants)
// index // index
0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // constant index 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // constant index
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // function undex 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, // raw code
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,
@@ -66,11 +66,11 @@ TEST(Bytecode, Constants)
// constant indexes // constant indexes
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
// constant values // constant values
0x33, 0x33, 0x29, 0x42, // float: 42.3f CONST_TYPE_FLOAT, 0x33, 0x33, 0x29, 0x42, // float: 42.3f
'H', 'E', 'L', 'L', 'O', 0x00 CONST_TYPE_STRING, 'H', 'E', 'L', 'L', 'O', 0x00
}; };
ByteArray ba = Bytecode::generate(bp); ByteArray ba = Bytecode::generate(bp);
@@ -142,8 +142,8 @@ TEST(Bytecode, Parsing)
ASSERT_EQ(bc.n_constants(), 2); ASSERT_EQ(bc.n_constants(), 2);
ASSERT_EQ(bc.n_functions(), 2); ASSERT_EQ(bc.n_functions(), 2);
ASSERT_FLOAT_EQ(bc.get_constant_float(0), 3.14f); ASSERT_FLOAT_EQ(std::get<float>(bc.get_constant(0)), 3.14f);
ASSERT_EQ(bc.get_constant_string(1), "HELLO"); ASSERT_EQ(std::get<std::string>(bc.get_constant(1)), "HELLO");
Bytecode::FunctionDef f1 = bc.get_function_def(0); Bytecode::FunctionDef f1 = bc.get_function_def(0);
ASSERT_EQ(f1.n_params, 0); ASSERT_EQ(f1.n_params, 0);