aboutsummaryrefslogtreecommitdiff
path: root/src/tokenizer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tokenizer.c')
-rw-r--r--src/tokenizer.c111
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) {