aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-24 17:51:18 +0200
committerBad Diode <bd@badd10de.dev>2024-06-24 17:51:18 +0200
commit8658d71e8a0761f8407b35cdf08b4b80229f560e (patch)
tree80440edae7a8c6083c903a39f6531fd106c1988c /src/main.c
parent2560da172f15982da7464a6534702c08f9b7575d (diff)
downloadbdl-8658d71e8a0761f8407b35cdf08b4b80229f560e.tar.gz
bdl-8658d71e8a0761f8407b35cdf08b4b80229f560e.zip
Add field accessor for typechecking enum fields
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c45
1 files changed, 40 insertions, 5 deletions
diff --git a/src/main.c b/src/main.c
index f2c4d4f..d493d8e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -8,7 +8,7 @@
8#include "vm.c" 8#include "vm.c"
9 9
10// TODO: typecheck structs 10// TODO: typecheck structs
11// TODO: add field accessor for struct/enum symbols 11// TODO: add field accessor for struct symbols
12 12
13typedef enum ExecMode { 13typedef enum ExecMode {
14 RUN_NORMAL, 14 RUN_NORMAL,
@@ -162,6 +162,18 @@ find_fun(TypeScope *scope, Str type) {
162 return NULL; 162 return NULL;
163} 163}
164 164
165EnumMap *
166find_enum(TypeScope *scope, Str type) {
167 while (scope != NULL) {
168 EnumMap *val = enummap_lookup(&scope->enums, type);
169 if (val != NULL) {
170 return val;
171 }
172 scope = scope->parent;
173 }
174 return NULL;
175}
176
165void 177void
166graph_scope(Scope *scope, Arena a) { 178graph_scope(Scope *scope, Arena a) {
167 if (!scope->symbols) { 179 if (!scope->symbols) {
@@ -507,6 +519,7 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) {
507 a->storage); 519 a->storage);
508 field->type = cstr("int"); 520 field->type = cstr("int");
509 } 521 }
522 typemap_insert(&scope->types, symbol, symbol, a->storage);
510 return node->type; 523 return node->type;
511 } break; 524 } break;
512 case NODE_IF: { 525 case NODE_IF: {
@@ -716,11 +729,33 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) {
716 return node->type; 729 return node->type;
717 } break; 730 } break;
718 case NODE_SYMBOL: { 731 case NODE_SYMBOL: {
719 TypeMap *type = find_type(scope, node->value.str); 732 Str symbol = node->value.str;
720 if (type) { 733 TypeMap *type = find_type(scope, symbol);
721 node->type = type->val; 734 if (!type) {
722 return node->type; 735 eprintln("%s:%d:%d: error: couldn't resolve symbol '%s'",
736 a->file_name, node->line, node->col, symbol);
737 return cstr("");
723 } 738 }
739 EnumMap *e = find_enum(scope, type->val);
740 if (e && str_eq(symbol, type->val)) {
741 if (!node->next) {
742 eprintln(
743 "%s:%d:%d: error: unspecified enum field for symbol "
744 "'%s'",
745 a->file_name, node->line, node->col, symbol);
746 return cstr("");
747 }
748 // Check if there is a next and it matches the enum field.
749 if (!fieldmap_lookup(&e->val.fields, node->next->value.str)) {
750 eprintln(
751 "%s:%d:%d: error: unknown enum field for symbol "
752 "'%s'",
753 a->file_name, node->line, node->col, symbol);
754 return cstr("");
755 }
756 node->next->type = symbol;
757 }
758 node->type = type->val;
724 return node->type; 759 return node->type;
725 } break; 760 } break;
726 case NODE_FUNCALL: { 761 case NODE_FUNCALL: {