aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-27 16:29:45 +0200
committerBad Diode <bd@badd10de.dev>2024-06-27 16:29:45 +0200
commit7f81a3e35ab0b02ef7695cb399cd7302e98d6296 (patch)
treeab68493e324d5bf2787205bd2223fbc3dd64f7d8
parentf3e0021067c03f5434e306eeea375f0f7aa62287 (diff)
downloadbdl-7f81a3e35ab0b02ef7695cb399cd7302e98d6296.tar.gz
bdl-7f81a3e35ab0b02ef7695cb399cd7302e98d6296.zip
Add initial pointer and array access/declaration typechecking
-rw-r--r--src/main.c58
-rw-r--r--src/parser.c3
-rw-r--r--tests/semantics.bad12
3 files changed, 56 insertions, 17 deletions
diff --git a/src/main.c b/src/main.c
index b0207f7..669984b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -57,6 +57,12 @@ typedef struct Symbol {
57 SymbolKind kind; 57 SymbolKind kind;
58} Symbol; 58} Symbol;
59 59
60typedef struct ArraySymbol {
61 Str name;
62 Str type;
63 sz size;
64} ArraySymbol;
65
60typedef struct Fun { 66typedef struct Fun {
61 Str name; 67 Str name;
62 Str param_type; 68 Str param_type;
@@ -74,6 +80,7 @@ typedef struct Struct {
74 Node *val; 80 Node *val;
75} Struct; 81} Struct;
76 82
83MAPDEF(ArrayMap, arraymap, Str, ArraySymbol, str_hash, str_eq)
77MAPDEF(SymbolMap, symmap, Str, Symbol, str_hash, str_eq) 84MAPDEF(SymbolMap, symmap, Str, Symbol, str_hash, str_eq)
78MAPDEF(FunMap, funmap, Str, Fun, str_hash, str_eq) 85MAPDEF(FunMap, funmap, Str, Fun, str_hash, str_eq)
79MAPDEF(EnumMap, enummap, Str, Enum, str_hash, str_eq) 86MAPDEF(EnumMap, enummap, Str, Enum, str_hash, str_eq)
@@ -87,6 +94,7 @@ typedef struct Scope {
87 FunMap *funcs; 94 FunMap *funcs;
88 EnumMap *enums; 95 EnumMap *enums;
89 StructMap *structs; 96 StructMap *structs;
97 ArrayMap *arrays;
90 struct Scope *parent; 98 struct Scope *parent;
91} Scope; 99} Scope;
92 100
@@ -478,6 +486,14 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
478 a->err = true; 486 a->err = true;
479 return cstr(""); 487 return cstr("");
480 } 488 }
489 if (node->var_type->is_ptr) {
490 type_name = str_concat(cstr("@"), type_name, a->storage);
491 }
492 if (node->var_type->kind == NODE_ARR_TYPE) {
493 type_name = str_concat(cstr("@"), type_name, a->storage);
494 // TODO: typecheck size
495 // TODO: register array in scope
496 }
481 if (node->var_val) { 497 if (node->var_val) {
482 Str type = type_inference(a, node->var_val, scope); 498 Str type = type_inference(a, node->var_val, scope);
483 if (!type.size) { 499 if (!type.size) {
@@ -506,7 +522,12 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
506 } 522 }
507 } 523 }
508 } 524 }
509 symmap_insert(&scope->symbols, symbol, type->val, a->storage); 525 symmap_insert(&scope->symbols, symbol,
526 (Symbol){
527 .name = type_name,
528 .kind = SYM_VAR,
529 },
530 a->storage);
510 return node->type; 531 return node->type;
511 } 532 }
512 533
@@ -856,6 +877,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
856 node->type = type->val.name; 877 node->type = type->val.name;
857 return node->type; 878 return node->type;
858 } break; 879 } break;
880 case NODE_SYMBOL_IDX:
859 case NODE_SYMBOL: { 881 case NODE_SYMBOL: {
860 Str symbol = node->value.str; 882 Str symbol = node->value.str;
861 SymbolMap *type = find_type(scope, symbol); 883 SymbolMap *type = find_type(scope, symbol);
@@ -865,9 +887,22 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
865 a->err = true; 887 a->err = true;
866 return cstr(""); 888 return cstr("");
867 } 889 }
890 Str type_name = type->val.name;
891 if (node->kind == NODE_SYMBOL_IDX) {
892 Str idx_type = type_inference(a, node->arr_size, scope);
893 if (!strset_lookup(&a->integer_types, idx_type)) {
894 emit_semantic_error(
895 a, node, cstr("can't resolve non integer index"));
896 return cstr("");
897 }
898 type_name = str_remove_prefix(type_name, cstr("@"));
899 }
900 if (node->is_ptr) {
901 type_name = str_concat(cstr("@"), type_name, a->storage);
902 }
868 903
869 FindEnumResult e = find_enum(scope, type->val.name); 904 FindEnumResult e = find_enum(scope, type_name);
870 if (e.map && str_eq(symbol, type->val.name)) { 905 if (e.map && str_eq(symbol, type_name)) {
871 if (!node->next) { 906 if (!node->next) {
872 eprintln( 907 eprintln(
873 "%s:%d:%d: error: unspecified enum field for symbol " 908 "%s:%d:%d: error: unspecified enum field for symbol "
@@ -877,7 +912,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
877 return cstr(""); 912 return cstr("");
878 } 913 }
879 // Check if there is a next and it matches the enum field. 914 // Check if there is a next and it matches the enum field.
880 Str field = str_concat(type->val.name, cstr("."), a->storage); 915 Str field = str_concat(type_name, cstr("."), a->storage);
881 field = str_concat(field, node->next->value.str, a->storage); 916 field = str_concat(field, node->next->value.str, a->storage);
882 if (!enummap_lookup(&e.scope->enums, field)) { 917 if (!enummap_lookup(&e.scope->enums, field)) {
883 eprintln( 918 eprintln(
@@ -888,24 +923,23 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
888 a->err = true; 923 a->err = true;
889 return cstr(""); 924 return cstr("");
890 } 925 }
891 node->next->type = type->val.name; 926 node->next->type = type_name;
892 node->type = type->val.name; 927 node->type = type_name;
893 return node->next->type; 928 return node->next->type;
894 } 929 }
895 930
896 FindStructResult s = find_struct(scope, type->val.name); 931 FindStructResult s = find_struct(scope, type_name);
897 if (s.map) { 932 if (s.map) {
898 if (str_eq(symbol, type->val.name)) { 933 if (str_eq(symbol, type_name)) {
899 eprintln( 934 eprintln(
900 "%s:%d:%d: error: struct incomplete struct literal " 935 "%s:%d:%d: error: struct incomplete struct literal "
901 "'%s', did you mean to use %s:{}?", 936 "'%s', did you mean to use %s:{}?",
902 a->file_name, node->line, node->col, symbol, 937 a->file_name, node->line, node->col, symbol, symbol);
903 symbol);
904 a->err = true; 938 a->err = true;
905 return cstr(""); 939 return cstr("");
906 } else { 940 } else {
907 if (node->next) { 941 if (node->next) {
908 Str chain = type->val.name; 942 Str chain = type_name;
909 Node *next = node; 943 Node *next = node;
910 while (next->next) { 944 while (next->next) {
911 next = next->next; 945 next = next->next;
@@ -927,7 +961,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
927 } 961 }
928 } 962 }
929 } 963 }
930 node->type = type->val.name; 964 node->type = type_name;
931 return node->type; 965 return node->type;
932 } break; 966 } break;
933 case NODE_STRUCT_LIT: { 967 case NODE_STRUCT_LIT: {
diff --git a/src/parser.c b/src/parser.c
index ce8eef8..cdd3c47 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -976,8 +976,7 @@ parse_symbol(Parser *parser) {
976 } 976 }
977 } else if (parse_match(parser, TOK_LSQUARE)) { 977 } else if (parse_match(parser, TOK_LSQUARE)) {
978 node->kind = NODE_SYMBOL_IDX; 978 node->kind = NODE_SYMBOL_IDX;
979 parse_consume(parser, TOK_NUM_INT, cstr("no array size given")); 979 parse_expr(parser, PREC_LOW);
980 parse_number(parser);
981 node->arr_size = array_pop(parser->nodes); 980 node->arr_size = array_pop(parser->nodes);
982 parse_consume(parser, TOK_RSQUARE, 981 parse_consume(parser, TOK_RSQUARE,
983 cstr("unmatched brackets ']' in array type")); 982 cstr("unmatched brackets ']' in array type"));
diff --git a/tests/semantics.bad b/tests/semantics.bad
index b0cc26e..1bb2ceb 100644
--- a/tests/semantics.bad
+++ b/tests/semantics.bad
@@ -1,8 +1,14 @@
1; We can have static arrays and have indexed access. 1; We can have static arrays and have indexed access.
2; let numbers: int[0xff] 2let a = 1
3let numbers: int[0xff] 3let numbers: @int
4set numbers[0] = 32 4set numbers[a] = 32
5set numbers[1] = numbers[0] 5set numbers[1] = numbers[0]
6let numbers_arr: int[0xff]
7set numbers_arr[0] = numbers[0]
8let ptr_arr: @int[0xff]
9set ptr_arr[0] = @numbers[0]
10
11; TODO: test pointers/arrays on structs
6 12
7; ; Arrays are syntactic sugar for pointers (@). 13; ; Arrays are syntactic sugar for pointers (@).
8; let ptr:@u32 = numbers 14; let ptr:@u32 = numbers