diff options
Diffstat (limited to 'src/tokenizer.c')
-rw-r--r-- | src/tokenizer.c | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/src/tokenizer.c b/src/tokenizer.c index 04e9d27..f2f52ad 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -2,6 +2,7 @@ #include "../include/std/mem.h" #include "../include/std/log.h" #include "../include/std/thread.h" +#include "../include/std/scoped_allocator.h" #include <assert.h> #include <limits.h> #include <stdio.h> @@ -19,7 +20,7 @@ static int isAlphaDigit(int c) { return isAlpha(c) || isDigit(c); } -int tokenizer_init(Tokenizer *self, BufferView code, BufferView code_name) { +int tokenizer_init(Tokenizer *self, ScopedAllocator *allocator, BufferView code, BufferView code_name) { assert(code.size <= INT_MAX); self->code = code; self->index = 0; @@ -29,6 +30,7 @@ int tokenizer_init(Tokenizer *self, BufferView code, BufferView code_name) { self->needs_update = bool_true; self->code_name = code_name.data ? code_name : create_buffer_view("<buffer>", 8); self->number_is_integer = bool_false; + self->allocator = allocator; return 0; } @@ -548,14 +550,51 @@ void tokenizer_print_error(Tokenizer *self, const char *fmt, ...) { ignore_result_int(amal_mutex_unlock(mutex)); } +/* TODO: Optimize */ +static int tokenizer_get_line_by_index(Tokenizer *self, int index) { + int i; + int line; + if(index < 0 || index >= (int)self->code.size) + return -1; + + line = 1; + for(i = 0; i < index; ++i) { + if(self->code.data[i] == '\n') + ++line; + } + return line; +} + void tokenizer_print_error_object(Tokenizer *self, TokenizerError *error) { self->prev_index = error->index; - tokenizer_print_error(self, error->str); + self->line = tokenizer_get_line_by_index(self, self->prev_index); + tokenizer_print_error(self, "%s", error->str); } -TokenizerError tokenizer_create_error(Tokenizer *tokenizer, const char *err_str) { +TokenizerError tokenizer_create_error(Tokenizer *self, int index, const char *fmt, ...) { TokenizerError result; - result.index = tokenizer->prev_index; - result.str = err_str; + va_list args; + char buffer[1024]; + int bytes_copied; + + va_start(args, fmt); + bytes_copied = vsnprintf(buffer, sizeof(buffer), fmt, args); + va_end(args); + if(bytes_copied < 0) + bytes_copied = 0; + + result.index = index; + result.str = NULL; + ignore_result_int(scoped_allocator_alloc(self->allocator, bytes_copied, (void**)&result.str)); + if(result.str) + am_memcpy(result.str, buffer, bytes_copied); return result; } + +int tokenizer_get_error_index(Tokenizer *self) { + return self->prev_index; +} + +int tokenizer_get_code_reference_index(Tokenizer *self, const char *ref) { + return ref - self->code.data; +} |