aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-26 16:30:57 +0200
committerBad Diode <bd@badd10de.dev>2024-06-26 16:30:57 +0200
commita93323df87caeb345df74a2141c72d591db91c7b (patch)
tree919881d8de05040b6cc8675189d093dce88ac890 /src
parent56510571a9d2c6c1242d5efc26c4ab2905269930 (diff)
downloadbdl-a93323df87caeb345df74a2141c72d591db91c7b.tar.gz
bdl-a93323df87caeb345df74a2141c72d591db91c7b.zip
Add err to analyzer context
Diffstat (limited to 'src')
-rw-r--r--src/main.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/src/main.c b/src/main.c
index 7e95e2e..5c99a10 100644
--- a/src/main.c
+++ b/src/main.c
@@ -10,7 +10,6 @@
10// TODO: unions 10// TODO: unions
11// TODO: match deconstruct enums 11// TODO: match deconstruct enums
12// TODO: arrays and pointers 12// TODO: arrays and pointers
13// TODO: if we have errors make sure we mark the analyzer as such
14 13
15typedef enum ExecMode { 14typedef enum ExecMode {
16 RUN_NORMAL, 15 RUN_NORMAL,
@@ -98,6 +97,7 @@ typedef struct Analyzer {
98 Scope **scopes; 97 Scope **scopes;
99 StrSet *numeric_types; 98 StrSet *numeric_types;
100 StrSet *integer_types; 99 StrSet *integer_types;
100 bool err;
101} Analyzer; 101} Analyzer;
102 102
103Scope * 103Scope *
@@ -274,6 +274,7 @@ graph_types(Scope **scopes, Arena a) {
274void 274void
275emit_semantic_error(Analyzer *a, Node *n, Str msg) { 275emit_semantic_error(Analyzer *a, Node *n, Str msg) {
276 eprintln("%s:%d:%d: error: %s", a->file_name, n->line, n->col, msg); 276 eprintln("%s:%d:%d: error: %s", a->file_name, n->line, n->col, msg);
277 a->err = true;
277} 278}
278 279
279Str type_inference(Analyzer *a, Node *node, Scope *scope); 280Str type_inference(Analyzer *a, Node *node, Scope *scope);
@@ -286,6 +287,7 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
286 if (structmap_lookup(&scope->structs, field_name)) { 287 if (structmap_lookup(&scope->structs, field_name)) {
287 eprintln("%s:%d:%d: error: struct field '%s' already exists", 288 eprintln("%s:%d:%d: error: struct field '%s' already exists",
288 a->file_name, node->line, node->col, field_name); 289 a->file_name, node->line, node->col, field_name);
290 a->err = true;
289 } 291 }
290 Str type = cstr("\\{ "); 292 Str type = cstr("\\{ ");
291 for (sz i = 0; i < array_size(node->field_type->elements); i++) { 293 for (sz i = 0; i < array_size(node->field_type->elements); i++) {
@@ -303,10 +305,12 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
303 if (!find_type(scope, field_type)) { 305 if (!find_type(scope, field_type)) {
304 eprintln("%s:%d:%d: error: unknown type '%s'", a->file_name, 306 eprintln("%s:%d:%d: error: unknown type '%s'", a->file_name,
305 node->field_type->line, node->field_type->col, field_type); 307 node->field_type->line, node->field_type->col, field_type);
308 a->err = true;
306 } 309 }
307 if (structmap_lookup(&scope->structs, field_name)) { 310 if (structmap_lookup(&scope->structs, field_name)) {
308 eprintln("%s:%d:%d: error: struct field '%s' already exists", 311 eprintln("%s:%d:%d: error: struct field '%s' already exists",
309 a->file_name, node->line, node->col, field_name); 312 a->file_name, node->line, node->col, field_name);
313 a->err = true;
310 } 314 }
311 if (node->field_val) { 315 if (node->field_val) {
312 Str type = type_inference(a, node->field_val, scope); 316 Str type = type_inference(a, node->field_val, scope);
@@ -317,6 +321,7 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
317 "for '%s': %s expected %s", 321 "for '%s': %s expected %s",
318 a->file_name, node->line, node->col, field_name, type, 322 a->file_name, node->line, node->col, field_name, type,
319 field_type); 323 field_type);
324 a->err = true;
320 } 325 }
321 } 326 }
322 structmap_insert(&scope->structs, field_name, 327 structmap_insert(&scope->structs, field_name,
@@ -352,6 +357,7 @@ typecheck_lit_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
352 if (!s) { 357 if (!s) {
353 eprintln("%s:%d:%d: error: unknown struct field '%s'", a->file_name, 358 eprintln("%s:%d:%d: error: unknown struct field '%s'", a->file_name,
354 node->line, node->col, symbol); 359 node->line, node->col, symbol);
360 a->err = true;
355 return; 361 return;
356 } 362 }
357 Str field_type = s->val.type; 363 Str field_type = s->val.type;
@@ -362,6 +368,7 @@ typecheck_lit_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
362 "value " 368 "value "
363 "for '%s': %s expected %s", 369 "for '%s': %s expected %s",
364 a->file_name, node->line, node->col, symbol, type, field_type); 370 a->file_name, node->line, node->col, symbol, type, field_type);
371 a->err = true;
365 } 372 }
366 node->type = field_type; 373 node->type = field_type;
367 } 374 }
@@ -387,6 +394,7 @@ typecheck_returns(Analyzer *a, Node *node, Str expected) {
387 eprintln( 394 eprintln(
388 "%s:%d:%d: error: mismatched return type %s, expected %s", 395 "%s:%d:%d: error: mismatched return type %s, expected %s",
389 a->file_name, node->line, node->col, node->type, expected); 396 a->file_name, node->line, node->col, node->type, expected);
397 a->err = true;
390 } 398 }
391 } break; 399 } break;
392 case NODE_BLOCK: { 400 case NODE_BLOCK: {
@@ -457,6 +465,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
457 "scope ", 465 "scope ",
458 a->file_name, node->var_name->line, node->var_name->col, 466 a->file_name, node->var_name->line, node->var_name->col,
459 symbol); 467 symbol);
468 a->err = true;
460 return cstr(""); 469 return cstr("");
461 } 470 }
462 if (node->var_type) { 471 if (node->var_type) {
@@ -466,6 +475,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
466 eprintln("%s:%d:%d: error: unknown type '%s'", a->file_name, 475 eprintln("%s:%d:%d: error: unknown type '%s'", a->file_name,
467 node->var_type->line, node->var_type->col, 476 node->var_type->line, node->var_type->col,
468 type_name); 477 type_name);
478 a->err = true;
469 return cstr(""); 479 return cstr("");
470 } 480 }
471 if (node->var_val) { 481 if (node->var_val) {
@@ -476,6 +486,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
476 "'%s'", 486 "'%s'",
477 a->file_name, node->var_type->line, 487 a->file_name, node->var_type->line,
478 node->var_type->col, symbol); 488 node->var_type->col, symbol);
489 a->err = true;
479 return cstr(""); 490 return cstr("");
480 } 491 }
481 // TODO: Consider compatible types. 492 // TODO: Consider compatible types.
@@ -490,6 +501,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
490 " to a variable of type %s", 501 " to a variable of type %s",
491 a->file_name, node->var_type->line, 502 a->file_name, node->var_type->line,
492 node->var_type->col, type, type_name); 503 node->var_type->col, type, type_name);
504 a->err = true;
493 return cstr(""); 505 return cstr("");
494 } 506 }
495 } 507 }
@@ -517,6 +529,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
517 "%s" 529 "%s"
518 " to a variable of type %s", 530 " to a variable of type %s",
519 a->file_name, node->line, node->col, val, name); 531 a->file_name, node->line, node->col, val, name);
532 a->err = true;
520 return cstr(""); 533 return cstr("");
521 } 534 }
522 node->type = cstr("nil"); 535 node->type = cstr("nil");
@@ -530,6 +543,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
530 "%s:%d:%d: error: struct '%s' already exists in current " 543 "%s:%d:%d: error: struct '%s' already exists in current "
531 "scope", 544 "scope",
532 a->file_name, node->line, node->col, symbol); 545 a->file_name, node->line, node->col, symbol);
546 a->err = true;
533 return cstr(""); 547 return cstr("");
534 } 548 }
535 structmap_insert(&scope->structs, symbol, (Struct){.name = symbol}, 549 structmap_insert(&scope->structs, symbol, (Struct){.name = symbol},
@@ -551,6 +565,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
551 "%s:%d:%d: error: enum '%s' already exists in current " 565 "%s:%d:%d: error: enum '%s' already exists in current "
552 "scope", 566 "scope",
553 a->file_name, node->line, node->col, symbol); 567 a->file_name, node->line, node->col, symbol);
568 a->err = true;
554 return cstr(""); 569 return cstr("");
555 } 570 }
556 enummap_insert(&scope->enums, symbol, 571 enummap_insert(&scope->enums, symbol,
@@ -567,6 +582,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
567 if (enummap_lookup(&scope->enums, field_name)) { 582 if (enummap_lookup(&scope->enums, field_name)) {
568 eprintln("%s:%d:%d: error: enum field '%s' already exists", 583 eprintln("%s:%d:%d: error: enum field '%s' already exists",
569 a->file_name, field->line, field->col, field_name); 584 a->file_name, field->line, field->col, field_name);
585 a->err = true;
570 } 586 }
571 if (field->field_val) { 587 if (field->field_val) {
572 Str type = type_inference(a, field->field_val, scope); 588 Str type = type_inference(a, field->field_val, scope);
@@ -575,6 +591,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
575 "%s:%d:%d: error: non int enum value for '%s.%s'", 591 "%s:%d:%d: error: non int enum value for '%s.%s'",
576 a->file_name, field->line, field->col, symbol, 592 a->file_name, field->line, field->col, symbol,
577 field_name); 593 field_name);
594 a->err = true;
578 } 595 }
579 } 596 }
580 enummap_insert(&scope->enums, field_name, 597 enummap_insert(&scope->enums, field_name,
@@ -803,6 +820,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
803 if (!type) { 820 if (!type) {
804 eprintln("%s:%d:%d: error: couldn't resolve symbol '%s'", 821 eprintln("%s:%d:%d: error: couldn't resolve symbol '%s'",
805 a->file_name, node->line, node->col, symbol); 822 a->file_name, node->line, node->col, symbol);
823 a->err = true;
806 return cstr(""); 824 return cstr("");
807 } 825 }
808 826
@@ -813,6 +831,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
813 "%s:%d:%d: error: unspecified enum field for symbol " 831 "%s:%d:%d: error: unspecified enum field for symbol "
814 "'%s'", 832 "'%s'",
815 a->file_name, node->line, node->col, symbol); 833 a->file_name, node->line, node->col, symbol);
834 a->err = true;
816 return cstr(""); 835 return cstr("");
817 } 836 }
818 // Check if there is a next and it matches the enum field. 837 // Check if there is a next and it matches the enum field.
@@ -824,6 +843,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
824 "'%s': %s", 843 "'%s': %s",
825 a->file_name, node->line, node->col, symbol, 844 a->file_name, node->line, node->col, symbol,
826 node->next->value.str); 845 node->next->value.str);
846 a->err = true;
827 return cstr(""); 847 return cstr("");
828 } 848 }
829 node->next->type = cstr("int"); 849 node->next->type = cstr("int");
@@ -839,6 +859,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
839 "'%s', did you mean to use %s:{}?", 859 "'%s', did you mean to use %s:{}?",
840 a->file_name, node->line, node->col, type->val, 860 a->file_name, node->line, node->col, type->val,
841 type->val); 861 type->val);
862 a->err = true;
842 return cstr(""); 863 return cstr("");
843 } else { 864 } else {
844 if (node->next) { 865 if (node->next) {
@@ -856,6 +877,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
856 eprintln( 877 eprintln(
857 "%s:%d:%d: error: unknown struct field '%s'", 878 "%s:%d:%d: error: unknown struct field '%s'",
858 a->file_name, node->line, node->col, chain); 879 a->file_name, node->line, node->col, chain);
880 a->err = true;
859 return cstr(""); 881 return cstr("");
860 } 882 }
861 node->type = field->val.type; 883 node->type = field->val.type;
@@ -872,6 +894,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
872 if (!s.map) { 894 if (!s.map) {
873 eprintln("%s:%d:%d: error: unknown struct type '%s'", 895 eprintln("%s:%d:%d: error: unknown struct type '%s'",
874 a->file_name, node->line, node->col, name); 896 a->file_name, node->line, node->col, name);
897 a->err = true;
875 return cstr(""); 898 return cstr("");
876 } 899 }
877 900
@@ -887,6 +910,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
887 "%s:%d:%d: error: field '%s' already present in struct " 910 "%s:%d:%d: error: field '%s' already present in struct "
888 "literal", 911 "literal",
889 a->file_name, next->line, next->col, field_name); 912 a->file_name, next->line, next->col, field_name);
913 a->err = true;
890 } else { 914 } else {
891 strset_insert(&set, field_name, a->storage); 915 strset_insert(&set, field_name, a->storage);
892 } 916 }
@@ -903,6 +927,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
903 "%s:%d:%d: error: function '%s' doesn't exist in current " 927 "%s:%d:%d: error: function '%s' doesn't exist in current "
904 "scope ", 928 "scope ",
905 a->file_name, node->line, node->col, symbol); 929 a->file_name, node->line, node->col, symbol);
930 a->err = true;
906 return cstr(""); 931 return cstr("");
907 } 932 }
908 // Check that actual parameters typecheck 933 // Check that actual parameters typecheck
@@ -924,6 +949,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
924 "%s:%d:%d: error: mismatched parameter types: %s expected " 949 "%s:%d:%d: error: mismatched parameter types: %s expected "
925 "%s", 950 "%s",
926 a->file_name, node->line, node->col, args, expected); 951 a->file_name, node->line, node->col, args, expected);
952 a->err = true;
927 } 953 }
928 node->type = fun->val.return_type; 954 node->type = fun->val.return_type;
929 return node->type; 955 return node->type;
@@ -1002,6 +1028,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
1002 "scope ", 1028 "scope ",
1003 a->file_name, node->var_name->line, node->var_name->col, 1029 a->file_name, node->var_name->line, node->var_name->col,
1004 symbol); 1030 symbol);
1031 a->err = true;
1005 return cstr(""); 1032 return cstr("");
1006 } 1033 }
1007 symmap_insert(&scope->symbols, symbol, 1034 symmap_insert(&scope->symbols, symbol,
@@ -1035,6 +1062,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
1035 "%s:%d:%d: error: mismatched return type %s, expected %s", 1062 "%s:%d:%d: error: mismatched return type %s, expected %s",
1036 a->file_name, node->line, node->col, node->func_body->type, 1063 a->file_name, node->line, node->col, node->func_body->type,
1037 ret_type); 1064 ret_type);
1065 a->err = true;
1038 } 1066 }
1039 1067
1040 // Ensure ALL return statements match the function prototype. 1068 // Ensure ALL return statements match the function prototype.
@@ -1115,6 +1143,7 @@ symbolic_analysis(Analyzer *a, Parser *parser) {
1115 "scope ", 1143 "scope ",
1116 a->file_name, root->var_name->line, root->var_name->col, 1144 a->file_name, root->var_name->line, root->var_name->col,
1117 symbol); 1145 symbol);
1146 a->err = true;
1118 } 1147 }
1119 symmap_insert(&scope->symbols, symbol, 1148 symmap_insert(&scope->symbols, symbol,
1120 (Symbol){.name = symbol, .kind = SYM_FUN}, 1149 (Symbol){.name = symbol, .kind = SYM_FUN},
@@ -1198,10 +1227,12 @@ process_file(Str path) {
1198 .file_name = path, 1227 .file_name = path,
1199 }; 1228 };
1200 symbolic_analysis(&analyzer, &parser); 1229 symbolic_analysis(&analyzer, &parser);
1230 if (analyzer.err) {
1231 exit(EXIT_FAILURE);
1232 }
1201 1233
1202 // Printing symbol tables. 1234 // Printing symbol tables.
1203 if (mode == PRINT_SYMTABLES) { 1235 if (mode == PRINT_SYMTABLES) {
1204 // graph_symbols(analyzer.scopes, lexer_arena);
1205 graph_types(analyzer.scopes, lexer_arena); 1236 graph_types(analyzer.scopes, lexer_arena);
1206 } 1237 }
1207 if (mode == PRINT_SEMANTIC) { 1238 if (mode == PRINT_SEMANTIC) {