🐛 type checking of overloaded functions.
parent
85875d2d94
commit
bf91985e00
|
@ -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))
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue