aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-26 07:50:23 +0200
committerBad Diode <bd@badd10de.dev>2024-06-26 07:50:23 +0200
commit131bb573e16ecc760b682b3c43149d59a94b9bd7 (patch)
treeb6815bf8e5132d07ddd90e49bfc5d1c67ae3ccf0 /src
parente61947196d898232d40a63d5bbe40ec82b260c03 (diff)
downloadbdl-131bb573e16ecc760b682b3c43149d59a94b9bd7.tar.gz
bdl-131bb573e16ecc760b682b3c43149d59a94b9bd7.zip
Fix bug in struct/enum field matching
Diffstat (limited to 'src')
-rw-r--r--src/main.c58
1 files changed, 35 insertions, 23 deletions
diff --git a/src/main.c b/src/main.c
index 6d25b2d..b2e8d7f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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
19typedef enum ExecMode { 17typedef 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
173EnumMap * 171typedef struct FindEnumResult {
172 EnumMap *map;
173 TypeScope *scope;
174} FindEnumResult;
175
176FindEnumResult
174find_enum(TypeScope *scope, Str type) { 177find_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
185StructMap * 188typedef struct FindStructResult {
189 StructMap *map;
190 TypeScope *scope;
191} FindStructResult;
192
193FindStructResult
186find_struct(TypeScope *scope, Str type) { 194find_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
197void 205void
@@ -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 }