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
This commit is contained in:
samsonium
2026-10-10 21:03:23 +03:00
parent f49a54c878
commit 1db985ecb5
7 changed files with 47 additions and 14 deletions
+1
View File
@@ -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;
+11 -2
View File
@@ -1,3 +1,4 @@
#include "compiler/fzl_token.h"
#include <compiler/fzl_parser.h>
#include <stdio.h>
#include <stdlib.h>
@@ -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); // <NAME>
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;
}
+15 -6
View File
@@ -1,4 +1,5 @@
#include <compiler/fzl_reader.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -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;
+2 -1
View File
@@ -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;
+10 -2
View File
@@ -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;
}
+7 -2
View File
@@ -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);
+1 -1
View File
@@ -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;
}