From a38b2736c6fa28b93adba7438dae8e7afe7b5177 Mon Sep 17 00:00:00 2001 From: Andre Wagner Date: Thu, 14 May 2026 14:39:34 -0500 Subject: [PATCH] . --- doc/BYTECODE | 4 ++-- lib/code.c | 39 ++++++++++++++++++++++++++++++++++++--- lib/compiler.c | 14 +++++++++++++- lib/compiler/compiler.lua | 1 + lib/priv.h | 16 +++++++++++++--- lib/tyche.h | 2 ++ test/code-tests.lua | 14 ++++++++++++++ test/tests.c | 31 +++++++++++++++++++++++++++++++ 8 files changed, 112 insertions(+), 9 deletions(-) create mode 100644 test/code-tests.lua diff --git a/doc/BYTECODE b/doc/BYTECODE index b73ba24..6456367 100644 --- a/doc/BYTECODE +++ b/doc/BYTECODE @@ -21,10 +21,10 @@ The bytecode file is composed of the following sections: [1..4]: real * CODE + [0:3]: Debug start address (or zero) + [4:7]: Number of functions Each function: [0:3] Address of next function - [4:5] Number of parameters - [6:7] Number of variables [...] Code [0] : Opcode [between 1 and 4] : Operand diff --git a/lib/code.c b/lib/code.c index feae963..0c2e9cd 100644 --- a/lib/code.c +++ b/lib/code.c @@ -1,9 +1,42 @@ #include "priv.h" -Code* code_load_bytecode(uint8_t* bytecode, size_t bytecode_sz) +#include + +struct Code { +}; + +Code* code_new(uint8_t* bytecode, size_t bytecode_sz) { + Code* code = xcalloc(1, sizeof(Code)); + return code; } -Code* code_load_bytecode_cb(void(*read_bytes)(size_t, void*), void* data) +void code_destroy(Code* code) { -} \ No newline at end of file + free(code); +} + +size_t code_n_consts(Code const* code) +{ + return 0; // TODO +} + +TYC_CONST_TYPE code_const_type(Code const* code, size_t n) +{ + return TC_REAL; // TODO +} + +T_REAL code_const_real(Code const* code, size_t n) +{ + return 0.f; // TODO +} + +const char* code_const_string(Code const* code, size_t n) +{ + return ""; // TODO +} + +size_t code_n_functions(Code const* code) +{ + return 0; // TODO +} diff --git a/lib/compiler.c b/lib/compiler.c index c272da2..cd86aea 100644 --- a/lib/compiler.c +++ b/lib/compiler.c @@ -5,12 +5,14 @@ #include "lua.h" #include "lauxlib.h" +#include "lualib.h" #include "compiler/compiler.lua.h" TYC_RESULT code_assemble(const char* code, uint8_t** bytecode, size_t* bytecode_sz) { lua_State* L = luaL_newstate(); + luaL_openlibs(L); int r = luaL_loadbufferx(L, (const char *) lib_compiler_compiler_out, lib_compiler_compiler_out_len, "compiler", "b"); if (r == LUA_ERRSYNTAX) @@ -18,6 +20,8 @@ TYC_RESULT code_assemble(const char* code, uint8_t** bytecode, size_t* bytecode_ else if (r == LUA_ERRMEM) out_of_memory(); + lua_call(L, 0, 1); + lua_pushstring(L, code); r = lua_pcall(L, 1, 1, 0); if (r == LUA_ERRMEM) { @@ -29,7 +33,15 @@ TYC_RESULT code_assemble(const char* code, uint8_t** bytecode, size_t* bytecode_ return T_ERR_ASSEMBLER_SYNTAX_ERROR; } - + if (!lua_istable(L, -1)) + abort(); + *bytecode_sz = luaL_len(L, -1); + *bytecode = malloc(*bytecode_sz); + for (size_t i = 0; i < *bytecode_sz; ++i) { + lua_geti(L, -1, i + 1); + (*bytecode)[i] = (uint8_t) lua_tointeger(L, -1); + lua_pop(L, 1); + } lua_close(L); return T_OK; diff --git a/lib/compiler/compiler.lua b/lib/compiler/compiler.lua index 367d945..34085d7 100644 --- a/lib/compiler/compiler.lua +++ b/lib/compiler/compiler.lua @@ -81,5 +81,6 @@ end ---------------------- return function(source) + print('test') return { 0, 1, 2, 3, 4 } end \ No newline at end of file diff --git a/lib/priv.h b/lib/priv.h index 9da801b..ab112d4 100644 --- a/lib/priv.h +++ b/lib/priv.h @@ -29,6 +29,10 @@ typedef struct Code Code; typedef uint32_t HEAP_KEY; typedef uint64_t TABLE_HASH; +typedef enum { + TC_STRING, TC_REAL, +} TYC_CONST_TYPE; + // // UTILS // @@ -122,9 +126,15 @@ void heap_gc(Heap* h, VALUE const* roots, size_t n_roots); TYC_RESULT code_assemble(const char* code, uint8_t** bytecode, size_t* bytecode_sz); -Code* code_load_bytecode(uint8_t* bytecode, size_t bytecode_sz); -Code* code_load_bytecode_cb(void(*read_bytes)(size_t, void*), void* data); - +Code* code_new(uint8_t* bytecode, size_t bytecode_sz); void code_destroy(Code* code); +size_t code_n_consts(Code const* code); +TYC_CONST_TYPE code_const_type(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); + +size_t code_n_functions(Code const* code); + #endif //TYCHE_PRIV_H diff --git a/lib/tyche.h b/lib/tyche.h index 34b7344..1598c86 100644 --- a/lib/tyche.h +++ b/lib/tyche.h @@ -13,4 +13,6 @@ typedef enum { T_ERR_ASSEMBLER_SYNTAX_ERROR = -30, } TYC_RESULT; +#define T_REAL float + #endif //TYCHE_TYCHE_H diff --git a/test/code-tests.lua b/test/code-tests.lua new file mode 100644 index 0000000..71e2197 --- /dev/null +++ b/test/code-tests.lua @@ -0,0 +1,14 @@ +return { + { + name = "VM: basic", + code = [[ + .func 0 + pushi 2 + pushi 3 + sum + ret + ]], + expected_stack_size = 1, + expected_stack_top = { integer = 5 }, + }, +} \ No newline at end of file diff --git a/test/tests.c b/test/tests.c index 24ea6a6..f0d6d6a 100644 --- a/test/tests.c +++ b/test/tests.c @@ -213,4 +213,35 @@ int main() heap_destroy(h); stack_destroy(s); } + + { + printf("### Bytecode\n"); + const char* assembly_code = + ".const\n" + " 0: 3.14\n" + " 1: \"Hello world\"\n" + "\n" + ".func 0\n" + " pushi 2 ; this is a comment\n" + " pushi 3\n" + " sum\n" + " ret\n" + ".func 1\n" + " pushi 5000\n" + " ret"; + + uint8_t* bytecode; size_t bytecode_sz; + assert(code_assemble(assembly_code, &bytecode, &bytecode_sz) == T_OK); + + Code* code = code_new(bytecode, bytecode_sz); + + assert(code_n_consts(code) == 2); + assert(code_const_type(code, 0) == TC_REAL); + assert(code_const_type(code, 1) == TC_STRING); + 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(code_n_functions(code) == 2); + + free(bytecode); + } } \ No newline at end of file