This commit is contained in:
2026-05-14 23:28:16 -05:00
parent 8a4cce0da4
commit 89caa700cf
6 changed files with 81 additions and 40 deletions

View File

@@ -14,8 +14,7 @@ The bytecode file is composed of the following sections:
Each constant: Each constant:
[0]: Type (0 = string, 1 = real) [0]: Type (0 = string, 1 = real)
if string: if string:
[1..4]: string size [...]: string (NULL terminated)
[...]: string
if real if real
[1..4]: real [1..4]: real

View File

@@ -2,6 +2,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# error Sorry, big endian architectures are not supported at this time. # error Sorry, big endian architectures are not supported at this time.
@@ -15,13 +16,14 @@
#define CONST_START 0x10 #define CONST_START 0x10
struct Code { struct Code {
uint8_t* bytecode; uint8_t const* bytecode;
size_t bytecode_sz; size_t bytecode_sz;
uint32_t* const_addr; uint32_t* const_addr;
uint32_t* fn_addr; uint32_t fn_count;
uint32_t* fn_addr;
}; };
Code* code_new() Code* code_new(void)
{ {
Code* code = xcalloc(1, sizeof(Code)); Code* code = xcalloc(1, sizeof(Code));
return code; return code;
@@ -29,6 +31,8 @@ Code* code_new()
void code_destroy(Code* code) void code_destroy(Code* code)
{ {
free(code->const_addr);
free(code->fn_addr);
free(code); free(code);
} }
@@ -46,6 +50,7 @@ TYC_RESULT code_load_bytecode(Code* code, uint8_t* bytecode, size_t bytecode_sz)
code->bytecode = bytecode; code->bytecode = bytecode;
code->bytecode_sz = bytecode_sz; code->bytecode_sz = bytecode_sz;
/*
for (size_t i = 0; i < bytecode_sz; ++i) { for (size_t i = 0; i < bytecode_sz; ++i) {
if (i % 16 == 0) if (i % 16 == 0)
printf("%04X: ", i); printf("%04X: ", i);
@@ -53,32 +58,71 @@ TYC_RESULT code_load_bytecode(Code* code, uint8_t* bytecode, size_t bytecode_sz)
if (i % 16 == 15) if (i % 16 == 15)
printf("\n"); printf("\n");
} }
printf("\n");
*/
uint32_t n_consts = code_n_consts(code);
code->const_addr = calloc(n_consts, sizeof(uint32_t));
uint32_t addr = CONST_START;
for (size_t i = 0; i < n_consts; ++i) {
code->const_addr[i] = addr;
switch (code_const_type(code, i)) {
case TC_STRING: {
uint32_t sz = (uint32_t) strlen((const char*) &bytecode[code->const_addr[i] + 1]);
addr += sz + 2; // 2 = constant type + NULL terminator
break;
}
case TC_REAL:
addr += 5; // 5 = constant type + float
break;
case TC_INVALID_TYPE:
default:
__builtin_unreachable();
}
}
addr += 4; // skip debug start address
memcpy(&code->fn_count, &bytecode[addr], sizeof(uint32_t)); // number of functions
addr += 4;
code->fn_addr = calloc(code->fn_count, sizeof(uint32_t));
code->fn_addr[0] = addr;
for (size_t i = 1; i < code->fn_count; ++i) {
uint32_t addr_next;
memcpy(&addr_next, &bytecode[addr], sizeof(uint32_t));
addr = code->fn_addr[i] = addr_next;
}
return T_OK; return T_OK;
} }
size_t code_n_consts(Code const* code) uint32_t code_n_consts(Code const* code)
{ {
uint32_t n_consts = *(uint32_t*) &code->bytecode[N_CONST_ADDR]; uint32_t n_consts; memcpy(&n_consts, &code->bytecode[N_CONST_ADDR], sizeof(uint32_t));
return n_consts; return n_consts;
} }
TYC_CONST_TYPE code_const_type(Code const* code, size_t n) TYC_CONST_TYPE code_const_type(Code const* code, size_t n)
{ {
return TC_REAL; // TODO uint8_t t = code->bytecode[code->const_addr[n]];
if (t >= TC_INVALID_TYPE)
return TC_INVALID_TYPE;
return t;
} }
T_REAL code_const_real(Code const* code, size_t n) T_REAL code_const_real(Code const* code, size_t n)
{ {
return 0.f; // TODO float f;
memcpy(&f, &code->bytecode[code->const_addr[n] + 1], sizeof(float));
return f;
} }
const char* code_const_string(Code const* code, size_t n) const char* code_const_string(Code const* code, size_t n)
{ {
return ""; // TODO return (const char*) &code->bytecode[code->const_addr[n] + 1];
} }
size_t code_n_functions(Code const* code) uint32_t code_n_functions(Code const* code)
{ {
return 0; // TODO return code->fn_count;
} }

View File

