🐛 type checking of overloaded functions.

main
bog 2024-02-18 11:35:33 +01:00
parent 85875d2d94
commit bf91985e00
4 changed files with 45 additions and 7 deletions

View File

@ -12,6 +12,12 @@ void sym_table_init(struct sym_table* self, struct sym_table* prev)
self->addr_counter = 0; self->addr_counter = 0;
self->prev = prev; 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) void sym_table_free(struct sym_table* self)
@ -96,7 +102,7 @@ struct sym* sym_table_fetch(struct sym_table* self,
if (self->prev) if (self->prev)
{ {
return sym_table_fetch(self->prev, name, NULL); return sym_table_fetch(self->prev, name, type);
} }
return NULL; return NULL;
@ -109,8 +115,15 @@ struct sym* sym_table_fetch_fun(struct sym_table* self,
struct vec args_ty; struct vec args_ty;
vec_init(&args_ty, 1); vec_init(&args_ty, 1);
struct sym_table* itr = self;
while (itr->next)
{
itr = itr->next;
}
struct type_resolver resolver; struct type_resolver resolver;
type_resolver_init(&resolver, self); type_resolver_init(&resolver, itr);
for (size_t i=0; i < args->children.size; i++) 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_init(arg_type, TYPE_VOID);
type_resolver_resolve(&resolver, child, arg_type); type_resolver_resolve(&resolver, child, arg_type);
vec_push(&args_ty, 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) if (self->prev)
{ {
return sym_table_fetch(self->prev, name, NULL); return sym_table_fetch_fun(self->prev, name, args);
} }
return NULL; return NULL;
@ -205,7 +219,7 @@ int sym_table_declare(struct sym_table* self,
assert(self); assert(self);
assert(strcmp(name, "") != 0); 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 if (s && s->parent == self->root
&& type_equals(s->type, new_type)) && type_equals(s->type, new_type))
@ -236,7 +250,7 @@ int sym_table_declare_global(struct sym_table* self,
assert(self); assert(self);
assert(strcmp(name, "") != 0); 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 if (s && s->parent == self->root && s->is_global
&& type_equals(s->type, new_type)) && type_equals(s->type, new_type))

View File

@ -20,6 +20,7 @@ struct table {
}; };
struct sym_table { struct sym_table {
struct sym_table* next;
struct sym_table* prev; struct sym_table* prev;
struct table* root; struct table* root;
int addr_counter; int addr_counter;

View File

@ -83,8 +83,8 @@ int type_checker_check(struct type_checker* self,
struct node* args = node->children.data[1]; struct node* args = node->children.data[1];
struct sym* entry = sym_table_fetch_fun(&self->sym_table, struct sym* entry = sym_table_fetch_fun(&self->sym_table,
target->value, target->value,
args); args);
if (!entry) if (!entry)
{ {
@ -109,6 +109,7 @@ int type_checker_check(struct type_checker* self,
{ {
struct type* sub = ty->subtypes.data[i + 1]; struct type* sub = ty->subtypes.data[i + 1];
struct node* sub_node = args->children.data[i]; struct node* sub_node = args->children.data[i];
struct type t; struct type t;
type_init(&t, TYPE_VOID); type_init(&t, TYPE_VOID);
@ -118,6 +119,14 @@ int type_checker_check(struct type_checker* self,
return 1; 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)) if (!type_equals(&t, sub))
{ {
type_checker_error_msg(self, sub_node, sub, &t); type_checker_error_msg(self, sub_node, sub, &t);

View File

@ -1,5 +1,6 @@
#include "type_resolver.h" #include "type_resolver.h"
#include "node.h" #include "node.h"
#include "sym_table.h"
#include "type.h" #include "type.h"
void type_resolver_init(struct type_resolver* self, void type_resolver_init(struct type_resolver* self,
@ -40,9 +41,22 @@ int type_resolver_resolve(struct type_resolver* self,
}; };
case NODE_CALL: { 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; struct type call_type;
type_init(&call_type, TYPE_VOID); type_init(&call_type, TYPE_VOID);
if (type_resolver_resolve(self, node->children.data[0], &call_type) == 0 if (type_resolver_resolve(self, node->children.data[0], &call_type) == 0
&& call_type.subtypes.size > 0) && call_type.subtypes.size > 0)
{ {