diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 32 |
1 files changed, 22 insertions, 10 deletions
@@ -8,8 +8,9 @@ | |||
8 | #include "vm.c" | 8 | #include "vm.c" |
9 | 9 | ||
10 | // TODO: unions | 10 | // TODO: unions |
11 | // TODO: arrays and pointers | ||
12 | // TODO: embed (binary file) and include (source file) | 11 | // TODO: embed (binary file) and include (source file) |
12 | // TODO: revisit ast parsing for pointers and arrays (I think I'm missing corner | ||
13 | // cases). | ||
13 | 14 | ||
14 | typedef enum ExecMode { | 15 | typedef enum ExecMode { |
15 | RUN_NORMAL, | 16 | RUN_NORMAL, |
@@ -57,12 +58,6 @@ typedef struct Symbol { | |||
57 | SymbolKind kind; | 58 | SymbolKind kind; |
58 | } Symbol; | 59 | } Symbol; |
59 | 60 | ||
60 | typedef struct ArraySymbol { | ||
61 | Str name; | ||
62 | Str type; | ||
63 | sz size; | ||
64 | } ArraySymbol; | ||
65 | |||
66 | typedef struct Fun { | 61 | typedef struct Fun { |
67 | Str name; | 62 | Str name; |
68 | Str param_type; | 63 | Str param_type; |
@@ -80,7 +75,6 @@ typedef struct Struct { | |||
80 | Node *val; | 75 | Node *val; |
81 | } Struct; | 76 | } Struct; |
82 | 77 | ||
83 | MAPDEF(ArrayMap, arraymap, Str, ArraySymbol, str_hash, str_eq) | ||
84 | MAPDEF(SymbolMap, symmap, Str, Symbol, str_hash, str_eq) | 78 | MAPDEF(SymbolMap, symmap, Str, Symbol, str_hash, str_eq) |
85 | MAPDEF(FunMap, funmap, Str, Fun, str_hash, str_eq) | 79 | MAPDEF(FunMap, funmap, Str, Fun, str_hash, str_eq) |
86 | MAPDEF(EnumMap, enummap, Str, Enum, str_hash, str_eq) | 80 | MAPDEF(EnumMap, enummap, Str, Enum, str_hash, str_eq) |
@@ -94,7 +88,6 @@ typedef struct Scope { | |||
94 | FunMap *funcs; | 88 | FunMap *funcs; |
95 | EnumMap *enums; | 89 | EnumMap *enums; |
96 | StructMap *structs; | 90 | StructMap *structs; |
97 | ArrayMap *arrays; | ||
98 | struct Scope *parent; | 91 | struct Scope *parent; |
99 | } Scope; | 92 | } Scope; |
100 | 93 | ||
@@ -315,6 +308,12 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) { | |||
315 | node->field_type->line, node->field_type->col, field_type); | 308 | node->field_type->line, node->field_type->col, field_type); |
316 | a->err = true; | 309 | a->err = true; |
317 | } | 310 | } |
311 | if (node->field_type->is_ptr) { | ||
312 | field_type = str_concat(cstr("@"), field_type, a->storage); | ||
313 | } | ||
314 | if (node->field_type->kind == NODE_ARR_TYPE) { | ||
315 | field_type = str_concat(cstr("@"), field_type, a->storage); | ||
316 | } | ||
318 | if (structmap_lookup(&scope->structs, field_name)) { | 317 | if (structmap_lookup(&scope->structs, field_name)) { |
319 | eprintln("%s:%d:%d: error: struct field '%s' already exists", | 318 | eprintln("%s:%d:%d: error: struct field '%s' already exists", |
320 | a->file_name, node->line, node->col, field_name); | 319 | a->file_name, node->line, node->col, field_name); |
@@ -956,7 +955,20 @@ type_inference(Analyzer *a, Node *node, Scope *scope) { | |||
956 | a->err = true; | 955 | a->err = true; |
957 | return cstr(""); | 956 | return cstr(""); |
958 | } | 957 | } |
959 | node->type = field->val.type; | 958 | Str field_type = field->val.type; |
959 | if (next->kind == NODE_SYMBOL_IDX) { | ||
960 | Str idx_type = | ||
961 | type_inference(a, next->arr_size, scope); | ||
962 | if (!strset_lookup(&a->integer_types, idx_type)) { | ||
963 | emit_semantic_error( | ||
964 | a, next, | ||
965 | cstr("can't resolve non integer index")); | ||
966 | return cstr(""); | ||
967 | } | ||
968 | field_type = | ||
969 | str_remove_prefix(field_type, cstr("@")); | ||
970 | } | ||
971 | node->type = field_type; | ||
960 | return node->type; | 972 | return node->type; |
961 | } | 973 | } |
962 | } | 974 | } |