feat: enhance compiler
- Add comments and test for it - Add semicolon as required end of some expressions - Add new arguments parser - Add multi-file compilation - Add colors in output
This commit is contained in:
+86
-37
@@ -1,4 +1,5 @@
|
||||
#include "compiler/fzl_token.h"
|
||||
#include "compiler/utils/fzl_linked.h"
|
||||
#include <compiler/fzl_reader.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
@@ -9,7 +10,7 @@
|
||||
// Last error from reader
|
||||
static char last_err[256] = {0};
|
||||
|
||||
fzl_reader_t *fzl_mkreader(char *source)
|
||||
fzl_reader_t *fzl_mkreader(fzl_linked_t *linked)
|
||||
{
|
||||
fzl_reader_ll_t *first_node = malloc(sizeof(fzl_reader_ll_t));
|
||||
first_node->token = NULL;
|
||||
@@ -18,11 +19,10 @@ fzl_reader_t *fzl_mkreader(char *source)
|
||||
fzl_reader_t *reader = malloc(sizeof(fzl_reader_t));
|
||||
reader->first = first_node;
|
||||
reader->last = first_node;
|
||||
reader->source = source;
|
||||
reader->size = strlen(source);
|
||||
reader->linked = linked;
|
||||
reader->source = linked->source;
|
||||
reader->size = linked->total_sz;
|
||||
reader->position = 0;
|
||||
reader->line_n = 1;
|
||||
reader->line_start = 0;
|
||||
|
||||
return reader;
|
||||
}
|
||||
@@ -30,21 +30,12 @@ fzl_reader_t *fzl_mkreader(char *source)
|
||||
// --- Read zone ---
|
||||
|
||||
// Move cursor forward
|
||||
// @deprecated
|
||||
static size_t move(fzl_reader_t *reader, size_t len)
|
||||
{
|
||||
if (!reader)
|
||||
return 0;
|
||||
|
||||
char *src = reader->source;
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
if (src[reader->position + i] == '\n')
|
||||
{
|
||||
reader->line_n++;
|
||||
reader->line_start = reader->position + i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return reader->position += len;
|
||||
}
|
||||
|
||||
@@ -71,17 +62,24 @@ fzl_token_t *parse_name(fzl_reader_t *reader)
|
||||
move(reader, size);
|
||||
|
||||
fzl_token_t *tok;
|
||||
size_t line = reader->line_n;
|
||||
size_t pos = start - reader->line_start;
|
||||
fzl_file_loc l;
|
||||
bool ok = fzl_linked_getpos(reader->linked, start, &l);
|
||||
if (!ok)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err), "failed to locate line:col");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strcmp(value, "return") == 0)
|
||||
tok = fzl_mktoken(FZL_TOKTYPE_RETURN, line, pos, value, size);
|
||||
tok =
|
||||
fzl_mktoken(FZL_TOKTYPE_RETURN, l.line, l.col, value, size, l.filename);
|
||||
else if (strcmp(value, "if") == 0)
|
||||
tok = fzl_mktoken(FZL_TOKTYPE_IF, line, pos, value, size);
|
||||
tok = fzl_mktoken(FZL_TOKTYPE_IF, l.line, l.col, value, size, l.filename);
|
||||
else if (strcmp(value, "else") == 0)
|
||||
tok = fzl_mktoken(FZL_TOKTYPE_ELSE, line, pos, value, size);
|
||||
tok = fzl_mktoken(FZL_TOKTYPE_ELSE, l.line, l.col, value, size, l.filename);
|
||||
else if (strcmp(value, "true") == 0 || strcmp(value, "false") == 0)
|
||||
tok = fzl_mktoken(FZL_TOKTYPE_BOOL_LITERAL, line, pos, value, size);
|
||||
tok = fzl_mktoken(FZL_TOKTYPE_BOOL_LITERAL, l.line, l.col, value, size,
|
||||
l.filename);
|
||||
else if (strcmp(value, "str") == 0 || strcmp(value, "char") == 0 ||
|
||||
strcmp(value, "bool") == 0 || strcmp(value, "uint") == 0 ||
|
||||
strcmp(value, "int") == 0 || strcmp(value, "i8") == 0 ||
|
||||
@@ -89,9 +87,9 @@ fzl_token_t *parse_name(fzl_reader_t *reader)
|
||||
strcmp(value, "i64") == 0 || strcmp(value, "u8") == 0 ||
|
||||
strcmp(value, "u16") == 0 || strcmp(value, "u32") == 0 ||
|
||||
strcmp(value, "u64") == 0)
|
||||
tok = fzl_mktoken(FZL_TOKTYPE_TYPE, line, pos, value, size);
|
||||
tok = fzl_mktoken(FZL_TOKTYPE_TYPE, l.line, l.col, value, size, l.filename);
|
||||
else
|
||||
tok = fzl_mktoken(FZL_TOKTYPE_NAME, line, pos, value, size);
|
||||
tok = fzl_mktoken(FZL_TOKTYPE_NAME, l.line, l.col, value, size, l.filename);
|
||||
free(value);
|
||||
|
||||
return tok;
|
||||
@@ -120,26 +118,33 @@ fzl_token_t *parse_string_literal(fzl_reader_t *reader)
|
||||
} while (reader->source[lpos] != open_symbol && lpos < reader->size);
|
||||
size++;
|
||||
|
||||
fzl_file_loc l;
|
||||
bool ok = fzl_linked_getpos(reader->linked, reader->position, &l);
|
||||
if (!ok)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err), "failed to locate line:col");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (close_symbol != open_symbol)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err), "unterminated string at %ld:%ld",
|
||||
reader->line_n, reader->position - reader->line_start);
|
||||
snprintf(last_err, sizeof(last_err), "'%s': unterminated string at %ld:%ld",
|
||||
l.filename, l.line, l.col);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (size == 2)
|
||||
{
|
||||
fzl_token_t *tok =
|
||||
fzl_mktoken(FZL_TOKTYPE_STR_LITERAL, reader->line_n,
|
||||
reader->position - reader->line_start, "", 0);
|
||||
fzl_mktoken(FZL_TOKTYPE_STR_LITERAL, l.line, l.col, "", 0, l.filename);
|
||||
move(reader, 2);
|
||||
return tok;
|
||||
}
|
||||
|
||||
char *value = malloc(size - 2);
|
||||
memcpy(value, reader->source + reader->position + 1, size - 2);
|
||||
fzl_token_t *tok = fzl_mktoken(FZL_TOKTYPE_STR_LITERAL, reader->line_n,
|
||||
lpos - reader->line_start, value, size - 2);
|
||||
fzl_token_t *tok = fzl_mktoken(FZL_TOKTYPE_STR_LITERAL, l.line, l.col, value,
|
||||
size - 2, l.filename);
|
||||
free(value);
|
||||
move(reader, size);
|
||||
|
||||
@@ -166,8 +171,16 @@ fzl_token_t *parse_number(fzl_reader_t *reader)
|
||||
memcpy(value, reader->source + reader->position, size);
|
||||
value[size] = '\0';
|
||||
|
||||
fzl_token_t *tok = fzl_mktoken(FZL_TOKTYPE_NUM_LITERAL, reader->line_n,
|
||||
lpos - reader->line_start, value, size);
|
||||
fzl_file_loc l;
|
||||
bool ok = fzl_linked_getpos(reader->linked, reader->position, &l);
|
||||
if (!ok)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err), "failed to locate line:col");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fzl_token_t *tok = fzl_mktoken(FZL_TOKTYPE_NUM_LITERAL, l.line, l.col, value,
|
||||
size, l.filename);
|
||||
free(value);
|
||||
|
||||
if (!tok)
|
||||
@@ -181,14 +194,31 @@ fzl_token_t *parse_number(fzl_reader_t *reader)
|
||||
fzl_token_t *add_single(fzl_reader_t *reader, fzl_toktype_t type)
|
||||
{
|
||||
size_t p = move(reader, 1);
|
||||
return fzl_mktoken(type, reader->line_n, p - reader->line_start, NULL, 0);
|
||||
fzl_file_loc l;
|
||||
bool ok = fzl_linked_getpos(reader->linked, p, &l);
|
||||
if (!ok)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err), "failed to locate line:col");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fzl_mktoken(type, l.line, l.col, NULL, 0, l.filename);
|
||||
}
|
||||
|
||||
// Add double-char token
|
||||
fzl_token_t *add_double(fzl_reader_t *reader, fzl_toktype_t type)
|
||||
{
|
||||
size_t p = move(reader, 2);
|
||||
return fzl_mktoken(type, reader->line_n, p - reader->line_start, NULL, 0);
|
||||
fzl_file_loc l;
|
||||
bool ok = fzl_linked_getpos(reader->linked, p, &l);
|
||||
if (!ok)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err), "failed to locate line:col");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fzl_mktoken(type, l.line, l.col, NULL, 0, l.filename);
|
||||
}
|
||||
|
||||
// Skip symbols until '\n' or EOF
|
||||
void skip_comment(fzl_reader_t *reader)
|
||||
@@ -277,16 +307,35 @@ int fzl_read(fzl_reader_t *reader)
|
||||
token = parse_number(reader);
|
||||
else
|
||||
{
|
||||
sprintf(last_err, "undefined token '%c' at %ld:%ld", curr, reader->line_n,
|
||||
p - reader->line_start);
|
||||
fzl_file_loc l;
|
||||
bool ok = fzl_linked_getpos(reader->linked, p, &l);
|
||||
if (!ok)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err), "failed to locate line:col");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(last_err, "'%s': undefined token '%c' at %ld:%ld", l.filename,
|
||||
curr, l.line, l.col);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!token)
|
||||
{
|
||||
if (!last_err[0])
|
||||
sprintf(last_err, "cannot parse token at %ld:%ld", reader->line_n,
|
||||
p - reader->line_start);
|
||||
{
|
||||
fzl_file_loc l;
|
||||
bool ok = fzl_linked_getpos(reader->linked, p, &l);
|
||||
if (!ok)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err), "failed to locate line:col");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(last_err, "'%s': cannot parse token at %ld:%ld", l.filename,
|
||||
l.line, l.col);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user