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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user