@@ -35,7 +35,7 @@ TYC_RESULT code_assemble(const char* code, uint8_t** bytecode, size_t* bytecode_
if (!lua_isstring(L, -1)) if (!lua_isstring(L, -1))
abort(); abort();
*bytecode_sz = luaL_len(L, -1); *bytecode_sz = (size_t) luaL_len(L, -1);
*bytecode = malloc(*bytecode_sz); *bytecode = malloc(*bytecode_sz);
memcpy(*bytecode, lua_tostring(L, -1), *bytecode_sz); memcpy(*bytecode, lua_tostring(L, -1), *bytecode_sz);

View File

@@ -107,13 +107,9 @@ local function assemble(proto)
bin[pos + 3] = (data >> 24) & 0xff bin[pos + 3] = (data >> 24) & 0xff
end end
local float_to_le_bytes = function(f) local function float_to_bits(f)
local bytes = {} local bytes = string.pack("<f", f)
local packed = string.pack("<f", f) return string.unpack("<I4", bytes)
for i = 1, 4 do
bytes[i] = packed:byte(i)
end
return bytes
end end
-- header -- header
@@ -123,34 +119,35 @@ 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
print(code_addr_pos) push32(#proto.constants + 1) -- number of constants
push32(#proto.constants) -- number of constants for i=0,#proto.constants do
for i, const in ipairs(proto.constants) do local const = proto.constants[i]
if type(const) == 'string' then if type(const) == 'string' then
table.insert(bin, 0) -- string type table.insert(bin, 0) -- string type
push32(#const)
for c in const:gmatch('.') do for c in const:gmatch('.') do
table.insert(bin, c:byte()) table.insert(bin, c:byte())
end end
table.insert(bin, 0) -- string terminator
elseif type(const) == 'number' then elseif type(const) == 'number' then
table.insert(bin, 0) -- float type table.insert(bin, 1) -- float type
push32(float_to_le_bytes(const)) push32(float_to_bits(const))
end end
end end
replace32(code_addr_pos, #bin) replace32(code_addr_pos, #bin)
-- code -- code
push32(0) -- debug address (TODO) push32(0) -- debug address (TODO)
push32(#proto.functions) -- number of functions push32(#proto.functions + 1) -- number of functions
for _,func in ipairs(proto.functions) do for i=0,#proto.functions do
local next_function_pos = #bin local func = proto.functions[i]
local next_function_pos = #bin + 1
push32(0) -- to be replaced with next function address push32(0) -- to be replaced with next function address
-- TODO - add code -- TODO - add code
replace32(next_function_pos, #bin) replace32(next_function_pos, #bin)
end end
return string.char(table.unpack(bin)) return string.char(table.unpack(bin))
end end
---------------------- ----------------------

View File

@@ -30,7 +30,7 @@ typedef uint32_t HEAP_KEY;
typedef uint64_t TABLE_HASH; typedef uint64_t TABLE_HASH;
typedef enum { typedef enum {
TC_STRING, TC_REAL, TC_STRING, TC_REAL, TC_INVALID_TYPE
} TYC_CONST_TYPE; } TYC_CONST_TYPE;
// //
@@ -124,19 +124,19 @@ void heap_gc(Heap* h, VALUE const* roots, size_t n_roots);
// CODE // CODE
// //
TYC_RESULT code_assemble(const char* code, uint8_t** bytecode, size_t* bytecode_sz); TYC_RESULT code_assemble(const char* code, uint8_t** bytecode, size_t* bytecode_sz);
Code* code_new(); Code* code_new(void);
void code_destroy(Code* code); void code_destroy(Code* code);
TYC_RESULT code_load_bytecode(Code* code, uint8_t* bytecode, size_t bytecode_sz); TYC_RESULT code_load_bytecode(Code* code, uint8_t* bytecode, size_t bytecode_sz);
size_t code_n_consts(Code const* code); uint32_t code_n_consts(Code const* code);
TYC_CONST_TYPE code_const_type(Code const* code, size_t n); TYC_CONST_TYPE code_const_type(Code const* code, size_t n);
T_REAL code_const_real(Code const* code, size_t n); T_REAL code_const_real(Code const* code, size_t n);
const char* code_const_string(Code const* code, size_t n); const char* code_const_string(Code const* code, size_t n);
size_t code_n_functions(Code const* code); uint32_t code_n_functions(Code const* code);
#endif //TYCHE_PRIV_H #endif //TYCHE_PRIV_H

View File

@@ -241,9 +241,10 @@ int main()
assert(code_const_type(code, 0) == TC_REAL); assert(code_const_type(code, 0) == TC_REAL);
assert(code_const_type(code, 1) == TC_STRING); assert(code_const_type(code, 1) == TC_STRING);
assert(code_const_real(code, 0) >= 3.13 && code_const_real(code, 0) <= 3.15); assert(code_const_real(code, 0) >= 3.13 && code_const_real(code, 0) <= 3.15);
assert(strcmp(code_const_string(code, 1), "Hello world\n") == 0); assert(strcmp(code_const_string(code, 1), "Hello world") == 0);
assert(code_n_functions(code) == 2); assert(code_n_functions(code) == 2);
code_destroy(code);
free(bytecode); free(bytecode);
} }
} }