aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-26 08:54:55 +0200
committerBad Diode <bd@badd10de.dev>2024-06-26 08:54:55 +0200
commitaad6b8707d59efc5c4136db470896112a45e82b1 (patch)
treea5bc48f201e5236778b46bb98b279b18a919bec5 /src/main.c
parent5453e1545b4b3663408456ac8c8aedf2da856ac0 (diff)
downloadbdl-aad6b8707d59efc5c4136db470896112a45e82b1.tar.gz
bdl-aad6b8707d59efc5c4136db470896112a45e82b1.zip
Fix typechecking for nested struct literals
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c53
1 files changed, 35 insertions, 18 deletions
diff --git a/src/main.c b/src/main.c
index b2e8d7f..0dd8288 100644
--- a/src/main.c
+++ b/src/main.c
@@ -441,6 +441,40 @@ typecheck_field(Analyzer *a, Node *node, TypeScope *scope, Str symbol) {
441} 441}
442 442
443void 443void
444typecheck_lit_field(Analyzer *a, Node *node, TypeScope *scope, Str symbol) {
445 if (node->field_val->kind == NODE_COMPOUND_TYPE) {
446 Str type = cstr("\\{ ");
447 for (sz i = 0; i < array_size(node->field_val->elements); i++) {
448 Node *field = node->field_val->elements[i];
449 Str field_name = str_concat(symbol, cstr("."), a->storage);
450 field_name = str_concat(field_name, field->value.str, a->storage);
451 typecheck_lit_field(a, field, scope, field_name);
452 type = str_concat(type, field->type, a->storage);
453 type = str_concat(type, cstr(" "), a->storage);
454 }
455 type = str_concat(type, cstr("\\}"), a->storage);
456 node->type = type;
457 } else {
458 StructMap *s = structmap_lookup(&scope->structs, symbol);
459 if (!s) {
460 eprintln("%s:%d:%d: error: unknown struct field '%s'", a->file_name,
461 node->line, node->col, symbol);
462 return;
463 }
464 Str field_type = s->val.type;
465 Type type = type_inference(a, node->field_val, scope);
466 if (!str_eq(type, field_type)) {
467 eprintln(
468 "%s:%d:%d: error: mismatched types in struct "
469 "value "
470 "for '%s': %s expected %s",
471 a->file_name, node->line, node->col, symbol, type, field_type);
472 }
473 node->type = field_type;
474 }
475}
476
477void
444typecheck_returns(Analyzer *a, Node *node, Str expected) { 478typecheck_returns(Analyzer *a, Node *node, Str expected) {
445 if (!node) { 479 if (!node) {
446 return; 480 return;
@@ -922,24 +956,7 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) {
922 } else { 956 } else {
923 strset_insert(&set, field_name, a->storage); 957 strset_insert(&set, field_name, a->storage);
924 } 958 }
925 959 typecheck_lit_field(a, next, s.scope, field_name);
926 StructMap *field =
927 structmap_lookup(&s.scope->structs, field_name);
928 if (!field) {
929 eprintln("%s:%d:%d: error: unknown struct field '%s'",
930 a->file_name, next->line, next->col, field_name);
931 } else {
932 Type type = type_inference(a, next->field_val, scope);
933 if (!str_eq(type, field->val.type)) {
934 eprintln(
935 "%s:%d:%d: error: mismatched types in struct "
936 "literal for '%s': %s expected %s ",
937 a->file_name, next->line, next->col, field_name,
938 type, field->val.type);
939 }
940 next->type = type;
941 }
942 // TODO: nested fields.
943 } 960 }
944 node->type = name; 961 node->type = name;
945 return node->type; 962 return node->type;