From bf91985e00832adfcd316ea15627a02c88a6beb5 Mon Sep 17 00:00:00 2001 From: bog Date: Sun, 18 Feb 2024 11:35:33 +0100 Subject: [PATCH] :bug: type checking of overloaded functions. --- lang/src/sym_table.c | 24 +++++++++++++++++++----- lang/src/sym_table.h | 1 + lang/src/type_checker.c | 13 +++++++++++-- lang/src/type_resolver.c | 14 ++++++++++++++ 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/lang/src/sym_table.c b/lang/src/sym_table.c index b5e45fe..17d109b 100644 --- a/lang/src/sym_table.c +++ b/lang/src/sym_table.c @@ -12,6 +12,12 @@ void sym_table_init(struct sym_table* self, struct sym_table* prev) self->addr_counter = 0; self->prev = prev; + self->next = NULL; + + if (self->prev && self->prev->next == NULL) + { + self->prev->next = self; + } } void sym_table_free(struct sym_table* self) @@ -96,7 +102,7 @@ struct sym* sym_table_fetch(struct sym_table* self, if (self->prev) { - return sym_table_fetch(self->prev, name, NULL); + return sym_table_fetch(self->prev, name, type); } return NULL; @@ -109,8 +115,15 @@ struct sym* sym_table_fetch_fun(struct sym_table* self, struct vec args_ty; vec_init(&args_ty, 1); + struct sym_table* itr = self; + + while (itr->next) + { + itr = itr->next; + } + struct type_resolver resolver; - type_resolver_init(&resolver, self); + type_resolver_init(&resolver, itr); for (size_t i=0; i < args->children.size; i++) { @@ -119,6 +132,7 @@ struct sym* sym_table_fetch_fun(struct sym_table* self, type_init(arg_type, TYPE_VOID); type_resolver_resolve(&resolver, child, arg_type); + vec_push(&args_ty, arg_type); } @@ -177,7 +191,7 @@ struct sym* sym_table_fetch_fun(struct sym_table* self, if (self->prev) { - return sym_table_fetch(self->prev, name, NULL); + return sym_table_fetch_fun(self->prev, name, args); } return NULL; @@ -205,7 +219,7 @@ int sym_table_declare(struct sym_table* self, assert(self); assert(strcmp(name, "") != 0); - struct sym* s = sym_table_fetch(self, name, NULL); + struct sym* s = sym_table_fetch(self, name, new_type); if (s && s->parent == self->root && type_equals(s->type, new_type)) @@ -236,7 +250,7 @@ int sym_table_declare_global(struct sym_table* self, assert(self); assert(strcmp(name, "") != 0); - struct sym* s = sym_table_fetch(self, name, NULL); + struct sym* s = sym_table_fetch(self, name, new_type); if (s && s->parent == self->root && s->is_global && type_equals(s->type, new_type)) diff --git a/lang/src/sym_table.h b/lang/src/sym_table.h index 7905f4b..74df115 100644 --- a/lang/src/sym_table.h +++ b/lang/src/sym_table.h @@ -20,6 +20,7 @@ struct table { }; struct sym_table { + struct sym_table* next; struct sym_table* prev; struct table* root; int addr_counter; diff --git a/lang/src/type_checker.c b/lang/src/type_checker.c index 4e6b40b..8a66b60 100644 --- a/lang/src/type_checker.c +++ b/lang/src/type_checker.c @@ -83,8 +83,8 @@ int type_checker_check(struct type_checker* self, struct node* args = node->children.data[1]; struct sym* entry = sym_table_fetch_fun(&self->sym_table, - target->value, - args); + target->value, + args); if (!entry) { @@ -109,6 +109,7 @@ int type_checker_check(struct type_checker* self, { struct type* sub = ty->subtypes.data[i + 1]; struct node* sub_node = args->children.data[i]; + struct type t; type_init(&t, TYPE_VOID); @@ -118,6 +119,14 @@ int type_checker_check(struct type_checker* self, return 1; } + if (type_checker_check(self, sub_node) != 0) + { + self->error_line = sub_node->line; + + type_free(&t); + return 1; + } + if (!type_equals(&t, sub)) { type_checker_error_msg(self, sub_node, sub, &t); diff --git a/lang/src/type_resolver.c b/lang/src/type_resolver.c index 299b5fa..5c08062 100644 --- a/lang/src/type_resolver.c +++ b/lang/src/type_resolver.c @@ -1,5 +1,6 @@ #include "type_resolver.h" #include "node.h" +#include "sym_table.h" #include "type.h" void type_resolver_init(struct type_resolver* self, @@ -40,9 +41,22 @@ int type_resolver_resolve(struct type_resolver* self, }; case NODE_CALL: { + struct node* target = node->children.data[0]; + struct node* args = node->children.data[1]; + struct sym* entry = sym_table_fetch_fun(self->sym_table, + target->value, + args); + + if (entry) + { + type_copy(entry->type->subtypes.data[0], type); + return 0; + } + struct type call_type; type_init(&call_type, TYPE_VOID); + if (type_resolver_resolve(self, node->children.data[0], &call_type) == 0 && call_type.subtypes.size > 0) {