From df889a7a15030d8eb48be20cba4fa698feff1ed5 Mon Sep 17 00:00:00 2001 From: tema5002 Date: Mon, 22 Jun 2026 17:54:46 +0300 Subject: [PATCH 1/4] Random changes with varying usefulness --- src/compiler.c | 10 +--- src/error.c | 14 ++--- src/helper.c | 119 +++++++++++++++++++++++++++++++++++++- src/helper.h | 7 ++- src/lexer.c | 13 ++++- src/lexer.h | 2 + src/main.c | 152 ++++++++++++++++++++++++++++++------------------- src/noom.h | 8 ++- 8 files changed, 244 insertions(+), 81 deletions(-) diff --git a/src/compiler.c b/src/compiler.c index dbd63f3..6ae1c36 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -30,9 +30,7 @@ // ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡘⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ typedef struct noomC_LocalInfo { - enum { NOOMC_GLOBAL, - NOOMC_LOCAL, - NOOMC_UPVAL } type; + enum { NOOMC_GLOBAL, NOOMC_LOCAL, NOOMC_UPVAL } type; unsigned int idx; } noomC_LocalInfo; @@ -141,8 +139,6 @@ static noom_BinOp noomC_what_bop_is_this(const noomP_Parser* parser, noom_uint_t // no .., that is special cased due to funky behavior if (parser->version >= NOOM_VERSION_53) { - // Fucking atom forgot to put make an instruction - // update no i am unable to read if (noom_startswith(op, "//")) return NOOM_BIN_IDIV; if (noom_startswith(op, ">>")) return NOOM_BIN_BSHIFTR; if (noom_startswith(op, "<<")) return NOOM_BIN_BSHIFTL; @@ -169,9 +165,9 @@ static noom_Exit noomC_compile_expr( noomV_Function* func, const noomP_Node* node, // retc of -1 means all values!!!!!!!!!!! - int retc) { + int retc +) { noom_Exit result; - // Baba is You OST is a very cool soundtrack to code to Can recommend if (node->type == NOOMP_NODE_NILLITERAL) { compiler->curstack++; // TODO: analyze last instruction to optimize automatically diff --git a/src/error.c b/src/error.c index e7ffba4..4089e4a 100644 --- a/src/error.c +++ b/src/error.c @@ -42,8 +42,6 @@ noom_uint_t noom_format_error(const noomP_Parser* parser, const char* program_na [NOOMP_ERROR_EXPECTED_IDENTIFIER_AFTER_GOTO] = {"expected identifier after goto\n", 0}, [NOOMP_ERROR_EXPECTED_COLONCOLON] = {"expected :: to end label identifier", 1}, [NOOMP_ERROR_INVALID_STATEMENT] = {"expected statement, got", 2}, - // I want someone smarter than me [tema5002] to give these a proper description - // ^ alrighty then [NOOMP_ERROR_EXPECTED_ASSIGNABLE] = {"expected assignable expression after comma in assignment", 1}, [NOOMP_ERROR_NOT_ASSIGNABLE] = {"expression in assignment is not assignable", 1}, [NOOMP_ERROR_EXPECTED_COMMA_OR_EQUAL_IN_ASSIGNMENT] = {"expected a comma or equals after assignable in assignment", 1}, @@ -77,14 +75,15 @@ noom_uint_t noom_format_error(const noomP_Parser* parser, const char* program_na lexer_code = parser->error_state & ~NOOMP_ERROR_LEXER; } - struct noom_error err = (base_err == NOOMP_ERROR_LEXER) ? lexer_errors[lexer_code] : parser_errors[base_err]; + struct noom_error err = base_err == NOOMP_ERROR_LEXER ? lexer_errors[lexer_code] : parser_errors[base_err]; noom_uint_t row = 1, column = 1; for (noom_uint_t i = 0; i < parser->lex_offset; i++) { if (parser->code[i] == '\n') { row++; column = 1; - } else { + } + else { column++; } } @@ -105,7 +104,7 @@ noom_uint_t noom_format_error(const noomP_Parser* parser, const char* program_na linedig + sizeof(": ") - 1 + noom_strlen(err.s) + - +1; // \0; + 1; // \0; if (err.near) space += (err.near == 1 ? sizeof(" near") - 1 : 0) + @@ -128,12 +127,13 @@ noom_uint_t noom_format_error(const noomP_Parser* parser, const char* program_na if (row == 0) { num_buf[num_len++] = '0'; - } else { + } + else { noom_uint_t temp = row; noom_uint_t divisor = 1; while (temp / divisor >= 10) divisor *= 10; while (divisor > 0) { - num_buf[num_len++] = '0' + (temp / divisor); + num_buf[num_len++] = (char)(temp / divisor + '0'); temp %= divisor; divisor /= 10; } diff --git a/src/helper.c b/src/helper.c index 3f58bd0..5ad46b1 100644 --- a/src/helper.c +++ b/src/helper.c @@ -1,7 +1,115 @@ #include "helper.h" - +#include "lexer.h" #include "noom.h" +double noom_strtod(const char* s, const char** endptr, int* error) { + // Num???? Is that a fucking noom reference??????? + double num = 0.0; + + int error_but_different = 1; + + const noom_bool_t negative = *s == '-'; + if (*s == '-' || *s == '+') + s++; + + if (!noomL_isnumber(s[*s == '.'])) goto fuck; + + if (*s == '0' && noomL_lower(s[1]) == 'x') { + s += 2; + // if the string starts with "0x" but does not contain digits it's invalid + noom_bool_t are_we_cooked = 1; + while (noomL_ishex(*s)) { + int digit; + if (noomL_isnumber(*s)) digit = *s - '0'; + else digit = noomL_lower(*s) - 'a' + 10; + + num = num * 16.0 + digit; + are_we_cooked = 0; + s++; + } + + if (are_we_cooked) goto fuck; + + if (noomL_lower(*s) == 'p') { + // damn then + s++; + int exponent = 0; + const noom_bool_t exponent_negative = *s == '-'; + if (*s == '-' || *s == '+') + s++; + + if (!noomL_isnumber(*s)) goto fuck; + + while (noomL_isnumber(*s)) { + exponent = exponent * 10 + (*s - '0'); + s++; + } + + num *= noom_pow(2.0, exponent_negative ? -exponent : exponent); + } + } + else { + noom_bool_t are_we_cooked = 1; + while (noomL_isnumber(*s)) { + num = num * 10.0 + (*s - '0'); + are_we_cooked = 0; + s++; + } + if (*s == '.') { + s++; + + double fraction_divisor = 10.0; + while (noomL_isnumber(*s)) { + are_we_cooked = 0; + num += (double)(*s - '0') / fraction_divisor; + fraction_divisor *= 10.0; + s++; + } + } + if (are_we_cooked) goto fuck; + + if (noomL_lower(*s) == 'e') { + s++; + int exponent = 0; + const noom_bool_t exponent_negative = *s == '-'; + if (*s == '-' || *s == '+') + s++; + + if (!noomL_isnumber(*s)) goto fuck; + + while (noomL_isnumber(*s)) { + exponent = exponent * 10 + (*s - '0'); + s++; + } + + num *= noom_pow(10.0, exponent_negative ? -exponent : exponent); + } + } + + error_but_different = 0; +fuck: + if (endptr) *endptr = s; + if (error) *error = error_but_different; + return negative ? -num : num; +} + +// made by some stranger on stack overflow +double noom_pow(double x, int y) { + if (y == 0) + return 1; + + const double temp = noom_pow(x, y / 2); + + if (y % 2 == 0) { + return temp * temp; + } + + if (y > 0) + return x * temp * temp; + + return temp * temp / x; +} + int noom_startswith(const char* str, const char* compare) { #ifdef __has_builtin #if __has_builtin(__builtin_strncmp) @@ -90,3 +198,12 @@ void noom_free(void* ptr) { void* noom_realloc(void* ptr, noom_uint_t size) { return realloc(ptr, size); } + +void* noom_realloc_free(void* ptr, noom_uint_t size) { + void* newptr = noom_realloc(ptr, size); + if (newptr == 0) { + noom_free(ptr); + return 0; + } + return newptr; +} diff --git a/src/helper.h b/src/helper.h index 91f19f2..00f49fe 100644 --- a/src/helper.h +++ b/src/helper.h @@ -2,15 +2,20 @@ #define NOOM_USHORT_MAX 0xffff +// isn't quite strtod, is it +// doesn't skip whitespace unlike actual C stdlib strtod!!!! +double noom_strtod(const char* s, const char** endptr, int* error); +double noom_pow(double x, int y); + int noom_startswith(const char* str, const char* compare); int noom_memeq(const char* stra, noom_uint_t lena, const char* strb, noom_uint_t lenb); noom_uint_t noom_strlen(const char* s); int noom_strcmp(const char* a, const char* b); void noom_safe_strcpy(char* buffer, noom_uint_t* pos, noom_uint_t buffer_size, const char* src); char* noom_strndup(const char* s, noom_uint_t len); - void noom_memcpy(void* dst, const void* src, noom_uint_t n); void* noom_alloc(noom_uint_t size); void noom_free(void* ptr); void* noom_realloc(void* ptr, noom_uint_t size); +void *noom_realloc_free(void* ptr, noom_uint_t size); diff --git a/src/lexer.c b/src/lexer.c index cfe27e7..08c7cce 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -29,6 +29,14 @@ int noomL_ishex(char c) { return noomL_isnumber(c) || (noomL_lower(c) >= 'a' && noomL_lower(c) <= 'f'); } +int noomL_is_ident_start(char c) { + return noomL_isalpha(c) || c == '_'; +} + +int noomL_is_ident_continue(char c) { + return noomL_isalphanum(c) || c == '_'; +} + noom_uint_t noomL_getsymbol(const char* s, noom_LuaVersion version) { // TODO: maybe find some less shit crap holy crap if (noom_startswith(s, "...")) return 3; @@ -514,10 +522,9 @@ noomL_ErrorType noomL_lex(const char* s, noom_uint_t start, noomL_Token* token, return NOOML_ERROR_NONE; } - if (str[0] == '_' || noomL_isalpha(str[0])) { // TODO: maybe abstract into function for "can start ident"? + if (noomL_is_ident_start(str[0])) { noom_uint_t len = 1; - while (str[len] == '_' || noomL_isalphanum(str[len])) // same here - len++; + while (noomL_is_ident_continue(str[len])) len++; token->type = NOOML_TOKEN_IDENTIFIER; if (noomL_iskeyword(str, len, version)) token->type = NOOML_TOKEN_KEYWORD; diff --git a/src/lexer.h b/src/lexer.h index 18757fb..387925f 100644 --- a/src/lexer.h +++ b/src/lexer.h @@ -44,6 +44,8 @@ int noomL_isalphanum(char c); int noomL_iswhitespace(char c); int noomL_lower(char c); int noomL_ishex(char c); +int noomL_is_ident_start(char c); +int noomL_is_ident_continue(char c); noom_uint_t noomL_getsymbol(const char* s, noom_LuaVersion version); noom_uint_t noomL_getnumber(const char* s, noomL_ErrorType* error, noom_LuaVersion version); diff --git a/src/main.c b/src/main.c index 027f1b5..1def51b 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,4 @@ #include // for now -#include #include "helper.h" #include "error.h" #include "noom.h" @@ -16,7 +15,7 @@ void tab(noom_uint_t amount) { } } -void print_node(const noomP_Node* node, noom_uint_t depth) { +void print_node(const noomP_Node *node, noom_uint_t depth) { tab(depth); printf("{\n"); @@ -37,14 +36,12 @@ void print_node(const noomP_Node* node, noom_uint_t depth) { printf("}\n"); } -int the_theoretical_function_to_execute_your_code_that_should_be_replaced_later(const char* code, const char* program_name, const char* filename) { +int execute(const char* code, noom_LuaVersion version, const char* program_name, const char* filename) { noomP_Parser parser; noomP_Node* program; - - noom_LuaVM* vm = noom_createVM(NOOM_VERSION_51); - + // goodbye "shitass" you will be missed - int success = noomP_parse(code, filename, NOOM_VERSION_51, &program, &parser); + int success = noomP_parse(code, filename, version, &program, &parser); if (success == 0) { puts("LEX OUTPUT:"); fputs("\x1b[48;2;10;10;10m", stdout); @@ -52,7 +49,7 @@ int the_theoretical_function_to_execute_your_code_that_should_be_replaced_later( while (1) { noomL_Token token; - noomL_ErrorType err = noomL_lex(code, pos, &token, NOOM_VERSION_54); + noomL_ErrorType err = noomL_lex(code, pos, &token, version); if (err) break; if (token.type == NOOML_TOKEN_KEYWORD) { @@ -87,46 +84,15 @@ int the_theoretical_function_to_execute_your_code_that_should_be_replaced_later( puts("\x1b[0m"); puts("PARSE OUTPUT:"); print_node(program, 0); - } else { + } + else { noom_uint_t bleh = noom_format_error(&parser, program_name, NULL, 0); char* buf = noom_alloc(bleh); noom_format_error(&parser, program_name, buf, bleh); fputs(buf, stdout); noom_free(buf); } - - noomV_Value peak; - - noom_Exit e = noomC_compile(vm, &parser, program, 0, 0, &peak); - if (e) { - printf("error: %d\n", e); - exit(e); - } - - noomV_Function* f = (noomV_Function*)peak.obj; - - for (int i = 0; i < f->codesize; i++) { - noomV_Inst inst = f->code[i]; - noomV_DisInfo dis = noomV_disInfo[inst.op]; - - printf("%s %d ", dis.name, inst.a); - - switch (dis.arg) { - case NOOMV_DIS_NONE: - break; - case NOOMV_DIS_BC: - printf("%d, %d", inst.b, inst.c); - break; - case NOOMV_DIS_uD: - printf("%d", inst.us); - break; - case NOOMV_DIS_sD: - printf("%d", inst.ss); - break; - } - printf("\n"); - } - + // freeing time noomP_Node* last_node = parser.last_node; while (last_node) { @@ -136,9 +102,43 @@ int the_theoretical_function_to_execute_your_code_that_should_be_replaced_later( noom_free(last_node); last_node = next; } + + if (success) { + noom_LuaVM* vm = noom_createVM(version); + noomV_Value peak; - noom_destroyVM(vm); + noom_Exit e = noomC_compile(vm, &parser, program, 0, 0, &peak); + if (e) { + printf("error: %d\n", e); + return 1; + } + noomV_Function* f = (noomV_Function*)peak.obj; + + for (int i = 0; i < f->codesize; i++) { + noomV_Inst inst = f->code[i]; + noomV_DisInfo dis = noomV_disInfo[inst.op]; + + printf("%s %d ", dis.name, inst.a); + + switch (dis.arg) { + case NOOMV_DIS_NONE: + break; + case NOOMV_DIS_BC: + printf("%d, %d", inst.b, inst.c); + break; + case NOOMV_DIS_uD: + printf("%d", inst.us); + break; + case NOOMV_DIS_sD: + printf("%d", inst.ss); + break; + } + printf("\n"); + } + noom_destroyVM(vm); + } + return success; } @@ -154,9 +154,11 @@ static char* read_file(const char* filename) { fseek(file, 0, SEEK_SET); char* buffer = noom_alloc(filesize + 1); + if (buffer == 0) return 0; if (fread(buffer, 1, filesize, file) != filesize) { fprintf(stderr, "Reached the end of the file\n"); + noom_free(buffer); return 0; } buffer[filesize] = '\0'; @@ -169,13 +171,15 @@ static char* read_stdin() { noom_uint_t capacity = 4096; noom_uint_t size = 0; char* buffer = noom_alloc(capacity); + if (buffer == 0) return 0; size_t n; while ((n = fread(buffer + size, 1, capacity - size, stdin)) > 0) { size += n; if (size == capacity) { capacity *= 2; - buffer = noom_realloc(buffer, capacity); + buffer = noom_realloc_free(buffer, capacity); + if (buffer == 0) return 0; } } @@ -183,7 +187,6 @@ static char* read_stdin() { return buffer; } -// code stolen from my different project static int read_prompt(char* buf, int buf_size, char* prompt, const int required) { do { printf("%s", prompt); @@ -207,6 +210,7 @@ int main(int argc, char** argv) { const char* script_exec; const char* script_path; noom_bool_t do_i_already_know_what_to_do; + noom_LuaVersion lua_version; } params = {0}; if (argc < 2) { @@ -246,7 +250,7 @@ int main(int argc, char** argv) { if (params.do_i_already_know_what_to_do) { goto die; } - /* "-estat" or "-e stat" */ + // "-estat" or "-e stat" if (argv[i][2] != '\0') { params.script_exec = argv[i] + 2; params.do_i_already_know_what_to_do = 1; @@ -260,6 +264,29 @@ int main(int argc, char** argv) { params.script_exec = argv[i]; params.do_i_already_know_what_to_do = 1; } + + if (argv[i][1] == 'l') { + const char* version_string = 0; + if (argv[i][2] != '\0') { + version_string = argv[i] + 2; + } + else { + if (++i >= argc) { + err = "-l needs an argument"; + goto die; + } + version_string = argv[i]; + } + if (noom_strcmp(version_string, "51") == 0) params.lua_version = NOOM_VERSION_51; + else if (noom_strcmp(version_string, "52") == 0) params.lua_version = NOOM_VERSION_52; + else if (noom_strcmp(version_string, "53") == 0) params.lua_version = NOOM_VERSION_53; + else if (noom_strcmp(version_string, "54") == 0) params.lua_version = NOOM_VERSION_54; + else { + err = "unknown lua version"; + goto die; + } + continue; + } if (argv[i][1] == 'v') { puts(NOOM_VERSION_TEXT); @@ -269,27 +296,33 @@ int main(int argc, char** argv) { err = "unknown option"; goto die; } + if (params.lua_version != 0) { + params.lua_version = NOOM_VERSION_54; + if (!params.do_i_already_know_what_to_do) { + params.enter_repl = 1; + params.do_i_already_know_what_to_do = 1; + } + } if (!params.do_i_already_know_what_to_do) { err = "script not set"; goto die; } if (params.script_exec || params.script_path) { if (params.script_exec) { - return the_theoretical_function_to_execute_your_code_that_should_be_replaced_later(params.script_exec, argv[0], "(command line)"); + return execute(params.script_exec, params.lua_version, argv[0], "(command line)"); } char* code = read_file(params.script_path); if (code == 0) return 1; int offset = 0; - if (code[0] == '#' && code[1] == '!') - for (offset = 2; code[offset] && code[offset] != '\n'; offset++); - int e = the_theoretical_function_to_execute_your_code_that_should_be_replaced_later(code + offset, argv[0], params.script_path); + if (code[0] == '#' && code[1] == '!') for (offset = 2; code[offset] && code[offset] != '\n'; offset++); + const int e = execute(code + offset, params.lua_version, argv[0], params.script_path); noom_free(code); return e; } if (params.use_stdin) { char* code = read_stdin(); if (code == 0) return 1; - int e = the_theoretical_function_to_execute_your_code_that_should_be_replaced_later(code, argv[0], "stdin"); + const int e = execute(code, params.lua_version, argv[0], "stdin"); noom_free(code); return e; } @@ -298,18 +331,17 @@ int main(int argc, char** argv) { for (;;) { char code[4096]; if (read_prompt(code, sizeof(code), "> ", 1)) return 0; - the_theoretical_function_to_execute_your_code_that_should_be_replaced_later(code, 0, "(noom input)"); + execute(code, params.lua_version, 0, "(noom input)"); } } die: fprintf(stderr, "%s: %s\n" - "usage: %s [options] [script [args]]\n" - "Available options are:\n" - " - execute stdin\n" - " -e stat execute string 'stat'\n" - " -v show version\n", - argv[0], - err, - argv[0]); + "usage: %s [options] [script [args]]\n" + "Available options are:\n" + " - execute stdin\n" + " -e stat execute string 'stat'\n" + " -v show version\n" + " -l [51|52|53|54] select lua version\n", + argv[0], err, argv[0]); return 1; } diff --git a/src/noom.h b/src/noom.h index 6fa44e8..130d8f8 100644 --- a/src/noom.h +++ b/src/noom.h @@ -4,15 +4,19 @@ #define NN_STR(x) #x #define NN_XSTR(x) NN_STR(x) +/* #define NOOM_VERSION_MAJOR 0 #define NOOM_VERSION_MINOR 0 #define NOOM_VERSION_PATCH 0 -#if NOOM_VERSION_PATCH == 0 +#if NOOM_VERSION_PATCH==0 #define NOOM_VERSION_FULL NN_XSTR(NOOM_VERSION_MAJOR) "." NN_XSTR(NOOM_VERSION_MINOR) #else #define NOOM_VERSION_FULL NN_XSTR(NOOM_VERSION_MAJOR) "." NN_XSTR(NOOM_VERSION_MINOR) "." NN_XSTR(NOOM_VERSION_PATCH) #endif -#define NOOM_VERSION_TEXT "Noom " NOOM_VERSION_FULL " (C) 2026 NeoFlock and Noom contributors" +*/ +#define NOOM_VERSION_FULL "development build" + +#define NOOM_VERSION_TEXT "Noom " NOOM_VERSION_FULL " (c) 2026 NeoFlock and Noom contributors" #ifdef __cplusplus extern "C" { -- 2.49.1 From d049b65292542c0be457e62fa913eae87107cee1 Mon Sep 17 00:00:00 2001 From: tema5002 Date: Mon, 22 Jun 2026 17:56:13 +0300 Subject: [PATCH 2/4] :> --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 1def51b..fc928bb 100644 --- a/src/main.c +++ b/src/main.c @@ -15,7 +15,7 @@ void tab(noom_uint_t amount) { } } -void print_node(const noomP_Node *node, noom_uint_t depth) { +void print_node(const noomP_Node* node, noom_uint_t depth) { tab(depth); printf("{\n"); -- 2.49.1 From c767c0de242ac9c46d3a0d9bbd69c3c37b0cfcb9 Mon Sep 17 00:00:00 2001 From: tema5002 Date: Mon, 22 Jun 2026 18:02:53 +0300 Subject: [PATCH 3/4] :< --- src/compiler.c | 7 ++++--- src/error.c | 6 ++---- src/helper.c | 35 +++++++++++++++++------------------ src/main.c | 35 +++++++++++++++++------------------ 4 files changed, 40 insertions(+), 43 deletions(-) diff --git a/src/compiler.c b/src/compiler.c index 6ae1c36..aa16cd9 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -30,7 +30,9 @@ // ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡘⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ typedef struct noomC_LocalInfo { - enum { NOOMC_GLOBAL, NOOMC_LOCAL, NOOMC_UPVAL } type; + enum { NOOMC_GLOBAL, + NOOMC_LOCAL, + NOOMC_UPVAL } type; unsigned int idx; } noomC_LocalInfo; @@ -165,8 +167,7 @@ static noom_Exit noomC_compile_expr( noomV_Function* func, const noomP_Node* node, // retc of -1 means all values!!!!!!!!!!! - int retc -) { + int retc) { noom_Exit result; if (node->type == NOOMP_NODE_NILLITERAL) { compiler->curstack++; diff --git a/src/error.c b/src/error.c index 4089e4a..fa64b6d 100644 --- a/src/error.c +++ b/src/error.c @@ -82,8 +82,7 @@ noom_uint_t noom_format_error(const noomP_Parser* parser, const char* program_na if (parser->code[i] == '\n') { row++; column = 1; - } - else { + } else { column++; } } @@ -127,8 +126,7 @@ noom_uint_t noom_format_error(const noomP_Parser* parser, const char* program_na if (row == 0) { num_buf[num_len++] = '0'; - } - else { + } else { noom_uint_t temp = row; noom_uint_t divisor = 1; while (temp / divisor >= 10) divisor *= 10; diff --git a/src/helper.c b/src/helper.c index 5ad46b1..c251198 100644 --- a/src/helper.c +++ b/src/helper.c @@ -13,7 +13,7 @@ double noom_strtod(const char* s, const char** endptr, int* error) { s++; if (!noomL_isnumber(s[*s == '.'])) goto fuck; - + if (*s == '0' && noomL_lower(s[1]) == 'x') { s += 2; // if the string starts with "0x" but does not contain digits it's invalid @@ -22,14 +22,14 @@ double noom_strtod(const char* s, const char** endptr, int* error) { int digit; if (noomL_isnumber(*s)) digit = *s - '0'; else digit = noomL_lower(*s) - 'a' + 10; - + num = num * 16.0 + digit; are_we_cooked = 0; s++; } - + if (are_we_cooked) goto fuck; - + if (noomL_lower(*s) == 'p') { // damn then s++; @@ -37,18 +37,17 @@ double noom_strtod(const char* s, const char** endptr, int* error) { const noom_bool_t exponent_negative = *s == '-'; if (*s == '-' || *s == '+') s++; - + if (!noomL_isnumber(*s)) goto fuck; - + while (noomL_isnumber(*s)) { exponent = exponent * 10 + (*s - '0'); s++; } - + num *= noom_pow(2.0, exponent_negative ? -exponent : exponent); } - } - else { + } else { noom_bool_t are_we_cooked = 1; while (noomL_isnumber(*s)) { num = num * 10.0 + (*s - '0'); @@ -57,7 +56,7 @@ double noom_strtod(const char* s, const char** endptr, int* error) { } if (*s == '.') { s++; - + double fraction_divisor = 10.0; while (noomL_isnumber(*s)) { are_we_cooked = 0; @@ -67,21 +66,21 @@ double noom_strtod(const char* s, const char** endptr, int* error) { } } if (are_we_cooked) goto fuck; - + if (noomL_lower(*s) == 'e') { s++; int exponent = 0; const noom_bool_t exponent_negative = *s == '-'; if (*s == '-' || *s == '+') s++; - + if (!noomL_isnumber(*s)) goto fuck; - + while (noomL_isnumber(*s)) { exponent = exponent * 10 + (*s - '0'); s++; } - + num *= noom_pow(10.0, exponent_negative ? -exponent : exponent); } } @@ -99,16 +98,16 @@ double noom_pow(double x, int y) { return 1; const double temp = noom_pow(x, y / 2); - + if (y % 2 == 0) { return temp * temp; } - + if (y > 0) return x * temp * temp; - + return temp * temp / x; -} +} int noom_startswith(const char* str, const char* compare) { #ifdef __has_builtin diff --git a/src/main.c b/src/main.c index fc928bb..f913037 100644 --- a/src/main.c +++ b/src/main.c @@ -39,7 +39,7 @@ void print_node(const noomP_Node* node, noom_uint_t depth) { int execute(const char* code, noom_LuaVersion version, const char* program_name, const char* filename) { noomP_Parser parser; noomP_Node* program; - + // goodbye "shitass" you will be missed int success = noomP_parse(code, filename, version, &program, &parser); if (success == 0) { @@ -84,15 +84,14 @@ int execute(const char* code, noom_LuaVersion version, const char* program_name, puts("\x1b[0m"); puts("PARSE OUTPUT:"); print_node(program, 0); - } - else { + } else { noom_uint_t bleh = noom_format_error(&parser, program_name, NULL, 0); char* buf = noom_alloc(bleh); noom_format_error(&parser, program_name, buf, bleh); fputs(buf, stdout); noom_free(buf); } - + // freeing time noomP_Node* last_node = parser.last_node; while (last_node) { @@ -102,7 +101,7 @@ int execute(const char* code, noom_LuaVersion version, const char* program_name, noom_free(last_node); last_node = next; } - + if (success) { noom_LuaVM* vm = noom_createVM(version); noomV_Value peak; @@ -138,7 +137,7 @@ int execute(const char* code, noom_LuaVersion version, const char* program_name, } noom_destroyVM(vm); } - + return success; } @@ -264,19 +263,18 @@ int main(int argc, char** argv) { params.script_exec = argv[i]; params.do_i_already_know_what_to_do = 1; } - + if (argv[i][1] == 'l') { const char* version_string = 0; if (argv[i][2] != '\0') { version_string = argv[i] + 2; - } - else { + } else { if (++i >= argc) { err = "-l needs an argument"; goto die; } version_string = argv[i]; - } + } if (noom_strcmp(version_string, "51") == 0) params.lua_version = NOOM_VERSION_51; else if (noom_strcmp(version_string, "52") == 0) params.lua_version = NOOM_VERSION_52; else if (noom_strcmp(version_string, "53") == 0) params.lua_version = NOOM_VERSION_53; @@ -314,7 +312,8 @@ int main(int argc, char** argv) { char* code = read_file(params.script_path); if (code == 0) return 1; int offset = 0; - if (code[0] == '#' && code[1] == '!') for (offset = 2; code[offset] && code[offset] != '\n'; offset++); + if (code[0] == '#' && code[1] == '!') + for (offset = 2; code[offset] && code[offset] != '\n'; offset++); const int e = execute(code + offset, params.lua_version, argv[0], params.script_path); noom_free(code); return e; @@ -336,12 +335,12 @@ int main(int argc, char** argv) { } die: fprintf(stderr, "%s: %s\n" - "usage: %s [options] [script [args]]\n" - "Available options are:\n" - " - execute stdin\n" - " -e stat execute string 'stat'\n" - " -v show version\n" - " -l [51|52|53|54] select lua version\n", - argv[0], err, argv[0]); + "usage: %s [options] [script [args]]\n" + "Available options are:\n" + " - execute stdin\n" + " -e stat execute string 'stat'\n" + " -v show version\n" + " -l [51|52|53|54] select lua version\n", + argv[0], err, argv[0]); return 1; } -- 2.49.1 From 4107afb842cfdc1581dc2ccbdc28ce3267f23ef7 Mon Sep 17 00:00:00 2001 From: tema5002 Date: Mon, 22 Jun 2026 18:10:36 +0300 Subject: [PATCH 4/4] Compiling and shitting --- src/compiler.c | 55 +++++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/src/compiler.c b/src/compiler.c index aa16cd9..ae4b60d 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -87,7 +87,7 @@ static noom_Exit noomC_emit_ABC(noomV_Function* func, const noomV_Opcode op, con 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) { +static noom_Exit noomC_emit_AuD(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}); } @@ -122,6 +122,10 @@ static noom_Exit noomC_addconst_str(noomC_Compiler* c, noom_LuaVM* vm, const cha return noomC_addconst(c->target, (noomV_Value){.tag = NOOMV_VOBJ, .autoclose = 0, .isptr = 0, .obj = (noomV_Object*)s}); } +static noom_Exit noomC_addconst_num(noomC_Compiler *c, noom_LuaVM *vm, double num) { + // TODO :( +} + 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); @@ -171,27 +175,35 @@ static noom_Exit noomC_compile_expr( noom_Exit result; if (node->type == NOOMP_NODE_NILLITERAL) { compiler->curstack++; - // TODO: analyze last instruction to optimize automatically - return noomC_emit_Aus(func, NOOMV_INSTR_PUSHNIL, 0, 0); + if (func->codesize > 0 && func->code[func->codesize - 1].op == NOOMV_INSTR_PUSHNIL) { + func->code[func->codesize - 1].us++; + } + else { + if ((result = noomC_emit_AuD(func, NOOMV_INSTR_PUSHNIL, 0, 0)) != NOOM_OK) return result; + } + return noomC_emit_AuD(func, NOOMV_INSTR_PUSHNIL, 0, 0); } if (node->type == NOOMP_NODE_BOOLEANLITERAL) { - unsigned char fucking_destination = compiler->curstack++; + unsigned char where = 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); // TODO: analyze last instruction to optimize automatically - return noomC_emit_Aus(func, NOOMV_INSTR_PUSHBOOLS, 0, val ? 1 : 0); - } + return noomC_emit_AuD(func, NOOMV_INSTR_PUSHBOOLS, 0, val ? 1 : 0); + } if (node->type == NOOMP_NODE_NUMBERLITERAL) { unsigned char fucking_destination = compiler->curstack++; - return NOOM_PLEASEHELPMEIAMSCARED; // 😭😭😭😭😭😭😭😭 - } + noomL_Token number_token = noomC_token_at(parser, node->source_offset); + double val = noom_strtod(parser->code + number_token.offset, 0, 0); + if ((result = noomC_addconst_num(compiler, vm, val)) != NOOM_OK) return result; + return noomC_emit_AuD(func, NOOMV_INSTR_PUSHCONST, 0, fucking_destination); + } if (node->type == NOOMP_NODE_STRINGLITERAL) { compiler->curstack++; unsigned char fucking_destination = func->constsize; noom_Exit result = noomC_addconst_str(compiler, vm, "but DID YOU KNOW", 16); if (result) return result; - return noomC_emit_Aus(func, NOOMV_INSTR_PUSHCONST, 0, fucking_destination); + return noomC_emit_AuD(func, NOOMV_INSTR_PUSHCONST, 0, fucking_destination); } if (node->type == NOOMP_NODE_BINARYOPERATOR) { if (node->subnodec != 2) return NOOM_EINTERNAL; @@ -218,7 +230,7 @@ static noom_Exit noomC_compile_expr( } compiler->curstack -= amount; compiler->curstack++; - return noomC_emit_Aus(func, NOOMV_INSTR_CONCAT, 0, amount - 1); + return noomC_emit_AuD(func, NOOMV_INSTR_CONCAT, 0, amount - 1); } if ((result = noomC_compile_expr(vm, compiler, parser, func, node->subnodes[0], 1))) return result; @@ -239,13 +251,13 @@ static noom_Exit noomC_compile_expr( noom_uint_t fieldlen = noomL_tokenlen(fieldname, 0, parser->version); noom_uint_t constidx = func->constsize; if ((result = noomC_addconst_str(compiler, vm, fieldname, fieldlen))) return result; - if ((result = noomC_emit_Aus(func, NOOMV_INSTR_GETMETHOD, 0, constidx))) return result; + if ((result = noomC_emit_AuD(func, NOOMV_INSTR_GETMETHOD, 0, constidx))) return result; } for (int i = isMethod ? 2 : 1; i < node->subnodec; i++) { noom_bool_t isLast = i == (node->subnodec - 1); if ((result = noomC_compile_expr(vm, compiler, parser, func, node->subnodes[i], isLast ? -1 : 1))) return result; } - return noomC_emit_Aus(func, NOOMV_INSTR_CALL, funcIdx, retc + 1); + return noomC_emit_AuD(func, NOOMV_INSTR_CALL, funcIdx, retc + 1); } if (node->type == NOOMP_NODE_VARIABLE) { noomC_LocalInfo info; @@ -256,14 +268,14 @@ static noom_Exit noomC_compile_expr( switch (info.type) { case NOOMC_LOCAL: - return noomC_emit_Aus(func, NOOMV_INSTR_PUSHVAL, 0, info.idx); + return noomC_emit_AuD(func, NOOMV_INSTR_PUSHVAL, 0, info.idx); case NOOMC_UPVAL: - return noomC_emit_Aus(func, NOOMV_INSTR_PUSHUPVAL, 0, info.idx); + return noomC_emit_AuD(func, NOOMV_INSTR_PUSHUPVAL, 0, info.idx); case NOOMC_GLOBAL: { noom_uint_t constidx = compiler->target->constsize; if ((result = noomC_addconst_str(compiler, vm, varname, namelen))) return result; if (parser->version == NOOM_VERSION_51) { - return noomC_emit_Aus(func, NOOMV_INSTR_PUSHGLOBAL, 0, constidx); + return noomC_emit_AuD(func, NOOMV_INSTR_PUSHGLOBAL, 0, constidx); } noomC_LocalInfo _ENV; if ((result = noomC_identifyLocal(compiler, &_ENV, "_ENV", 4))) return result; @@ -271,11 +283,11 @@ static noom_Exit noomC_compile_expr( if (_ENV.type == NOOMC_GLOBAL) return NOOM_EINTERNAL; // most likely branch in human history if (_ENV.type == NOOMC_UPVAL) { - return noomC_emit_Aus(func, NOOMV_INSTR_PUSHUPVAL, _ENV.idx, constidx); + return noomC_emit_AuD(func, NOOMV_INSTR_PUSHUPVAL, _ENV.idx, constidx); } // bitchass - if ((result = noomC_emit_Aus(func, NOOMV_INSTR_PUSHVAL, 0, _ENV.idx))) return result; - return noomC_emit_Aus(func, NOOMV_INSTR_GETFIELD, 0, constidx); + if ((result = noomC_emit_AuD(func, NOOMV_INSTR_PUSHVAL, 0, _ENV.idx))) return result; + return noomC_emit_AuD(func, NOOMV_INSTR_GETFIELD, 0, constidx); } } // forgot a case @@ -302,10 +314,11 @@ static noom_Exit noomC_compile_block(noom_LuaVM* vm, noomC_Compiler* compiler, c // I remember atom said there is a memory leak somewhere but I don't rememeememember where uhhhhhhhhhhhhhhhhh 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) { noom_Exit result; - // local name = expression i think + // local name = expression if (node->type == NOOMP_NODE_LOCALDECLARATION) { // FIXME: there can be multiple locals defined // This code is awful for several reasons and we shall burn it + // :( if (node->subnodec != 1 && node->subnodec != 2) return NOOM_EINTERNAL; const noomP_Node* varname_node = node->subnodes[0]; @@ -344,7 +357,7 @@ static noom_Exit noomC_add_stuff_to_function(noom_LuaVM* vm, noomC_Compiler* com if (node->subnodec == 1) { const unsigned short constptr = func->constsize; - result = noomC_emit_Aus(func, NOOMV_INSTR_PUSHNIL, 0, 0); + result = noomC_emit_AuD(func, NOOMV_INSTR_PUSHNIL, 0, 0); if (result != NOOM_OK) return result; compiler->curstack++; } else { @@ -402,7 +415,7 @@ static noom_Exit noomC_add_stuff_to_function(noom_LuaVM* vm, noomC_Compiler* com // TODO if (node->type == NOOMP_NODE_RETURN) { - noomC_emit_Aus(func, NOOMV_INSTR_NOP, 0, 0); + noomC_emit_AuD(func, NOOMV_INSTR_NOP, 0, 0); return NOOM_OK; } -- 2.49.1