diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-26 11:25:33 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-26 11:25:33 +0200 |
commit | 0b07018bff583040b2b299b46139a6210c76fde8 (patch) | |
tree | db4f98e58e505275c0fc0daf2b259bbff3755fd9 /src | |
parent | aad6b8707d59efc5c4136db470896112a45e82b1 (diff) | |
download | bdl-0b07018bff583040b2b299b46139a6210c76fde8.tar.gz bdl-0b07018bff583040b2b299b46139a6210c76fde8.zip |
Fix struct literal assignment
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 50 |
1 files changed, 29 insertions, 21 deletions
@@ -7,12 +7,9 @@ | |||
7 | #include "parser.c" | 7 | #include "parser.c" |
8 | #include "vm.c" | 8 | #include "vm.c" |
9 | 9 | ||
10 | // TODO: in a let/set expression if the type is a struct check that we | ||
11 | // are assigning a struct literal, not just a symbol. | ||
12 | // TODO: unions | 10 | // TODO: unions |
13 | // TODO: match deconstruct structs | 11 | // TODO: match deconstruct structs |
14 | // TODO: arrays and pointers | 12 | // TODO: arrays and pointers |
15 | // TODO: struct literals with compound types | ||
16 | 13 | ||
17 | typedef enum ExecMode { | 14 | typedef enum ExecMode { |
18 | RUN_NORMAL, | 15 | RUN_NORMAL, |
@@ -410,7 +407,7 @@ typecheck_field(Analyzer *a, Node *node, TypeScope *scope, Str symbol) { | |||
410 | Str field_name = str_concat(symbol, cstr("."), a->storage); | 407 | Str field_name = str_concat(symbol, cstr("."), a->storage); |
411 | field_name = str_concat(field_name, node->value.str, a->storage); | 408 | field_name = str_concat(field_name, node->value.str, a->storage); |
412 | Str field_type = node->field_type->value.str; | 409 | Str field_type = node->field_type->value.str; |
413 | if (!find_type(scope, field_type)) { | 410 | if (!typemap_lookup(&scope->types, field_type)) { |
414 | eprintln("%s:%d:%d: error: unknown type '%s'", a->file_name, | 411 | eprintln("%s:%d:%d: error: unknown type '%s'", a->file_name, |
415 | node->field_type->line, node->field_type->col, field_type); | 412 | node->field_type->line, node->field_type->col, field_type); |
416 | } | 413 | } |
@@ -909,24 +906,35 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) { | |||
909 | } | 906 | } |
910 | 907 | ||
911 | FindStructResult s = find_struct(scope, type->val); | 908 | FindStructResult s = find_struct(scope, type->val); |
912 | if (s.map && !str_eq(symbol, type->val)) { | 909 | if (s.map) { |
913 | if (node->next) { | 910 | if (str_eq(symbol, type->val)) { |
914 | Str chain = type->val; | 911 | eprintln( |
915 | Node *next = node; | 912 | "%s:%d:%d: error: struct incomplete struct literal " |
916 | while (next->next) { | 913 | "'%s', did you mean to use %s:{}?", |
917 | next = next->next; | 914 | a->file_name, node->line, node->col, type->val, |
918 | chain = str_concat(chain, cstr("."), a->storage); | 915 | type->val); |
919 | chain = str_concat(chain, next->value.str, a->storage); | 916 | return cstr(""); |
920 | } | 917 | } else { |
921 | StructMap *field = | 918 | if (node->next) { |
922 | structmap_lookup(&s.scope->structs, chain); | 919 | Str chain = type->val; |
923 | if (!field) { | 920 | Node *next = node; |
924 | eprintln("%s:%d:%d: error: unknown struct field '%s'", | 921 | while (next->next) { |
925 | a->file_name, node->line, node->col, chain); | 922 | next = next->next; |
926 | return cstr(""); | 923 | chain = str_concat(chain, cstr("."), a->storage); |
924 | chain = | ||
925 | str_concat(chain, next->value.str, a->storage); | ||
926 | } | ||
927 | StructMap *field = | ||
928 | structmap_lookup(&s.scope->structs, chain); | ||
929 | if (!field) { | ||
930 | eprintln( | ||
931 | "%s:%d:%d: error: unknown struct field '%s'", | ||
932 | a->file_name, node->line, node->col, chain); | ||
933 | return cstr(""); | ||
934 | } | ||
935 | node->type = field->val.type; | ||
936 | return node->type; | ||
927 | } | 937 | } |
928 | node->type = field->val.type; | ||
929 | return node->type; | ||
930 | } | 938 | } |
931 | } | 939 | } |
932 | node->type = type->val; | 940 | node->type = type->val; |