This commit is contained in:
2026-05-15 10:42:59 -05:00
parent a0881e3c22
commit d2463fd163
3 changed files with 48 additions and 7 deletions

View File

@@ -179,6 +179,11 @@ local function assemble(proto)
return #bin - 3 return #bin - 3
end end
local replace16 = function(pos, data)
bin[pos] = data & 0xff
bin[pos + 1] = (data >> 8) & 0xff
end
local replace32 = function(pos, data) local replace32 = function(pos, data)
bin[pos] = data & 0xff bin[pos] = data & 0xff
bin[pos + 1] = (data >> 8) & 0xff bin[pos + 1] = (data >> 8) & 0xff
@@ -198,7 +203,14 @@ local function assemble(proto)
-- constants -- constants
local code_addr_pos = push32(0) -- code address, to be replaced local code_addr_pos = push32(0) -- code address, to be replaced
push32(#proto.constants + 1) -- number of constants
-- number of constants
if proto.constants[0] then
push32(#proto.constants + 1)
else
push32(0)
end
for i=0,#proto.constants do for i=0,#proto.constants do
local const = proto.constants[i] local const = proto.constants[i]
if type(const) == 'string' then if type(const) == 'string' then
@@ -218,19 +230,32 @@ local function assemble(proto)
-- code -- code
push32(0) -- debug address (TODO) push32(0) -- debug address (TODO)
push32(#proto.functions + 1) -- number of functions push32(#proto.functions + 1) -- number of functions
for i = 0, #proto.functions do for i = 0, #proto.functions do
local func = proto.functions[i] local func = proto.functions[i]
local next_function_pos = #bin + 1 local next_function_pos = #bin + 1
push32(0) -- to be replaced with next function address push32(0) -- to be replaced with next function address
local function_start = #bin
local labels = {}
for _, inst in ipairs(func) do for _, inst in ipairs(func) do
-- add labels
if inst.labels then
for _, lbl in ipairs(inst.labels) do
labels[lbl] = #bin - function_start - 1
end
end
local opcode, operand = instructions[inst[1]], inst[2] local opcode, operand = instructions[inst[1]], inst[2]
if opcode == nil then error("Unknown instruction " .. inst[1]) end if opcode == nil then error("Unknown instruction " .. inst[1]) end
if operand == nil then if operand == nil then
push8(opcode) push8(opcode)
elseif type(operand) == 'string' then elseif type(operand) == 'string' then
-- TODO
push8(opcode) push8(opcode)
push16(0) table.insert(bin, operand) -- insert the label
push8(0) -- byte to be replaced (label is 16-bit)
else else
if opcode >= 0xc0 and opcode < 0xe0 then if opcode >= 0xc0 and opcode < 0xe0 then
push8(opcode) push8(opcode)
@@ -246,11 +271,22 @@ local function assemble(proto)
push32(operand) push32(operand)
end end
end end
end end
-- replace labels
for i=function_start,#bin do
if type(bin[i]) == 'string' then
local label_addr = labels[bin[i]]
if label_addr == nil then error("Label not found: " .. bin[i]) end
replace32(i, label_addr)
end
end
replace32(next_function_pos, #bin) replace32(next_function_pos, #bin)
end end
-- for _, b in ipairs(bin) do io.write(b .. ' ') end; print() for _, b in ipairs(bin) do io.write(string.format("%02x", b) .. ' ') end; print()
return string.char(table.unpack(bin)) return string.char(table.unpack(bin))
end end

View File

@@ -78,9 +78,9 @@ typedef enum {
TO_LOAD = 0X4A, TO_LOAD = 0X4A,
// CONTROL FLOW // CONTROL FLOW
TO_BZ = 0XCA, TO_BZ = 0XAA,
TO_BNZ = 0XCB, TO_BNZ = 0XAB,
TO_JMP = 0XCC, TO_JMP = 0XAC,
// MEMORY MANAGEMENT // MEMORY MANAGEMENT
TO_GC = 0X4B, TO_GC = 0X4B,

View File

@@ -285,6 +285,11 @@ int main()
Code* code = code_new(); Code* code = code_new();
assert(code_load_bytecode(code, bytecode, bytecode_sz) == T_OK); assert(code_load_bytecode(code, bytecode, bytecode_sz) == T_OK);
Instruction inst = code_next_instruction(code, 0, 0);
assert(inst.operator == TO_JMP);
assert(inst.operand == 3);
assert(inst.sz == 3);
code_destroy(code); code_destroy(code);
free(bytecode); free(bytecode);
} }