From ee989fafa31e10e795ac7acc3c99f666354595d2 Mon Sep 17 00:00:00 2001 From: tema5002 Date: Tue, 9 Jun 2026 20:38:54 +0300 Subject: [PATCH] compiler.c and other minor tweaks --- src/compiler.c | 208 +++++++++++++++++++++++++++++++++++-------------- src/lexer.c | 1 - src/main.c | 4 +- src/vm.c | 41 ++++++++++ src/vm.h | 3 + 5 files changed, 195 insertions(+), 62 deletions(-) diff --git a/src/compiler.c b/src/compiler.c index ed94304..ca400de 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -30,7 +30,7 @@ // ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡘⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ void noomC_compiler_init(noomC_Compiler *compiler) { - compiler->parent = 0; // who is bro 😂✌️🥀 + compiler->parent = 0; compiler->localc = 0; compiler->localcap = 0; @@ -41,47 +41,6 @@ void noomC_compiler_init(noomC_Compiler *compiler) { compiler->constcap = 0; } -noomV_String *noomV_String_alloc(noom_LuaVM *vm, const char *str, const noom_uint_t len) { - noomV_String *s = (noomV_String*)noomV_allocObj(vm, NOOMV_OSTR, sizeof(noomV_String) + len + 1); - if (s == 0) return 0; - noom_memcpy(s->data, str, len); - s->data[len] = '\0'; - return s; -} - -noomV_Function *noomV_Function_alloc(noom_LuaVM *vm, const char *str, const noom_uint_t len) { - noomV_Function *f = (noomV_Function*)noomV_allocObj(vm, NOOMV_OFUNC, sizeof(noomV_Function)); - if (f == 0) return 0; - f->chunkname = noomV_String_alloc(vm, str, len); - if (f->chunkname == 0) return 0; - f->code = 0; - f->consts = 0; - f->protos = 0; - f->upvals = 0; - f->locals = 0; - f->codesize = 0; - f->linedefined = 0; - f->lastlinedefined = 0; - f->argc = 0; - f->flags = 0; - f->constsize = 0; - f->protosize = 0; - f->upvalsize = 0; - f->localsize = 0; - return f; -} - -noomV_Table *noomV_Table_alloc(noom_LuaVM *vm) { - noomV_Table *t = (noomV_Table *)noomV_allocObj(vm, NOOMV_OTABLE, sizeof(noomV_Table)); - if (t == 0) return 0; - t->meta = 0; - t->entries = 0; - t->used = 0; - t->len = 0; - t->entrydata = 0; - return t; -} - static noom_Exit noomC_emit(noomV_Function *func, const noomV_Inst inst) { func->code = noom_realloc(func->code, sizeof(noomV_Inst) * (func->codesize + 1)); if (func->code == 0) return NOOM_ENOMEM; @@ -89,6 +48,10 @@ static noom_Exit noomC_emit(noomV_Function *func, const noomV_Inst inst) { return NOOM_OK; } +static noom_Exit noomC_emit_ABC(noomV_Function *func, const noomV_Opcode op, const unsigned char a, const unsigned char b, const unsigned char c) { + return noomC_emit(func, (noomV_Inst){.op = op, .a = a, .b = b, .c = c}); +} + static noom_Exit noomC_emit_Aus(noomV_Function *func, const noomV_Opcode op, const unsigned char a, const unsigned short us) { return noomC_emit(func, (noomV_Inst){.op = op, .a = a, .us = us}); } @@ -101,44 +64,150 @@ static noom_Exit noomC_addconst(noomV_Function *func, const noomV_Value val) { return NOOM_OK; } +// TODO get rid of these two vvvv static noom_Exit noomC_addconst_nil(noomV_Function *func) { return noomC_addconst(func, (noomV_Value){.tag = NOOMV_VNIL, .autoclose = 0, .isptr = 0}); } - static noom_Exit noomC_addconst_bool(noomV_Function *func, const noom_bool_t b) { return noomC_addconst(func, (noomV_Value){.tag = NOOMV_VBOOL, .autoclose = 0, .isptr = 0, .boolean = b}); } +// yeah ^^^^^^^^^ + +static noom_Exit noomC_addconst_obj(noomV_Function *func, noom_LuaVM *vm, const noomV_ObjTag tag, const noom_uint_t size) { + noomV_Object *obj = noomV_allocObj(vm, tag, size); + if (obj == 0) return NOOM_ENOMEM; + return noomC_addconst(func, (noomV_Value){.tag = NOOMV_VOBJ, .autoclose = 0, .isptr = 0, .obj = obj}); +} + +static noom_Exit noomC_addconst_str(noomV_Function *func, noom_LuaVM *vm, const char *str, const noom_uint_t len) { + noomV_String *s = noomV_allocStr(vm, str, len); + if (s == 0) return NOOM_ENOMEM; + return noomC_addconst(func, (noomV_Value){.tag = NOOMV_VOBJ, .autoclose = 0, .isptr = 0, .obj = (noomV_Object *)s}); +} static noomL_Token noomC_token_at(const noomP_Parser *parser, noom_uint_t offset) { noomL_Token token; noomL_lex(parser->code, offset, &token, parser->version); return token; +} + +// There is a high chance I forgot something here +static noomV_Opcode noomC_what_bop_is_this(const noomP_Parser *parser, noom_uint_t offset) { + // I AM THE LEXER NOW!!!!!!!!! + if (noom_startswith(parser->code + offset, "==")) return NOOMV_INSTR_EQ; + if (noom_startswith(parser->code + offset, "~=")) return NOOMV_INSTR_NEQ; + if (noom_startswith(parser->code + offset, "~=")) return NOOMV_INSTR_LTE; + if (noom_startswith(parser->code + offset, "~=")) return NOOMV_INSTR_GTE; + if (noom_startswith(parser->code + offset, "..")) return NOOMV_INSTR_CONCAT; + + if (parser->version >= NOOM_VERSION_53) { + // Fucking atom forgot to put make an instruction + // update no i am unable to read + if (noom_startswith(parser->code + offset, "//")) return NOOMV_INSTR_FLOOR_DIV; + if (noom_startswith(parser->code + offset, ">>")) return NOOMV_INSTR_RSHIFT; + if (noom_startswith(parser->code + offset, "<<")) return NOOMV_INSTR_LSHIFT; + if (noom_startswith(parser->code + offset, "&")) return NOOMV_INSTR_BAND; + if (noom_startswith(parser->code + offset, "|")) return NOOMV_INSTR_BOR; + if (noom_startswith(parser->code + offset, "~")) return NOOMV_INSTR_BXOR; + } + + if (noom_startswith(parser->code + offset, "+")) return NOOMV_INSTR_ADD; + if (noom_startswith(parser->code + offset, "-")) return NOOMV_INSTR_SUB; + if (noom_startswith(parser->code + offset, "*")) return NOOMV_INSTR_MUL; + if (noom_startswith(parser->code + offset, "/")) return NOOMV_INSTR_DIV; + if (noom_startswith(parser->code + offset, "%")) return NOOMV_INSTR_MOD; + if (noom_startswith(parser->code + offset, "^")) return NOOMV_INSTR_POW; + if (noom_startswith(parser->code + offset, "<")) return NOOMV_INSTR_LT; + if (noom_startswith(parser->code + offset, ">")) return NOOMV_INSTR_GT; } -static noom_Exit noomC_compile_expr(noom_LuaVM *vm, const noomC_Compiler *compiler, const noomP_Parser *parser, noomV_Function *func, const noomP_Node *node) { +// mmap ahh function 🥀🥀🥀🥀🥀🥀🥀 +// What 6 argument syscalls there even are other than mmap and clone and is there anything longer +static noom_Exit noomC_compile_expr( + noom_LuaVM *vm, + noomC_Compiler *compiler, + const noomP_Parser *parser, + noomV_Function *func, + const noomP_Node *node +) { + // Baba is You OST is a very cool soundtrack to code to Can recommend if (node->type == NOOMP_NODE_NILLITERAL) { + unsigned char fucking_destination = compiler->curstack++; + unsigned short fucking_constant = func->constsize; noom_Exit result = noomC_addconst_nil(func); if (result != NOOM_OK) return result; - result = noomC_emit_Aus(func, NOOMV_INSTR_LOADC, compiler->curstack, func->constsize - 1); - if (result != NOOM_OK) return result; - return NOOM_OK; + + return noomC_emit_Aus(func, NOOMV_INSTR_LOADC, fucking_destination, fucking_constant); } if (node->type == NOOMP_NODE_BOOLEANLITERAL) { + unsigned char fucking_destination = compiler->curstack++; + unsigned short fucking_constant = func->constsize; noomL_Token bool_token = noomC_token_at(parser, node->source_offset); noom_bool_t val = noom_memeq(parser->code + bool_token.offset, bool_token.length, "true", 4); noom_Exit result = noomC_addconst_bool(func, val); if (result != NOOM_OK) return result; - result = noomC_emit_Aus(func, NOOMV_INSTR_LOADC, compiler->curstack, func->constsize - 1); - if (result != NOOM_OK) return result; - return NOOM_OK; + + return noomC_emit_Aus(func, NOOMV_INSTR_LOADC, fucking_destination, fucking_constant); } if (node->type == NOOMP_NODE_NUMBERLITERAL) { + unsigned char fucking_destination = compiler->curstack++; return NOOM_PLEASEHELPMEIAMSCARED; // 😭😭😭😭😭😭😭😭 } if (node->type == NOOMP_NODE_STRINGLITERAL) { - return NOOM_IAMNOTSCAREDJUSTLAZYTHISTIME; + unsigned char fucking_destination = compiler->curstack++; + noom_Exit result = noomC_addconst_str(func, vm, "but DID YOU KNOW", 16); + return result; } - return NOOM_EINTERNAL; // Idk what else I forgot + if (node->type == NOOMP_NODE_BINARYOPERATOR) { + unsigned char fucking_destination = compiler->curstack++; + if (node->subnodec != 2) return NOOM_EINTERNAL; + const unsigned char B = compiler->curstack++; + noom_Exit result = noomC_compile_expr(vm, compiler, parser, func, node->subnodes[0]); + if (result != NOOM_OK) return result; + const unsigned char C = compiler->curstack++; + result = noomC_compile_expr(vm, compiler, parser, func, node->subnodes[1]); + if (result != NOOM_OK) return result; + + return noomC_emit_ABC(func, noomC_what_bop_is_this(parser, node->source_offset), fucking_destination, B, C); + } + if (node->type == NOOMP_NODE_CALL) { + unsigned char fucking_destination = compiler->curstack; + // Here we don't fucking increment this fucking destination + // Because the fucking function call fucking increments it fucking anyway + for (int i = 1; i < node->subnodec; i++) { + // push node->subnodes[i] to stack or something + } + return noomC_emit_Aus(func, NOOMV_INSTR_JMP, 0, /* where do i start......... */ 0); + } + if (node->type == NOOMP_NODE_METHODCALL) { + unsigned char fucking_destination = compiler->curstack; + // Here we don't fucking increment this fucking destination + // Because the fucking function call fucking increments it fucking anyway + // push parent value... probably already processed below if you make it i = 0 + for (int i = 1; i < node->subnodec; i++) { + // push node->subnodes[i] to stack or something + } + return noomC_emit_Aus(func, NOOMV_INSTR_JMP, 0, /* where do i start......... */ 0); + } + if (node->type == NOOMP_NODE_GETFIELD) { + unsigned char fucking_destination = compiler->curstack++; + if (node->subnodec != 2) return NOOM_EINTERNAL; + + unsigned char B = compiler->curstack; + noom_Exit result = noomC_compile_expr(vm, compiler, parser, func, node->subnodes[0]); + if (result != NOOM_OK) return result; + + unsigned char C = compiler->curstack; + unsigned short C_constant = func->constsize; + noomL_Token field_token = noomC_token_at(parser, node->subnodes[1]->source_offset); + result = noomC_addconst_str(func, vm, parser->code + field_token.offset, field_token.length); + if (result != NOOM_OK) return result; + result = noomC_emit_Aus(func, NOOMV_INSTR_LOADC, C, C_constant); + if (result != NOOM_OK) return result; + + return noomC_emit_ABC(func, NOOMV_INSTR_GET, fucking_destination, B, C); + } + return NOOM_EINTERNAL; } static noom_Exit noomC_add_stuff_to_function(noom_LuaVM *vm, noomC_Compiler *compiler, const noomP_Parser *parser, noomV_Function *func, const noomP_Node *node); @@ -198,9 +267,10 @@ static noom_Exit noomC_add_stuff_to_function(noom_LuaVM *vm, noomC_Compiler *com if (node->subnodec == 1) { // according to atom this should be nil const unsigned short constptr = func->constsize; - const noom_Exit result = noomC_addconst_nil(func); + noom_Exit result = noomC_addconst_nil(func); + if (result != NOOM_OK) return result; + result = noomC_emit_Aus(func, NOOMV_INSTR_LOADC, destination, constptr); if (result != NOOM_OK) return result; - if (noomC_emit_Aus(func, NOOMV_INSTR_LOADC, destination, constptr) < 0) return NOOM_ENOMEM; } else { const noomP_Node *value_node = node->subnodes[1]; @@ -232,7 +302,7 @@ static noom_Exit noomC_add_stuff_to_function(noom_LuaVM *vm, noomC_Compiler *com if (block_node->type != NOOMP_NODE_BLOCK) return NOOM_EINTERNAL; const noomL_Token name_token = noomC_token_at(parser, varname_node->source_offset); - noomV_Function *proto = noomV_Function_alloc(vm, parser->code + name_token.offset, name_token.length); + noomV_Function *proto = noomV_allocFunc(vm, parser->code + name_token.offset, name_token.length); if (proto == 0) return NOOM_ENOMEM; proto->argc = (unsigned char)params_node->subnodec; @@ -249,9 +319,19 @@ static noom_Exit noomC_add_stuff_to_function(noom_LuaVM *vm, noomC_Compiler *com if (func->protos == 0) return NOOM_ENOMEM; func->protos[func->protosize++] = proto; - // I think something should be here but idfk what - // TODO - noomC_emit_Aus(func, NOOMV_INSTR_NOP, 0, 0); + noomC_Local local; + local.startpc = proto->codesize; + local.endpc = 0; + local.dropped = 0; // FIXME? + local.close = 0; + local.constant = 0; + local.name = noom_strndup(parser->code + varname_node->source_offset, varname_node->source_offset); + + compiler->locals = noom_realloc(compiler->locals, sizeof(noomC_Local) * (compiler->localc + 1)); + if (compiler->locals == 0) return NOOM_ENOMEM; + compiler->locals[compiler->localc++] = local; + // I guess??????? + if (compiler->localc > compiler->localcap) compiler->localcap = compiler->localc; return NOOM_OK; } @@ -272,10 +352,18 @@ static noom_Exit noomC_add_stuff_to_function(noom_LuaVM *vm, noomC_Compiler *com noom_Exit noomC_compile(noom_LuaVM *vm, const noomP_Parser *parser, const noomP_Node *node) { if (node->type != NOOMP_NODE_PROGRAM) return NOOM_EINTERNAL; - noomV_Function* program = noomV_Function_alloc(vm, "main", 4); + noomV_Function* program = noomV_allocFunc(vm, "main", 4); noomC_Compiler compiler; noomC_compiler_init(&compiler); - return noomC_compile_block(vm, &compiler, parser, program, node); + noom_Exit status = noomC_compile_block(vm, &compiler, parser, program, node); + if (status != NOOM_OK) return status; + + if (vm->mainThread->stacklen == vm->mainThread->stackcap) { + vm->mainThread->stackcap = vm->mainThread->stackcap ? vm->mainThread->stackcap * 2 : 16; + vm->mainThread->stack = noom_realloc(vm->mainThread->stack, sizeof(noomV_Value) * vm->mainThread->stackcap); + } + vm->mainThread->stack[vm->mainThread->stacklen++] = + (noomV_Value){.tag = NOOMV_VOBJ, .autoclose = 0, .isptr = 0, .obj = (noomV_Object*)program}; } diff --git a/src/lexer.c b/src/lexer.c index d1c6e22..e0a7947 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -580,7 +580,6 @@ noomL_ErrorType noomL_lex(const char* s, noom_uint_t start, noomL_Token* token, } } - // god damn it we errorrreed return NOOML_ERROR_UNKNOWN; } diff --git a/src/main.c b/src/main.c index 56cca8e..934fd18 100644 --- a/src/main.c +++ b/src/main.c @@ -241,7 +241,9 @@ int main(int argc, char **argv) { } char* code = read_file(params.script_path); if (code == 0) return 1; - return the_theoretical_function_to_execute_your_code_that_should_be_replaced_later(code, argv[0], params.script_path); + int offset = 0; + if (code[0] == '#' && code[1] == '!') for (offset = 2; code[offset] && code[offset] != '\n'; offset++); + return the_theoretical_function_to_execute_your_code_that_should_be_replaced_later(code + offset, argv[0], params.script_path); } if (params.use_stdin) { char* code = read_stdin(); diff --git a/src/vm.c b/src/vm.c index 8fa1e40..35da1cb 100644 --- a/src/vm.c +++ b/src/vm.c @@ -13,6 +13,47 @@ noomV_Object *noomV_allocObj(noom_LuaVM *vm, noomV_ObjTag tag, noom_uint_t size) return o; } +noomV_String *noomV_allocStr(noom_LuaVM *vm, const char *str, noom_uint_t len) { + noomV_String *s = (noomV_String*)noomV_allocObj(vm, NOOMV_OSTR, sizeof(noomV_String) + len + 1); + if (s == 0) return 0; + noom_memcpy(s->data, str, len); + s->data[len] = '\0'; + return s; +} + +noomV_Function *noomV_allocFunc(noom_LuaVM *vm, const char *str, noom_uint_t len) { + noomV_Function *f = (noomV_Function*)noomV_allocObj(vm, NOOMV_OFUNC, sizeof(noomV_Function)); + if (f == 0) return 0; + f->chunkname = noomV_allocStr(vm, str, len); + if (f->chunkname == 0) return 0; + f->code = 0; + f->consts = 0; + f->protos = 0; + f->upvals = 0; + f->locals = 0; + f->codesize = 0; + f->linedefined = 0; + f->lastlinedefined = 0; + f->argc = 0; + f->flags = 0; + f->constsize = 0; + f->protosize = 0; + f->upvalsize = 0; + f->localsize = 0; + return f; +} + +noomV_Table *noomV_allocTable(noom_LuaVM *vm) { + noomV_Table *t = (noomV_Table *)noomV_allocObj(vm, NOOMV_OTABLE, sizeof(noomV_Table)); + if (t == 0) return 0; + t->meta = 0; + t->entries = 0; + t->used = 0; + t->len = 0; + t->entrydata = 0; + return t; +} + void noomV_freeObj(noomV_Object *obj) { noom_free(obj); } diff --git a/src/vm.h b/src/vm.h index 2f623db..059328d 100644 --- a/src/vm.h +++ b/src/vm.h @@ -309,6 +309,9 @@ struct noom_LuaVM { // Allocating objects noomV_Object *noomV_allocObj(noom_LuaVM *vm, noomV_ObjTag tag, noom_uint_t size); +noomV_String *noomV_allocStr(noom_LuaVM *vm, const char *str, noom_uint_t len); +noomV_Function *noomV_allocFunc(noom_LuaVM *vm, const char *str, noom_uint_t len); +noomV_Function *noomV_allocFunc(noom_LuaVM *vm, const char *str, noom_uint_t len); void noomV_freeObj(noomV_Object *obj); #endif