aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c58
1 files changed, 46 insertions, 12 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: {