diff options
Diffstat (limited to 'src/tokenizer.c')
-rw-r--r-- | src/tokenizer.c | 111 |
1 files changed, 100 insertions, 11 deletions
diff --git a/src/tokenizer.c b/src/tokenizer.c index 7f6d08e..03a72a1 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -170,6 +170,9 @@ static CHECK_RESULT int __tokenizer_next(Tokenizer *self, Token *token) { if(am_memeql(self->value.identifier.data, "fn", 2)) { *token = TOK_FN; return TOKENIZER_OK; + } else if(am_memeql(self->value.identifier.data, "if", 2)) { + *token = TOK_IF; + return TOKENIZER_OK; } break; } @@ -183,10 +186,20 @@ static CHECK_RESULT int __tokenizer_next(Tokenizer *self, Token *token) { } break; } + case 4: { + if(am_memeql(self->value.identifier.data, "else", 4)) { + *token = TOK_ELSE; + return TOKENIZER_OK; + } + break; + } case 5: { if(am_memeql(self->value.identifier.data, "const", 5)) { *token = TOK_CONST; return TOKENIZER_OK; + } else if(am_memeql(self->value.identifier.data, "while", 5)) { + *token = TOK_WHILE; + return TOKENIZER_OK; } break; } @@ -194,6 +207,9 @@ static CHECK_RESULT int __tokenizer_next(Tokenizer *self, Token *token) { if(am_memeql(self->value.identifier.data, "struct", 6)) { *token = TOK_STRUCT; return TOKENIZER_OK; + } else if(am_memeql(self->value.identifier.data, "extern", 6)) { + *token = TOK_EXTERN; + return TOKENIZER_OK; } break; } @@ -288,7 +304,12 @@ static CHECK_RESULT int __tokenizer_next(Tokenizer *self, Token *token) { SET_BINOP(BINOP_DIV); } else if(c == '=') { ++self->index; - *token = TOK_EQUALS; + if(self->index < (int)self->code.size && tokenizer_get_char(self) == '=') { + ++self->index; + SET_BINOP(BINOP_EQUALS); + } else { + *token = TOK_EQUALS; + } } else if(c == '(') { ++self->index; *token = TOK_OPEN_PAREN; @@ -450,6 +471,18 @@ static BufferView tokenizer_expected_token_as_string(Token token) { case TOK_PUB: str = "pub"; break; + case TOK_IF: + str = "if"; + break; + case TOK_ELSE: + str = "else"; + break; + case TOK_WHILE: + str = "while"; + break; + case TOK_EXTERN: + str = "extern"; + break; } return create_buffer_view(str, strlen(str)); } @@ -588,18 +621,15 @@ int tokenizer_get_end_of_multiline_comment(Tokenizer *self, int index) { int comment_count; comment_count = 1; + ++index; while(index < (int)self->code.size) { c = self->code.data[index]; - if(c == '*') { - if(index - 1 >= 0 && self->code.data[index - 1] == '/') { - ++comment_count; - } - } else if(c == '/') { - if(index - 1 >= 0 && self->code.data[index - 1] == '*') { - --comment_count; - if(comment_count == 0) - return index + 1; - } + if(c == '*' && self->code.data[index - 1] == '/') { + ++comment_count; + } else if(c == '/' && self->code.data[index - 1] == '*') { + --comment_count; + if(comment_count == 0) + return index + 1; } ++index; } @@ -625,7 +655,61 @@ static int max(int a, int b) { return a > b ? a : b; } +void tokenizer_print_error_args(Tokenizer *self, int index, const char *fmt, va_list args) { + int line; + int line_start; + int line_end; + /*int code_start;*/ + int prev_column; + int i; + + line = tokenizer_get_line_by_index(self, index); + line_start = tokenizer_get_start_of_line_from_index(self, index); + line_end = tokenizer_get_end_of_line_from_index(self, index); + /*code_start = find_non_whitespace(&self->code.data[line_start], line_end - line_start); + if(code_start != -1) + line_start += code_start;*/ + prev_column = index - line_start; + + if(self->compiler_options->error_callback) { + char buffer[2048]; + int bytes_copied; + + bytes_copied = 0; + bytes_copied += max(0, snprintf(buffer + bytes_copied, sizeof(buffer) - bytes_copied, "%.*s:%d:%d: error: ", (int)self->code_name.size, self->code_name.data, line, 1 + prev_column)); + + if(sizeof(buffer) - bytes_copied > 0) { + bytes_copied += max(0, vsnprintf(buffer + bytes_copied, sizeof(buffer) - bytes_copied, fmt, args)); + } + + if(sizeof(buffer) - bytes_copied > 0) + bytes_copied += max(0, snprintf(buffer + bytes_copied, sizeof(buffer) - bytes_copied, "\n%.*s\n", line_end - line_start, self->code.data + line_start)); + + if(sizeof(buffer) - bytes_copied > 0) { + for(i = 0; i < prev_column; ++i) + bytes_copied += max(0, snprintf(buffer + bytes_copied, sizeof(buffer) - bytes_copied, " ")); + } + + if(sizeof(buffer) - bytes_copied > 0) + bytes_copied += max(0, snprintf(buffer + bytes_copied, sizeof(buffer) - bytes_copied, "^\n")); + + self->compiler_options->error_callback(buffer, bytes_copied, self->compiler_options->error_callback_userdata); + } else { + amal_mutex *mutex; + mutex = amal_log_get_mutex(); + ignore_result_int(amal_mutex_lock(mutex, "tokenizer_print_error")); + fprintf(stderr, "\x1b[1;37m%.*s:%d:%d:\x1b[0m \x1b[1;31merror:\x1b[0m ", (int)self->code_name.size, self->code_name.data, line, 1 + prev_column); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n%.*s\n", line_end - line_start, self->code.data + line_start); + for(i = 0; i < prev_column; ++i) + fprintf(stderr, " "); + fprintf(stderr, "\x1b[1;32m^\x1b[0m\n"); + ignore_result_int(amal_mutex_unlock(mutex)); + } +} + void tokenizer_print_error(Tokenizer *self, int index, const char *fmt, ...) { +#if 0 va_list args; int line; int line_start; @@ -681,6 +765,11 @@ void tokenizer_print_error(Tokenizer *self, int index, const char *fmt, ...) { va_end(args); ignore_result_int(amal_mutex_unlock(mutex)); } +#endif + va_list args; + va_start(args, fmt); + tokenizer_print_error_args(self, index, fmt, args); + va_end(args); } void tokenizer_print_error_object(Tokenizer *self, TokenizerError *error) { |