diff --git a/CMakeLists.txt b/CMakeLists.txt index a114d17..ba81f35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,11 @@ add_executable(fzc src/compiler/analyzer/an_return.c src/compiler/analyzer/an_unarycond.c src/compiler/analyzer/an_unarymath.c + src/compiler/reader/rd_fmtstr.c + src/compiler/reader/rd_name.c + src/compiler/reader/rd_number.c + src/compiler/reader/rd_string_literal.c + src/compiler/reader/utility.c src/compiler/fzl_analyzer.c src/compiler/fzl_debug.c src/compiler/fzl_parser.c diff --git a/include/compiler/internals/reader.h b/include/compiler/internals/reader.h new file mode 100644 index 0000000..97acd0b --- /dev/null +++ b/include/compiler/internals/reader.h @@ -0,0 +1,19 @@ +#ifndef INTERNALS_READER_H +#define INTERNALS_READER_H + +#include +#include + +extern char last_err[256]; + +size_t move(fzl_reader_t *reader, size_t len); +void rd_comment(fzl_reader_t *reader); + +fzl_token_t *rd_name(fzl_reader_t *reader); +fzl_token_t *rd_string_literal(fzl_reader_t *reader); +fzl_token_t *rd_number(fzl_reader_t *reader); +fzl_token_t *rd_single(fzl_reader_t *reader, fzl_toktype_t type); +fzl_token_t *rd_double(fzl_reader_t *reader, fzl_toktype_t type); +fzl_token_t *rd_fmtstr(fzl_reader_t *reader); + +#endif // INTERNALS_READER_H diff --git a/src/compiler/fzl_reader.c b/src/compiler/fzl_reader.c index fa09b1f..32196a3 100644 --- a/src/compiler/fzl_reader.c +++ b/src/compiler/fzl_reader.c @@ -1,6 +1,7 @@ -#include "compiler/fzl_token.h" -#include "compiler/utils/fzl_linked.h" #include +#include +#include +#include #include #include #include @@ -8,7 +9,7 @@ #include // Last error from reader -static char last_err[256] = {0}; +char last_err[256]; fzl_reader_t *fzl_mkreader(fzl_linked_t *linked) { @@ -24,303 +25,11 @@ fzl_reader_t *fzl_mkreader(fzl_linked_t *linked) reader->size = linked->total_sz; reader->position = 0; + memset(last_err, 0, sizeof(last_err)); + return reader; } -// --- Read zone --- - -// Move cursor forward -// @deprecated -static size_t move(fzl_reader_t *reader, size_t len) -{ - if (!reader) - return 0; - - return reader->position += len; -} - -// Try parse name -fzl_token_t *parse_name(fzl_reader_t *reader) -{ - size_t lpos = reader->position; - size_t size = 0; - - do - { - lpos++; - size++; - } while ((reader->source[lpos] >= 'A' && reader->source[lpos] <= 'Z') || - (reader->source[lpos] >= 'a' && reader->source[lpos] <= 'z') || - (reader->source[lpos] >= '0' && reader->source[lpos] <= '9') || - (reader->source[lpos] == '_')); - - char *value = malloc(size + 1); - memcpy(value, reader->source + reader->position, size); - value[size] = '\0'; - - size_t start = reader->position; - move(reader, size); - - fzl_token_t *tok; - 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, "class") == 0) - tok = - fzl_mktoken(FZL_TOKTYPE_CLASS, l.line, l.col, value, size, l.filename); - else if (strcmp(value, "for") == 0) - tok = fzl_mktoken(FZL_TOKTYPE_FOR, l.line, l.col, value, size, l.filename); - else if (strcmp(value, "while") == 0) - tok = - fzl_mktoken(FZL_TOKTYPE_WHILE, l.line, l.col, value, size, l.filename); - else if (strcmp(value, "break") == 0) - tok = - fzl_mktoken(FZL_TOKTYPE_BREAK, l.line, l.col, value, size, l.filename); - else if (strcmp(value, "new") == 0) - tok = fzl_mktoken(FZL_TOKTYPE_NEW, l.line, l.col, value, size, l.filename); - else if (strcmp(value, "fn") == 0) - tok = fzl_mktoken(FZL_TOKTYPE_FUNCTION, l.line, l.col, value, size, - l.filename); - else if (strcmp(value, "return") == 0) - 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, l.line, l.col, value, size, l.filename); - else if (strcmp(value, "else") == 0) - 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, l.line, l.col, value, size, - l.filename); - else if (strcmp(value, "null") == 0) - tok = fzl_mktoken(FZL_TOKTYPE_NULL_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 || - strcmp(value, "i16") == 0 || strcmp(value, "i32") == 0 || - 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, l.line, l.col, value, size, l.filename); - else - tok = fzl_mktoken(FZL_TOKTYPE_NAME, l.line, l.col, value, size, l.filename); - free(value); - - return tok; -} - -// Try parse string literal -fzl_token_t *parse_string_literal(fzl_reader_t *reader) -{ - size_t lpos = reader->position; - size_t size = 0; - - if (reader->source[lpos] != '\'' && reader->source[lpos] != '"') - return NULL; - - char open_symbol = reader->source[lpos]; - char close_symbol = '\0'; - - do - { - lpos++; - size++; - - if (reader->source[lpos] == open_symbol) - close_symbol = open_symbol; - - } 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), "'%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, 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, l.line, l.col, value, - size - 2, l.filename); - free(value); - move(reader, size); - - return tok; -} - -// Parse numeric literal -fzl_token_t *parse_number(fzl_reader_t *reader) -{ - if (!reader) - return NULL; - - size_t size = 0; - size_t lpos = reader->position; - - do - { - size++; - lpos++; - } while ((reader->source[lpos] >= '0' && reader->source[lpos] <= '9') && - lpos < reader->size); - - char *value = malloc(size * sizeof(char) + 1); - memcpy(value, reader->source + reader->position, size); - value[size] = '\0'; - - 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) - return NULL; - - move(reader, size); - return tok; -} - -// Add single-char token -fzl_token_t *add_single(fzl_reader_t *reader, fzl_toktype_t type) -{ - 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; - } - - move(reader, 1); - return fzl_mktoken(type, l.line, l.col, "", 0, l.filename); -} - -// Add double-char token -fzl_token_t *add_double(fzl_reader_t *reader, fzl_toktype_t type) -{ - 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; - } - - move(reader, 2); - return fzl_mktoken(type, l.line, l.col, "", 0, l.filename); -} - -// Skip symbols until '\n' or EOF -void skip_comment(fzl_reader_t *reader) -{ - move(reader, 2); - - while (reader->position < reader->size) - { - if (reader->source[reader->position++] == '\n') - break; - } -} - -// Parse string format -fzl_token_t *parse_fmtstring_part(fzl_reader_t *reader) -{ - size_t p = reader->position; - char *src = reader->source; - - 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 (src[p] == '{') - { - move(reader, 1); - fzl_token_t *id = parse_name(reader); - - if (id == NULL || src[reader->position] != '}') - { - snprintf(last_err, sizeof(last_err), - "'%s':%zu:%zu => failed to parse format string", l.filename, - l.line, l.col); - fzl_freetoken(id); - return NULL; - } - - move(reader, 1); - return id; - } - - if (src[p] == '"') - { - move(reader, 1); - - return fzl_mktoken(FZL_TOKTYPE_STR_FORMAT_END, l.line, l.col, NULL, 0, - l.filename); - } - - size_t size = 0; - size_t lpos = p; - - do - { - if (src[lpos + 1] == '"') - break; - - size++; - lpos++; - } while (lpos < reader->size && reader->source[lpos] != '{' && - reader->source[lpos] != '"'); - - ok = fzl_linked_getpos(reader->linked, reader->position, &l); - if (!ok) - { - snprintf(last_err, sizeof(last_err), "failed to locate line:col"); - return NULL; - } - - char *value = malloc(size); - memcpy(value, reader->source + reader->position, size); - fzl_token_t *tok = fzl_mktoken(FZL_TOKTYPE_STR_LITERAL, l.line, l.col, value, - size, l.filename); - free(value); - move(reader, size); - - return tok; -} - int fzl_read(fzl_reader_t *reader) { if (reader->position >= reader->size) @@ -342,63 +51,63 @@ int fzl_read(fzl_reader_t *reader) if (is_format_str) { - token = parse_fmtstring_part(reader); + token = rd_fmtstr(reader); if (token && token->type == FZL_TOKTYPE_STR_FORMAT_END) is_format_str = false; } else if (curr == '\'' || curr == '"') - token = parse_string_literal(reader); + token = rd_string_literal(reader); else if (curr == '/' && reader->source[p + 1] == '/') { - skip_comment(reader); + rd_comment(reader); continue; } else if (curr == '=' && reader->source[p + 1] == '=') - token = add_double(reader, FZL_TOKTYPE_EQEQ); + token = rd_double(reader, FZL_TOKTYPE_EQEQ); else if (curr == '>' && reader->source[p + 1] == '=') - token = add_double(reader, FZL_TOKTYPE_REQ); + token = rd_double(reader, FZL_TOKTYPE_REQ); else if (curr == '<' && reader->source[p + 1] == '=') - token = add_double(reader, FZL_TOKTYPE_LEQ); + token = rd_double(reader, FZL_TOKTYPE_LEQ); else if (curr == '!' && reader->source[p + 1] == '=') - token = add_double(reader, FZL_TOKTYPE_NEQ); + token = rd_double(reader, FZL_TOKTYPE_NEQ); else if (curr == '|' && reader->source[p + 1] == '|') - token = add_double(reader, FZL_TOKTYPE_DVBAR); + token = rd_double(reader, FZL_TOKTYPE_DVBAR); else if (curr == '&' && reader->source[p + 1] == '&') - token = add_double(reader, FZL_TOKTYPE_DAMPERSAND); + token = rd_double(reader, FZL_TOKTYPE_DAMPERSAND); else if (curr == '>') - token = add_single(reader, FZL_TOKTYPE_RANGLE); + token = rd_single(reader, FZL_TOKTYPE_RANGLE); else if (curr == '<') - token = add_single(reader, FZL_TOKTYPE_LANGLE); + token = rd_single(reader, FZL_TOKTYPE_LANGLE); else if (curr == '!') - token = add_single(reader, FZL_TOKTYPE_NOT); + token = rd_single(reader, FZL_TOKTYPE_NOT); else if (curr == ';') - token = add_single(reader, FZL_TOKTYPE_SEMICOLON); + token = rd_single(reader, FZL_TOKTYPE_SEMICOLON); else if (curr == '{') - token = add_single(reader, FZL_TOKTYPE_LBRACE); + token = rd_single(reader, FZL_TOKTYPE_LBRACE); else if (curr == '}') - token = add_single(reader, FZL_TOKTYPE_RBRACE); + token = rd_single(reader, FZL_TOKTYPE_RBRACE); else if (curr == '(') - token = add_single(reader, FZL_TOKTYPE_LPAREN); + token = rd_single(reader, FZL_TOKTYPE_LPAREN); else if (curr == ')') - token = add_single(reader, FZL_TOKTYPE_RPAREN); + token = rd_single(reader, FZL_TOKTYPE_RPAREN); else if (curr == ',') - token = add_single(reader, FZL_TOKTYPE_COMMA); + token = rd_single(reader, FZL_TOKTYPE_COMMA); else if (curr == '.') - token = add_single(reader, FZL_TOKTYPE_DOT); + token = rd_single(reader, FZL_TOKTYPE_DOT); else if (curr == '*') - token = add_single(reader, FZL_TOKTYPE_STAR); + token = rd_single(reader, FZL_TOKTYPE_STAR); else if (curr == '/') - token = add_single(reader, FZL_TOKTYPE_SLASH); + token = rd_single(reader, FZL_TOKTYPE_SLASH); else if (curr == '+') - token = add_single(reader, FZL_TOKTYPE_PLUS); + token = rd_single(reader, FZL_TOKTYPE_PLUS); else if (curr == '-') - token = add_single(reader, FZL_TOKTYPE_MINUS); + token = rd_single(reader, FZL_TOKTYPE_MINUS); else if (curr == '^') - token = add_single(reader, FZL_TOKTYPE_CARET); + token = rd_single(reader, FZL_TOKTYPE_CARET); else if (curr == '%') - token = add_single(reader, FZL_TOKTYPE_PERCENT); + token = rd_single(reader, FZL_TOKTYPE_PERCENT); else if (curr == '=') - token = add_single(reader, FZL_TOKTYPE_EQ); + token = rd_single(reader, FZL_TOKTYPE_EQ); else if (curr == '$' && reader->source[p + 1] == '"') { move(reader, 2); @@ -407,9 +116,9 @@ int fzl_read(fzl_reader_t *reader) } else if ((curr >= 'A' && curr <= 'Z') || (curr >= 'a' && curr <= 'z') || curr == '_') - token = parse_name(reader); + token = rd_name(reader); else if (curr >= '0' && curr <= '9') - token = parse_number(reader); + token = rd_number(reader); else { fzl_file_loc l; @@ -455,8 +164,6 @@ int fzl_read(fzl_reader_t *reader) return 0; } -// --- Read zone end --- - char *fzl_reader_geterror() { return last_err; } void free_node_and_next(fzl_reader_ll_t *node) diff --git a/src/compiler/reader/rd_fmtstr.c b/src/compiler/reader/rd_fmtstr.c new file mode 100644 index 0000000..234775a --- /dev/null +++ b/src/compiler/reader/rd_fmtstr.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include + +// Parse string format +fzl_token_t *rd_fmtstr(fzl_reader_t *reader) +{ + size_t p = reader->position; + char *src = reader->source; + + 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 (src[p] == '{') + { + move(reader, 1); + fzl_token_t *id = rd_name(reader); + + if (id == NULL || src[reader->position] != '}') + { + snprintf(last_err, sizeof(last_err), + "'%s':%zu:%zu => failed to parse format string", l.filename, + l.line, l.col); + fzl_freetoken(id); + return NULL; + } + + move(reader, 1); + return id; + } + + if (src[p] == '"') + { + move(reader, 1); + + return fzl_mktoken(FZL_TOKTYPE_STR_FORMAT_END, l.line, l.col, NULL, 0, + l.filename); + } + + size_t size = 0; + size_t lpos = p; + + do + { + if (src[lpos + 1] == '"') + break; + + size++; + lpos++; + } while (lpos < reader->size && reader->source[lpos] != '{' && + reader->source[lpos] != '"'); + + ok = fzl_linked_getpos(reader->linked, reader->position, &l); + if (!ok) + { + snprintf(last_err, sizeof(last_err), "failed to locate line:col"); + return NULL; + } + + char *value = malloc(size); + memcpy(value, reader->source + reader->position, size); + fzl_token_t *tok = fzl_mktoken(FZL_TOKTYPE_STR_LITERAL, l.line, l.col, value, + size, l.filename); + free(value); + move(reader, size); + + return tok; +} diff --git a/src/compiler/reader/rd_name.c b/src/compiler/reader/rd_name.c new file mode 100644 index 0000000..5858e12 --- /dev/null +++ b/src/compiler/reader/rd_name.c @@ -0,0 +1,80 @@ +#include +#include +#include +#include +#include + +// Try parse name +fzl_token_t *rd_name(fzl_reader_t *reader) +{ + size_t lpos = reader->position; + size_t size = 0; + + do + { + lpos++; + size++; + } while ((reader->source[lpos] >= 'A' && reader->source[lpos] <= 'Z') || + (reader->source[lpos] >= 'a' && reader->source[lpos] <= 'z') || + (reader->source[lpos] >= '0' && reader->source[lpos] <= '9') || + (reader->source[lpos] == '_')); + + char *value = malloc(size + 1); + memcpy(value, reader->source + reader->position, size); + value[size] = '\0'; + + size_t start = reader->position; + move(reader, size); + + fzl_token_t *tok; + 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, "class") == 0) + tok = + fzl_mktoken(FZL_TOKTYPE_CLASS, l.line, l.col, value, size, l.filename); + else if (strcmp(value, "for") == 0) + tok = fzl_mktoken(FZL_TOKTYPE_FOR, l.line, l.col, value, size, l.filename); + else if (strcmp(value, "while") == 0) + tok = + fzl_mktoken(FZL_TOKTYPE_WHILE, l.line, l.col, value, size, l.filename); + else if (strcmp(value, "break") == 0) + tok = + fzl_mktoken(FZL_TOKTYPE_BREAK, l.line, l.col, value, size, l.filename); + else if (strcmp(value, "new") == 0) + tok = fzl_mktoken(FZL_TOKTYPE_NEW, l.line, l.col, value, size, l.filename); + else if (strcmp(value, "fn") == 0) + tok = fzl_mktoken(FZL_TOKTYPE_FUNCTION, l.line, l.col, value, size, + l.filename); + else if (strcmp(value, "return") == 0) + 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, l.line, l.col, value, size, l.filename); + else if (strcmp(value, "else") == 0) + 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, l.line, l.col, value, size, + l.filename); + else if (strcmp(value, "null") == 0) + tok = fzl_mktoken(FZL_TOKTYPE_NULL_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 || + strcmp(value, "i16") == 0 || strcmp(value, "i32") == 0 || + 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, l.line, l.col, value, size, l.filename); + else + tok = fzl_mktoken(FZL_TOKTYPE_NAME, l.line, l.col, value, size, l.filename); + free(value); + + return tok; +} diff --git a/src/compiler/reader/rd_number.c b/src/compiler/reader/rd_number.c new file mode 100644 index 0000000..9f8a233 --- /dev/null +++ b/src/compiler/reader/rd_number.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include +#include + +// Parse numeric literal +fzl_token_t *rd_number(fzl_reader_t *reader) +{ + if (!reader) + return NULL; + + size_t size = 0; + size_t lpos = reader->position; + + do + { + size++; + lpos++; + } while ((reader->source[lpos] >= '0' && reader->source[lpos] <= '9') && + lpos < reader->size); + + char *value = malloc(size * sizeof(char) + 1); + memcpy(value, reader->source + reader->position, size); + value[size] = '\0'; + + 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) + return NULL; + + move(reader, size); + return tok; +} diff --git a/src/compiler/reader/rd_string_literal.c b/src/compiler/reader/rd_string_literal.c new file mode 100644 index 0000000..3069a12 --- /dev/null +++ b/src/compiler/reader/rd_string_literal.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include +#include + +// Try parse string literal +fzl_token_t *rd_string_literal(fzl_reader_t *reader) +{ + size_t lpos = reader->position; + size_t size = 0; + + if (reader->source[lpos] != '\'' && reader->source[lpos] != '"') + return NULL; + + char open_symbol = reader->source[lpos]; + char close_symbol = '\0'; + + do + { + lpos++; + size++; + + if (reader->source[lpos] == open_symbol) + close_symbol = open_symbol; + + } 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), "'%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, 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, l.line, l.col, value, + size - 2, l.filename); + free(value); + move(reader, size); + + return tok; +} diff --git a/src/compiler/reader/utility.c b/src/compiler/reader/utility.c new file mode 100644 index 0000000..6e6136b --- /dev/null +++ b/src/compiler/reader/utility.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include + +// Move cursor forward +size_t move(fzl_reader_t *reader, size_t len) +{ + if (!reader) + return 0; + + return reader->position += len; +} + +// Add single-char token +fzl_token_t *rd_single(fzl_reader_t *reader, fzl_toktype_t type) +{ + 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; + } + + move(reader, 1); + return fzl_mktoken(type, l.line, l.col, "", 0, l.filename); +} + +// Add double-char token +fzl_token_t *rd_double(fzl_reader_t *reader, fzl_toktype_t type) +{ + 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; + } + + move(reader, 2); + return fzl_mktoken(type, l.line, l.col, "", 0, l.filename); +} + +// Skip symbols until '\n' or EOF +void rd_comment(fzl_reader_t *reader) +{ + move(reader, 2); + + while (reader->position < reader->size) + { + if (reader->source[reader->position++] == '\n') + break; + } +}