diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-26 07:50:23 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-26 07:50:23 +0200 |
commit | 131bb573e16ecc760b682b3c43149d59a94b9bd7 (patch) | |
tree | b6815bf8e5132d07ddd90e49bfc5d1c67ae3ccf0 /src/main.c | |
parent | e61947196d898232d40a63d5bbe40ec82b260c03 (diff) | |
download | bdl-131bb573e16ecc760b682b3c43149d59a94b9bd7.tar.gz bdl-131bb573e16ecc760b682b3c43149d59a94b9bd7.zip |
Fix bug in struct/enum field matching
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 58 |
1 files changed, 35 insertions, 23 deletions
@@ -13,8 +13,6 @@ | |||
13 | // TODO: match deconstruct structs | 13 | // TODO: match deconstruct structs |
14 | // TODO: arrays and pointers | 14 | // TODO: arrays and pointers |
15 | // TODO: struct literals with compound types | 15 | // TODO: struct literals with compound types |
16 | // FIXME: there may be an issue with shadowed structs sharing fields... we may | ||
17 | // want to consider moving the fields to separate maps again... | ||
18 | 16 | ||
19 | typedef enum ExecMode { | 17 | typedef enum ExecMode { |
20 | RUN_NORMAL, | 18 | RUN_NORMAL, |
@@ -170,28 +168,38 @@ find_fun(TypeScope *scope, Str type) { | |||
170 | return NULL; | 168 | return NULL; |
171 | } | 169 | } |
172 | 170 | ||
173 | EnumMap * | 171 | typedef struct FindEnumResult { |
172 | EnumMap *map; | ||
173 | TypeScope *scope; | ||
174 | } FindEnumResult; | ||
175 | |||
176 | FindEnumResult | ||
174 | find_enum(TypeScope *scope, Str type) { | 177 | find_enum(TypeScope *scope, Str type) { |
175 | while (scope != NULL) { | 178 | while (scope != NULL) { |
176 | EnumMap *val = enummap_lookup(&scope->enums, type); | 179 | EnumMap *val = enummap_lookup(&scope->enums, type); |
177 | if (val != NULL) { | 180 | if (val != NULL) { |
178 | return val; | 181 | return (FindEnumResult){.map = val, .scope = scope}; |
179 | } | 182 | } |
180 | scope = scope->parent; | 183 | scope = scope->parent; |
181 | } | 184 | } |
182 | return NULL; | 185 | return (FindEnumResult){0}; |
183 | } | 186 | } |
184 | 187 | ||
185 | StructMap * | 188 | typedef struct FindStructResult { |
189 | StructMap *map; | ||
190 | TypeScope *scope; | ||
191 | } FindStructResult; | ||
192 | |||
193 | FindStructResult | ||
186 | find_struct(TypeScope *scope, Str type) { | 194 | find_struct(TypeScope *scope, Str type) { |
187 | while (scope != NULL) { | 195 | while (scope != NULL) { |
188 | StructMap *val = structmap_lookup(&scope->structs, type); | 196 | StructMap *val = structmap_lookup(&scope->structs, type); |
189 | if (val != NULL) { | 197 | if (val != NULL) { |
190 | return val; | 198 | return (FindStructResult){.map = val, .scope = scope}; |
191 | } | 199 | } |
192 | scope = scope->parent; | 200 | scope = scope->parent; |
193 | } | 201 | } |
194 | return NULL; | 202 | return (FindStructResult){0}; |
195 | } | 203 | } |
196 | 204 | ||
197 | void | 205 | void |
@@ -539,8 +547,8 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) { | |||
539 | // TODO: Consider compatible types. | 547 | // TODO: Consider compatible types. |
540 | if (!str_eq(type, type_name)) { | 548 | if (!str_eq(type, type_name)) { |
541 | // Special case, enums can be treated as ints. | 549 | // Special case, enums can be treated as ints. |
542 | EnumMap *e = find_enum(scope, type_name); | 550 | FindEnumResult res = find_enum(scope, type_name); |
543 | if (!(e && str_eq(type, cstr("int")))) { | 551 | if (!(res.map && str_eq(type, cstr("int")))) { |
544 | eprintln( | 552 | eprintln( |
545 | "%s:%d:%d: error: type mismatch, trying to " | 553 | "%s:%d:%d: error: type mismatch, trying to " |
546 | "assing " | 554 | "assing " |
@@ -841,8 +849,8 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) { | |||
841 | return cstr(""); | 849 | return cstr(""); |
842 | } | 850 | } |
843 | 851 | ||
844 | EnumMap *e = find_enum(scope, type->val); | 852 | FindEnumResult e = find_enum(scope, type->val); |
845 | if (e && str_eq(symbol, type->val)) { | 853 | if (e.map && str_eq(symbol, type->val)) { |
846 | if (!node->next) { | 854 | if (!node->next) { |
847 | eprintln( | 855 | eprintln( |
848 | "%s:%d:%d: error: unspecified enum field for symbol " | 856 | "%s:%d:%d: error: unspecified enum field for symbol " |
@@ -853,7 +861,7 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) { | |||
853 | // Check if there is a next and it matches the enum field. | 861 | // Check if there is a next and it matches the enum field. |
854 | Str field = str_concat(type->val, cstr("."), a->storage); | 862 | Str field = str_concat(type->val, cstr("."), a->storage); |
855 | field = str_concat(field, node->next->value.str, a->storage); | 863 | field = str_concat(field, node->next->value.str, a->storage); |
856 | if (!find_enum(scope, field)) { | 864 | if (!enummap_lookup(&e.scope->enums, field)) { |
857 | eprintln( | 865 | eprintln( |
858 | "%s:%d:%d: error: unknown enum field for " | 866 | "%s:%d:%d: error: unknown enum field for " |
859 | "'%s': %s", | 867 | "'%s': %s", |
@@ -866,8 +874,8 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) { | |||
866 | return node->next->type; | 874 | return node->next->type; |
867 | } | 875 | } |
868 | 876 | ||
869 | StructMap *s = find_struct(scope, type->val); | 877 | FindStructResult s = find_struct(scope, type->val); |
870 | if (s && !str_eq(symbol, type->val)) { | 878 | if (s.map && !str_eq(symbol, type->val)) { |
871 | if (node->next) { | 879 | if (node->next) { |
872 | Str chain = type->val; | 880 | Str chain = type->val; |
873 | Node *next = node; | 881 | Node *next = node; |
@@ -876,7 +884,8 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) { | |||
876 | chain = str_concat(chain, cstr("."), a->storage); | 884 | chain = str_concat(chain, cstr("."), a->storage); |
877 | chain = str_concat(chain, next->value.str, a->storage); | 885 | chain = str_concat(chain, next->value.str, a->storage); |
878 | } | 886 | } |
879 | StructMap *field = find_struct(scope, chain); | 887 | StructMap *field = |
888 | structmap_lookup(&s.scope->structs, chain); | ||
880 | if (!field) { | 889 | if (!field) { |
881 | eprintln("%s:%d:%d: error: unknown struct field '%s'", | 890 | eprintln("%s:%d:%d: error: unknown struct field '%s'", |
882 | a->file_name, node->line, node->col, chain); | 891 | a->file_name, node->line, node->col, chain); |
@@ -891,8 +900,8 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) { | |||
891 | } break; | 900 | } break; |
892 | case NODE_STRUCT_LIT: { | 901 | case NODE_STRUCT_LIT: { |
893 | Str name = node->value.str; | 902 | Str name = node->value.str; |
894 | StructMap *s = find_struct(scope, name); | 903 | FindStructResult s = find_struct(scope, name); |
895 | if (!s) { | 904 | if (!s.map) { |
896 | eprintln("%s:%d:%d: error: unknown struct type '%s'", | 905 | eprintln("%s:%d:%d: error: unknown struct type '%s'", |
897 | a->file_name, node->line, node->col, name); | 906 | a->file_name, node->line, node->col, name); |
898 | return cstr(""); | 907 | return cstr(""); |
@@ -914,7 +923,8 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) { | |||
914 | strset_insert(&set, field_name, a->storage); | 923 | strset_insert(&set, field_name, a->storage); |
915 | } | 924 | } |
916 | 925 | ||
917 | StructMap *field = find_struct(scope, field_name); | 926 | StructMap *field = |
927 | structmap_lookup(&s.scope->structs, field_name); | ||
918 | if (!field) { | 928 | if (!field) { |
919 | eprintln("%s:%d:%d: error: unknown struct field '%s'", | 929 | eprintln("%s:%d:%d: error: unknown struct field '%s'", |
920 | a->file_name, next->line, next->col, field_name); | 930 | a->file_name, next->line, next->col, field_name); |
@@ -1474,7 +1484,8 @@ process_file(Str path) { | |||
1474 | EnumMapIter iter = enummap_iterator(scope->enums, &scratch); | 1484 | EnumMapIter iter = enummap_iterator(scope->enums, &scratch); |
1475 | EnumMap *m = enummap_next(&iter, &scratch); | 1485 | EnumMap *m = enummap_next(&iter, &scratch); |
1476 | while (m) { | 1486 | while (m) { |
1477 | println("%s: enum: %s", path, m->val.name); | 1487 | println("scope: %x{2} -- %s: enum: %s", scope->id, path, |
1488 | m->val.name); | ||
1478 | m = enummap_next(&iter, &scratch); | 1489 | m = enummap_next(&iter, &scratch); |
1479 | } | 1490 | } |
1480 | } | 1491 | } |
@@ -1485,7 +1496,8 @@ process_file(Str path) { | |||
1485 | StructMapIter iter = structmap_iterator(scope->structs, &scratch); | 1496 | StructMapIter iter = structmap_iterator(scope->structs, &scratch); |
1486 | StructMap *m = structmap_next(&iter, &scratch); | 1497 | StructMap *m = structmap_next(&iter, &scratch); |
1487 | while (m) { | 1498 | while (m) { |
1488 | println("%s: struct: %s", path, m->val.name); | 1499 | println("scope: %x{2} -- %s: struct: %s", scope->id, path, |
1500 | m->val.name); | ||
1489 | m = structmap_next(&iter, &scratch); | 1501 | m = structmap_next(&iter, &scratch); |
1490 | } | 1502 | } |
1491 | } | 1503 | } |
@@ -1496,8 +1508,8 @@ process_file(Str path) { | |||
1496 | FunMapIter iter = funmap_iterator(scope->funcs, &scratch); | 1508 | FunMapIter iter = funmap_iterator(scope->funcs, &scratch); |
1497 | FunMap *m = funmap_next(&iter, &scratch); | 1509 | FunMap *m = funmap_next(&iter, &scratch); |
1498 | while (m) { | 1510 | while (m) { |
1499 | println("%s: func: %s(%s): (%s)", path, m->val.name, | 1511 | println("scope: %x{2} -- %s: func: %s(%s): (%s)", scope->id, path, |
1500 | m->val.param_type, m->val.return_type); | 1512 | m->val.name, m->val.param_type, m->val.return_type); |
1501 | m = funmap_next(&iter, &scratch); | 1513 | m = funmap_next(&iter, &scratch); |
1502 | } | 1514 | } |
1503 | } | 1515 | } |