This commit is contained in:
2026-04-28 09:48:16 -05:00
parent 44a51acad1
commit 30ecab3403
3 changed files with 85 additions and 76 deletions

View File

@@ -3,75 +3,8 @@
namespace tyche {
Bytecode::Bytecode(BytecodePrototype const& bp)
{
// constants
std::vector<uint32_t> constant_table;
ByteArray constant_array;
uint32_t idx = 0;
for (auto const& constant: bp.constants) {
constant_table.emplace_back(idx);
std::visit(overloaded {
[&](int32_t i) { constant_array.append_int(i); },
[&](float f) { constant_array.append_float(f); },
[&](std::string const& s) { constant_array.append_string(s); },
}, constant);
idx = constant_array.size();
}
// function table
std::vector<std::pair<FunctionDef, uint32_t>> functions;
ByteArray code;
for (auto const& f: bp.functions) {
functions.emplace_back(std::make_pair(FunctionDef { f.n_pars, f.n_locals }, code.size()));
code.append_bytearray(f.code);
}
//
// build binary
//
// header
byte_array_.set_uint32(0, MAGIC);
byte_array_.set_byte(4, VERSION);
// constants
idx = HEADER_SZ + INDEX_SZ;
for (auto const& const_idx: constant_table) {
byte_array_.set_uint32(idx, const_idx);
idx += 4;
}
byte_array_.append_bytearray(constant_array);
// constant index
if (!constant_table.empty()) {
byte_array_.set_uint32(HEADER_SZ, HEADER_SZ + INDEX_SZ);
byte_array_.set_uint16(HEADER_SZ + 4, constant_table.size());
}
// functions
size_t functions_start = idx + (constant_table.size() * 4) + byte_array_.size();
idx += functions_start;
uint32_t code_idx = 0;
for (auto const& f: functions) {
byte_array_.set_uint32(idx, code_idx);
byte_array_.set_uint16(idx + 4, f.first.n_params);
byte_array_.set_uint16(idx + 6, f.first.n_params);
idx += 8;
code_idx += f.second;
}
for (auto const& f: bp.functions)
byte_array_.append_bytearray(f.code);
// function index
if (!functions.empty()) {
byte_array_.set_uint32(HEADER_SZ + 6, functions_start);
byte_array_.set_uint16(HEADER_SZ + 6 + 4, functions.size());
}
}
Bytecode::Bytecode(std::vector<uint8_t> data)
: byte_array_(std::move(data))
Bytecode::Bytecode(ByteArray ba)
: byte_array_(std::move(ba))
{
// check file size
if (byte_array_.size() < (HEADER_SZ + INDEX_SZ))
@@ -135,4 +68,75 @@ float Bytecode::get_code_float(uint32_t function_id, uint32_t idx) const
return 0;
}
ByteArray Bytecode::generate(BytecodePrototype const& bp)
{
ByteArray ba;
// constants
std::vector<uint32_t> constant_table;
ByteArray constant_array;
uint32_t idx = 0;
for (auto const& constant: bp.constants) {
constant_table.emplace_back(idx);
std::visit(overloaded {
[&](int32_t i) { constant_array.append_int(i); },
[&](float f) { constant_array.append_float(f); },
[&](std::string const& s) { constant_array.append_string(s); },
}, constant);
idx = constant_array.size();
}
// function table
std::vector<std::pair<FunctionDef, uint32_t>> functions;
ByteArray code;
for (auto const& f: bp.functions) {
functions.emplace_back(std::make_pair(FunctionDef { f.n_pars, f.n_locals }, code.size()));
code.append_bytearray(f.code);
}
//
// build binary
//
// header
ba.set_uint32(0, MAGIC);
ba.set_byte(4, VERSION);
// constants
idx = HEADER_SZ + INDEX_SZ;
for (auto const& const_idx: constant_table) {
ba.set_uint32(idx, const_idx);
idx += 4;
}
ba.append_bytearray(constant_array);
// constant index
if (!constant_table.empty()) {
ba.set_uint32(HEADER_SZ, HEADER_SZ + INDEX_SZ);
ba.set_uint16(HEADER_SZ + 4, constant_table.size());
}
// functions
size_t functions_start = idx + (constant_table.size() * 4) + ba.size();
idx += functions_start;
uint32_t code_idx = 0;
for (auto const& f: functions) {
ba.set_uint32(idx, code_idx);
ba.set_uint16(idx + 4, f.first.n_params);
ba.set_uint16(idx + 6, f.first.n_params);
idx += 8;
code_idx += f.second;
}
for (auto const& f: bp.functions)
ba.append_bytearray(f.code);
// function index
if (!functions.empty()) {
ba.set_uint32(HEADER_SZ + 6, functions_start);
ba.set_uint16(HEADER_SZ + 6 + 4, functions.size());
}
return ba;
}
}