aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-26 11:25:33 +0200
committerBad Diode <bd@badd10de.dev>2024-06-26 11:25:33 +0200
commit0b07018bff583040b2b299b46139a6210c76fde8 (patch)
treedb4f98e58e505275c0fc0daf2b259bbff3755fd9 /src
parentaad6b8707d59efc5c4136db470896112a45e82b1 (diff)
downloadbdl-0b07018bff583040b2b299b46139a6210c76fde8.tar.gz
bdl-0b07018bff583040b2b299b46139a6210c76fde8.zip
Fix struct literal assignment
Diffstat (limited to 'src')
-rw-r--r--src/main.c50
1 files changed, 29 insertions, 21 deletions
diff --git a/src/main.c b/src/main.c
index 0dd8288..3027a1b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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
17typedef enum ExecMode { 14typedef 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;