aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2022-04-25 11:17:12 -0300
committerBad Diode <bd@badd10de.dev>2022-04-25 11:17:12 -0300
commitcc8600eaff00904650c21052d3e2be2508410876 (patch)
tree8910f8ff68d4d1c728f6bd5539cf851c4f4e1386
parent46c86de715afcf15af6dc4532969d0736a3a2e48 (diff)
downloadbdl-cc8600eaff00904650c21052d3e2be2508410876.tar.gz
bdl-cc8600eaff00904650c21052d3e2be2508410876.zip
Add more error types for different pipeline stages
-rw-r--r--src/errors.c2
-rw-r--r--src/errors.h2
-rw-r--r--src/ir.c28
-rw-r--r--src/semantic.c30
4 files changed, 46 insertions, 16 deletions
diff --git a/src/errors.c b/src/errors.c
index 6a69064..e854cf0 100644
--- a/src/errors.c
+++ b/src/errors.c
@@ -59,6 +59,8 @@ check_errors(const char *file_name) {
59 switch (current_error.type) { 59 switch (current_error.type) {
60 case ERR_TYPE_LEXER: { fprintf(stderr, ": [lexer] "); } break; 60 case ERR_TYPE_LEXER: { fprintf(stderr, ": [lexer] "); } break;
61 case ERR_TYPE_PARSER: { fprintf(stderr, ": [parser] "); } break; 61 case ERR_TYPE_PARSER: { fprintf(stderr, ": [parser] "); } break;
62 case ERR_TYPE_SEMANTIC: { fprintf(stderr, ": [semantic] "); } break;
63 case ERR_TYPE_BASM: { fprintf(stderr, ": [basm] "); } break;
62 default: break; 64 default: break;
63 } 65 }
64 fprintf(stderr, "%s\n", error_msgs[current_error.value]); 66 fprintf(stderr, "%s\n", error_msgs[current_error.value]);
diff --git a/src/errors.h b/src/errors.h
index f2737d0..8ddba25 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -6,6 +6,8 @@
6typedef enum ErrorType { 6typedef enum ErrorType {
7 ERR_TYPE_LEXER, 7 ERR_TYPE_LEXER,
8 ERR_TYPE_PARSER, 8 ERR_TYPE_PARSER,
9 ERR_TYPE_SEMANTIC,
10 ERR_TYPE_BASM,
9} ErrorType; 11} ErrorType;
10 12
11typedef enum ErrorValue { 13typedef enum ErrorValue {
diff --git a/src/ir.c b/src/ir.c
index 2b289d9..075ebe3 100644
--- a/src/ir.c
+++ b/src/ir.c
@@ -173,7 +173,7 @@ emit_builtin(ProgramBASM *program, Node *node) {
173 case TOKEN_LE: { return emit_numcomp(program, node, OP_JMP_GT); } break; 173 case TOKEN_LE: { return emit_numcomp(program, node, OP_JMP_GT); } break;
174 case TOKEN_GE: { return emit_numcomp(program, node, OP_JMP_LT); } break; 174 case TOKEN_GE: { return emit_numcomp(program, node, OP_JMP_LT); } break;
175 default: { 175 default: {
176 // TODO: assert unreachable. 176 push_error(ERR_TYPE_BASM, ERR_UNIMPLEMENTED, node->line, node->col);
177 return (Operand){0}; 177 return (Operand){0};
178 } break; 178 } break;
179 } 179 }
@@ -190,12 +190,36 @@ emit_number(ProgramBASM *program, Node *node) {
190} 190}
191 191
192Operand 192Operand
193emit_bool(ProgramBASM *program, Node *node) {
194 LineInfo line = (LineInfo){.line = node->line, .col = node->col};
195 Operand reg_dst = NEW_REG();
196 Operand val;
197 if (node->boolean) {
198 val = NEW_S64(1);
199 } else {
200 val = NEW_S64(0);
201 }
202 EMIT_1(program, line, OP_LD8, reg_dst, val);
203 return reg_dst;
204}
205
206// TODO: emit_if
207// TODO: emit_and
208// TODO: emit_or
209// TODO: emit_not
210// TODO: emit_global
211// TODO: emit_local
212// TODO: emit_procedure
213// TODO: emit_proc_call
214
215Operand
193emit_basm(ProgramBASM *program, Node *node) { 216emit_basm(ProgramBASM *program, Node *node) {
194 switch (node->type) { 217 switch (node->type) {
218 case NODE_BOOL: { return emit_bool(program, node); } break;
195 case NODE_NUMBER: { return emit_number(program, node); } break; 219 case NODE_NUMBER: { return emit_number(program, node); } break;
196 case NODE_BUILTIN: { return emit_builtin(program, node); } break; 220 case NODE_BUILTIN: { return emit_builtin(program, node); } break;
197 default: { 221 default: {
198 printf("UNIMPLEMENTED\n"); 222 push_error(ERR_TYPE_BASM, ERR_UNIMPLEMENTED, node->line, node->col);
199 return (Operand){0}; 223 return (Operand){0};
200 } break; 224 } break;
201 } 225 }
diff --git a/src/semantic.c b/src/semantic.c
index 22d290e..fe88249 100644
--- a/src/semantic.c
+++ b/src/semantic.c
@@ -130,7 +130,7 @@ find_type(Scope *scope, Node *type) {
130 } 130 }
131 scope = scope->parent; 131 scope = scope->parent;
132 } 132 }
133 push_error(ERR_TYPE_PARSER, ERR_UNKNOWN_TYPE, type->line, type->col); 133 push_error(ERR_TYPE_SEMANTIC, ERR_UNKNOWN_TYPE, type->line, type->col);
134 return NULL; 134 return NULL;
135} 135}
136 136
@@ -139,7 +139,7 @@ insert_symbol(Scope *scope, Node *symbol, Symbol *val) {
139 // Check if symbol already exists. 139 // Check if symbol already exists.
140 HashTable *symbols = scope->symbols; 140 HashTable *symbols = scope->symbols;
141 if (ht_lookup(symbols, symbol) != NULL) { 141 if (ht_lookup(symbols, symbol) != NULL) {
142 push_error(ERR_TYPE_PARSER, ERR_SYMBOL_REDEF, symbol->line, symbol->col); 142 push_error(ERR_TYPE_SEMANTIC, ERR_SYMBOL_REDEF, symbol->line, symbol->col);
143 return false; 143 return false;
144 } 144 }
145 ht_insert(symbols, symbol, val); 145 ht_insert(symbols, symbol, val);
@@ -214,7 +214,7 @@ find_symbol(Scope *scope, Node *node) {
214 } 214 }
215 scope = scope->parent; 215 scope = scope->parent;
216 } 216 }
217 push_error(ERR_TYPE_PARSER, ERR_UNKNOWN_SYMBOL, node->line, node->col); 217 push_error(ERR_TYPE_SEMANTIC, ERR_UNKNOWN_SYMBOL, node->line, node->col);
218 return NULL; 218 return NULL;
219} 219}
220 220
@@ -244,7 +244,7 @@ resolve_type(ParseTree *ast, Scope *scope, Node *node) {
244 244
245 // Check that all arguments are numbers. 245 // Check that all arguments are numbers.
246 if (!type_is_numeric(arg->expr_type)) { 246 if (!type_is_numeric(arg->expr_type)) {
247 push_error(ERR_TYPE_PARSER, ERR_WRONG_TYPE_NUM, 247 push_error(ERR_TYPE_SEMANTIC, ERR_WRONG_TYPE_NUM,
248 arg->line, arg->col); 248 arg->line, arg->col);
249 return false; 249 return false;
250 } 250 }
@@ -259,13 +259,15 @@ resolve_type(ParseTree *ast, Scope *scope, Node *node) {
259 } break; 259 } break;
260 // Bools. 260 // Bools.
261 case TOKEN_NOT: 261 case TOKEN_NOT:
262 // TODO: not should only take one argument and
263 // return the inverse.
262 case TOKEN_AND: 264 case TOKEN_AND:
263 case TOKEN_OR: { 265 case TOKEN_OR: {
264 // Check that all arguments are boolean. 266 // Check that all arguments are boolean.
265 for (size_t i = 0; i < array_size(node->builtin.args); ++i) { 267 for (size_t i = 0; i < array_size(node->builtin.args); ++i) {
266 Node *arg = node->builtin.args[i]; 268 Node *arg = node->builtin.args[i];
267 if (arg->expr_type != &default_types[TYPE_BOOL]) { 269 if (arg->expr_type != &default_types[TYPE_BOOL]) {
268 push_error(ERR_TYPE_PARSER, ERR_WRONG_TYPE_BOOL, 270 push_error(ERR_TYPE_SEMANTIC, ERR_WRONG_TYPE_BOOL,
269 arg->line, arg->col); 271 arg->line, arg->col);
270 return false; 272 return false;
271 } 273 }
@@ -283,7 +285,7 @@ resolve_type(ParseTree *ast, Scope *scope, Node *node) {
283 // TODO: Make sure all arguments have the same type, 285 // TODO: Make sure all arguments have the same type,
284 // like with numeric expressions. 286 // like with numeric expressions.
285 if (!type_is_numeric(arg->expr_type)) { 287 if (!type_is_numeric(arg->expr_type)) {
286 push_error(ERR_TYPE_PARSER, ERR_WRONG_TYPE_NUM, 288 push_error(ERR_TYPE_SEMANTIC, ERR_WRONG_TYPE_NUM,
287 arg->line, arg->col); 289 arg->line, arg->col);
288 return false; 290 return false;
289 } 291 }
@@ -354,7 +356,7 @@ resolve_type(ParseTree *ast, Scope *scope, Node *node) {
354 StringView *type_body = &node->fun.body->expr_type->name; 356 StringView *type_body = &node->fun.body->expr_type->name;
355 StringView *return_type = &node->fun.return_type->string; 357 StringView *return_type = &node->fun.return_type->string;
356 if (!sv_equal(type_body, return_type)) { 358 if (!sv_equal(type_body, return_type)) {
357 push_error(ERR_TYPE_PARSER, ERR_WRONG_RET_TYPE, node->line, node->col); 359 push_error(ERR_TYPE_SEMANTIC, ERR_WRONG_RET_TYPE, node->line, node->col);
358 return false; 360 return false;
359 } 361 }
360 } break; 362 } break;
@@ -390,7 +392,7 @@ resolve_type(ParseTree *ast, Scope *scope, Node *node) {
390 // Check ifexpr.cond is a bool. 392 // Check ifexpr.cond is a bool.
391 Type *type_cond = node->ifexpr.cond->expr_type; 393 Type *type_cond = node->ifexpr.cond->expr_type;
392 if (!sv_equal(&type_cond->name, &default_types[TYPE_BOOL].name)) { 394 if (!sv_equal(&type_cond->name, &default_types[TYPE_BOOL].name)) {
393 push_error(ERR_TYPE_PARSER, ERR_WRONG_COND_TYPE, 395 push_error(ERR_TYPE_SEMANTIC, ERR_WRONG_COND_TYPE,
394 node->line, node->col); 396 node->line, node->col);
395 return false; 397 return false;
396 } 398 }
@@ -401,7 +403,7 @@ resolve_type(ParseTree *ast, Scope *scope, Node *node) {
401 if (type_is_numeric(type_true) && type_is_numeric(type_false)) { 403 if (type_is_numeric(type_true) && type_is_numeric(type_false)) {
402 node->expr_type = coerce_numeric_types(type_true, type_false); 404 node->expr_type = coerce_numeric_types(type_true, type_false);
403 } else if (!sv_equal(&type_true->name, &type_false->name)) { 405 } else if (!sv_equal(&type_true->name, &type_false->name)) {
404 push_error(ERR_TYPE_PARSER, ERR_WRONG_TYPE_T_F, 406 push_error(ERR_TYPE_SEMANTIC, ERR_WRONG_TYPE_T_F,
405 node->line, node->col); 407 node->line, node->col);
406 return false; 408 return false;
407 } 409 }
@@ -418,7 +420,7 @@ resolve_type(ParseTree *ast, Scope *scope, Node *node) {
418 Node *symbol = node->set.symbol; 420 Node *symbol = node->set.symbol;
419 Node *value = node->set.value; 421 Node *value = node->set.value;
420 if (!sv_equal(&symbol->expr_type->name, &value->expr_type->name)) { 422 if (!sv_equal(&symbol->expr_type->name, &value->expr_type->name)) {
421 push_error(ERR_TYPE_PARSER, ERR_TYPE_MISMATCH, 423 push_error(ERR_TYPE_SEMANTIC, ERR_TYPE_MISMATCH,
422 node->line, node->col); 424 node->line, node->col);
423 return false; 425 return false;
424 } 426 }
@@ -446,7 +448,7 @@ resolve_type(ParseTree *ast, Scope *scope, Node *node) {
446 Node *symbol = node->def.symbol; 448 Node *symbol = node->def.symbol;
447 Node *value = node->def.value; 449 Node *value = node->def.value;
448 if (!sv_equal(&symbol->expr_type->name, &value->expr_type->name)) { 450 if (!sv_equal(&symbol->expr_type->name, &value->expr_type->name)) {
449 push_error(ERR_TYPE_PARSER, ERR_TYPE_MISMATCH, 451 push_error(ERR_TYPE_SEMANTIC, ERR_TYPE_MISMATCH,
450 node->line, node->col); 452 node->line, node->col);
451 return false; 453 return false;
452 } 454 }
@@ -474,12 +476,12 @@ resolve_type(ParseTree *ast, Scope *scope, Node *node) {
474 return false; 476 return false;
475 } 477 }
476 if (val->type != SYMBOL_FUN) { 478 if (val->type != SYMBOL_FUN) {
477 push_error(ERR_TYPE_PARSER, ERR_WRONG_TYPE_FUN, 479 push_error(ERR_TYPE_SEMANTIC, ERR_WRONG_TYPE_FUN,
478 node->funcall.name->line, node->funcall.name->col); 480 node->funcall.name->line, node->funcall.name->col);
479 return false; 481 return false;
480 } 482 }
481 if (array_size(node->funcall.args) != array_size(val->fun.param_types)) { 483 if (array_size(node->funcall.args) != array_size(val->fun.param_types)) {
482 push_error(ERR_TYPE_PARSER, ERR_BAD_ARGS, node->line, node->col); 484 push_error(ERR_TYPE_SEMANTIC, ERR_BAD_ARGS, node->line, node->col);
483 return false; 485 return false;
484 } 486 }
485 node->expr_type = node->funcall.name->expr_type; 487 node->expr_type = node->funcall.name->expr_type;
@@ -490,7 +492,7 @@ resolve_type(ParseTree *ast, Scope *scope, Node *node) {
490 } 492 }
491 Node *expected = val->fun.param_types[i]; 493 Node *expected = val->fun.param_types[i];
492 if (!sv_equal(&arg->expr_type->name, &expected->string)) { 494 if (!sv_equal(&arg->expr_type->name, &expected->string)) {
493 push_error(ERR_TYPE_PARSER, ERR_TYPE_MISMATCH, 495 push_error(ERR_TYPE_SEMANTIC, ERR_TYPE_MISMATCH,
494 arg->line, arg->col); 496 arg->line, arg->col);
495 return false; 497 return false;
496 } 498 }