From 1db985ecb5a8afd2e9a3447b1718a76bdf8bca6b Mon Sep 17 00:00:00 2001 From: samsonium Date: Sat, 10 Oct 2026 21:03:23 +0300 Subject: [PATCH] feat+fix: make compiler STRONGAAA - FEAT: add source code length field in `fzl_reader_t` struct - FIX: check name, lpair (lparen) and rpair (rparen) when lexing call - FIX: check string literal termination - FIX: increment position even on empty string to prevent infinite lexing loop - FIX: add string terminator in `fzl_mktoken` when allocating space for string value - FIX: add check for errors in recursevly called `walk` - FIX: change source code holder from stack-stored `char[8192]` to dynamically allocated with actual file size holder - FIX: correct constant hasing util to hash actual string value instead of link --- include/compiler/fzl_reader.h | 1 + src/compiler/fzl_parser.c | 13 +++++++++++-- src/compiler/fzl_reader.c | 21 +++++++++++++++------ src/compiler/fzl_token.c | 3 ++- src/compiler/fzl_walker.c | 12 ++++++++++-- src/compiler/main.c | 9 +++++++-- src/compiler/utils/fzl_const_pool.c | 2 +- 7 files changed, 47 insertions(+), 14 deletions(-) diff --git a/include/compiler/fzl_reader.h b/include/compiler/fzl_reader.h index 818459b..73898ee 100644 --- a/include/compiler/fzl_reader.h +++ b/include/compiler/fzl_reader.h @@ -20,6 +20,7 @@ typedef struct fzl_reader_ll_t *last; char *source; + size_t size; size_t position; bool at_end; } fzl_reader_t; diff --git a/src/compiler/fzl_parser.c b/src/compiler/fzl_parser.c index b93ab88..704ac2d 100644 --- a/src/compiler/fzl_parser.c +++ b/src/compiler/fzl_parser.c @@ -1,3 +1,4 @@ +#include "compiler/fzl_token.h" #include #include #include @@ -92,7 +93,12 @@ fzl_node_t *parse_expression(fzl_parser_t *parser, int precedence); fzl_node_t *parse_call(fzl_parser_t *parser) { fzl_token_t *tok = consume(parser); // - consume(parser); // ( + if (tok->type != FZL_TOKTYPE_NAME) + return NULL; + + fzl_token_t *lpair = consume(parser); // ( + if (lpair->type != FZL_TOKTYPE_LPAIR) + return NULL; fzl_node_t *node = fzl_mknode(FZL_NODETYPE_CALL, tok); node->list.entry_count = 0; @@ -132,7 +138,10 @@ fzl_node_t *parse_call(fzl_parser_t *parser) } } - consume(parser); + fzl_token_t *rpair = consume(parser); + if (rpair->type != FZL_TOKTYPE_RPAIR) + return NULL; + return node; } diff --git a/src/compiler/fzl_reader.c b/src/compiler/fzl_reader.c index 31f7437..a4c3dcb 100644 --- a/src/compiler/fzl_reader.c +++ b/src/compiler/fzl_reader.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -16,6 +17,7 @@ fzl_reader_t *fzl_mkreader(char *source) reader->first = first_node; reader->last = first_node; reader->source = source; + reader->size = strlen(source); reader->position = 0; reader->at_end = true; @@ -60,18 +62,27 @@ fzl_token_t *parse_string_literal(fzl_reader_t *reader) return NULL; char open_symbol = reader->source[lpos]; + char close_symbol = '\0'; do { lpos++; size++; - } while (reader->source[lpos] != open_symbol); + + if (reader->source[lpos] == open_symbol) + close_symbol = open_symbol; + + } while (reader->source[lpos] != open_symbol && lpos < reader->size); size++; + if (close_symbol != open_symbol) + return NULL; + if (size == 2) { fzl_token_t *tok = fzl_mktoken(FZL_TOKTYPE_STR_LITERAL, reader->position, reader->position + 1, "", 0); + reader->position += 2; return tok; } @@ -88,8 +99,7 @@ fzl_token_t *parse_string_literal(fzl_reader_t *reader) int fzl_read(fzl_reader_t *reader) { - const size_t len = strlen(reader->source); - if (reader->position >= len) + if (reader->position >= reader->size) return 0; do @@ -139,8 +149,7 @@ int fzl_read(fzl_reader_t *reader) linepos++; } - sprintf(last_err, "error parsing token (position %ld of line %ld)", line, - linepos); + sprintf(last_err, "cannot parse token (%ld:%ld)", line, linepos); return -1; } @@ -149,7 +158,7 @@ int fzl_read(fzl_reader_t *reader) reader->last->next = tok_node; reader->last = tok_node; - } while (reader->position < len); + } while (reader->position < reader->size); reader->at_end = true; return 0; diff --git a/src/compiler/fzl_token.c b/src/compiler/fzl_token.c index f11da36..67f6660 100644 --- a/src/compiler/fzl_token.c +++ b/src/compiler/fzl_token.c @@ -5,8 +5,9 @@ fzl_token_t *fzl_mktoken(const fzl_toktype_t type, uint16_t from, uint16_t to, void *value, size_t value_len) { - void *valholder = malloc(value_len); + char *valholder = malloc(value_len + 1); memcpy(valholder, value, value_len); + valholder[value_len] = '\0'; fzl_token_t *token = malloc(sizeof(fzl_token_t)); token->type = type; diff --git a/src/compiler/fzl_walker.c b/src/compiler/fzl_walker.c index 46ad2cd..e4b3112 100644 --- a/src/compiler/fzl_walker.c +++ b/src/compiler/fzl_walker.c @@ -100,7 +100,8 @@ bool walk(fzl_walker_t *walker, fzl_node_t *node) // NOTE: create block env here if (node->list.entry_count > 0) for (size_t i = 0; i < node->list.entry_count; i++) - walk(walker, node->list.entries[i]); + if (!walk(walker, node->list.entries[i])) + return false; // NOTE: destroy block env here break; @@ -109,7 +110,8 @@ bool walk(fzl_walker_t *walker, fzl_node_t *node) { for (size_t i = 0; i < node->list.entry_count; i++) { - walk(walker, node->list.entries[i]); + if (!walk(walker, node->list.entries[i])) + return false; push_op(walker, FZL_OPCODE_PUSHARG); } } @@ -146,6 +148,12 @@ bool walk(fzl_walker_t *walker, fzl_node_t *node) // Walk entire AST recursevily int fzl_walk(fzl_walker_t *walker) { + if (!walker) + { + snprintf(wlast_err, sizeof(wlast_err), "walker is null"); + return -1; + } + bool result = walk(walker, walker->root); return !result && wlast_err[0] ? -1 : 0; } diff --git a/src/compiler/main.c b/src/compiler/main.c index 46c0689..612cda5 100644 --- a/src/compiler/main.c +++ b/src/compiler/main.c @@ -102,7 +102,7 @@ int main(int argc, char **argv) if (args->verbose) printf("> analyze\n-> reading file..."); - char source[8192]; + char *source; FILE *fd = fopen(args->filepath, "r"); if (!fd) { @@ -114,11 +114,15 @@ int main(int argc, char **argv) size_t fsz = ftell(fd); rewind(fd); + source = malloc(fsz + 1); fread(source, fsz, 1, fd); fclose(fd); + source[fsz] = '\0'; + if (args->verbose) { printf("ok!\n"); + printf("--> Red %ld bytes\n", fsz); printf("-> tokenizing..."); } @@ -218,10 +222,11 @@ int main(int argc, char **argv) if (args->verbose) printf("ok!\n"); + free(source); free(args); fzl_freereader(rd); - fzl_freeparser(parser); fzl_freeast(parser->root); + fzl_freeparser(parser); fzl_freewalker(walker); fzl_freewriter(writer); diff --git a/src/compiler/utils/fzl_const_pool.c b/src/compiler/utils/fzl_const_pool.c index abb0d0b..39c4c28 100644 --- a/src/compiler/utils/fzl_const_pool.c +++ b/src/compiler/utils/fzl_const_pool.c @@ -33,7 +33,7 @@ static uint32_t fzl_hash_const(fzl_const_t c) switch (c.type) { case FZL_CONSTTYPE_STRING: - data = (const uint8_t *)&c.as.string.chars; + data = (const uint8_t *)c.as.string.chars; size = c.as.string.length; break; }