function overloading.

main
bog 2024-02-17 23:35:58 +01:00
parent 6420e283a1
commit 85875d2d94
7 changed files with 171 additions and 36 deletions

View File

@ -126,8 +126,15 @@ int compiler_compile(struct compiler* self,
compiler_compile(self, arg, program); compiler_compile(self, arg, program);
} }
struct sym* entry = sym_table_try_by_name(&self->sym_table, struct sym* entry = sym_table_fetch_fun(&self->sym_table,
target->value); target->value,
args);
if (!entry)
{
entry = sym_table_fetch(&self->sym_table,
target->value,
NULL);
}
assert(entry); assert(entry);
@ -247,8 +254,16 @@ int compiler_compile(struct compiler* self,
case NODE_ASSIGN: { case NODE_ASSIGN: {
struct node* ident = node->children.data[0]; struct node* ident = node->children.data[0];
struct node* expr = node->children.data[1]; struct node* expr = node->children.data[1];
struct sym* entry = sym_table_try_by_name(&self->sym_table,
ident->value); struct type type;
type_init(&type, TYPE_VOID);
compiler_get_type(self, expr, &type);
struct sym* entry = sym_table_fetch(&self->sym_table,
ident->value,
&type);
type_free(&type);
assert(entry); assert(entry);
if (compiler_compile(self, expr, program) != 0) if (compiler_compile(self, expr, program) != 0)
@ -260,8 +275,9 @@ int compiler_compile(struct compiler* self,
} break; } break;
case NODE_IDENT: { case NODE_IDENT: {
struct sym* entry = sym_table_try_by_name(&self->sym_table, struct sym* entry = sym_table_fetch(&self->sym_table,
node->value); node->value,
NULL);
if (!entry) if (!entry)
{ {
@ -301,8 +317,9 @@ int compiler_compile(struct compiler* self,
sym_table_declare(&self->sym_table, node->value, ty, sym_table_declare(&self->sym_table, node->value, ty,
node->type == NODE_VARDECL); node->type == NODE_VARDECL);
struct sym* entry = sym_table_try_by_name(&self->sym_table, struct sym* entry = sym_table_fetch(&self->sym_table,
node->value); node->value,
ty);
assert(entry); assert(entry);

View File

@ -1,5 +1,6 @@
#include "sym_table.h" #include "sym_table.h"
#include "commons.h" #include "commons.h"
#include "type_resolver.h"
#include "vec.h" #include "vec.h"
void sym_table_init(struct sym_table* self, struct sym_table* prev) void sym_table_init(struct sym_table* self, struct sym_table* prev)
@ -69,7 +70,9 @@ void sym_table_pop_table(struct sym_table* self)
self->root = next; self->root = next;
} }
struct sym* sym_table_try_by_name(struct sym_table* self, char* const name) struct sym* sym_table_fetch(struct sym_table* self,
char* const name,
struct type* type)
{ {
assert(self); assert(self);
@ -81,7 +84,8 @@ struct sym* sym_table_try_by_name(struct sym_table* self, char* const name)
{ {
struct sym* sym = table->syms.data[i]; struct sym* sym = table->syms.data[i];
if (strcmp(sym->name, name) == 0) if (strcmp(sym->name, name) == 0
&& (type == NULL || type_equals(type, sym->type)))
{ {
return sym; return sym;
} }
@ -92,7 +96,88 @@ struct sym* sym_table_try_by_name(struct sym_table* self, char* const name)
if (self->prev) if (self->prev)
{ {
return sym_table_try_by_name(self->prev, name); return sym_table_fetch(self->prev, name, NULL);
}
return NULL;
}
struct sym* sym_table_fetch_fun(struct sym_table* self,
char* const name,
struct node* args)
{
struct vec args_ty;
vec_init(&args_ty, 1);
struct type_resolver resolver;
type_resolver_init(&resolver, self);
for (size_t i=0; i < args->children.size; i++)
{
struct node* child = args->children.data[i];
struct type* arg_type = malloc(sizeof(struct type));
type_init(arg_type, TYPE_VOID);
type_resolver_resolve(&resolver, child, arg_type);
vec_push(&args_ty, arg_type);
}
type_resolver_free(&resolver);
struct table* table = self->root;
while (table)
{
for (size_t i=0; i<table->syms.size; i++)
{
struct sym* sym = table->syms.data[i];
if (strcmp(sym->name, name) == 0
&& args_ty.size == sym->type->subtypes.size - 1)
{
int same = 1;
for (size_t j=0; j<args_ty.size; j++)
{
struct type* arg = args_ty.data[j];
struct type* sub = sym->type->subtypes.data[1 + j];
if (!type_equals(arg, sub))
{
same = 0;
break;
}
}
if (same)
{
for (size_t k=0; k<args_ty.size; k++)
{
type_free(args_ty.data[k]);
}
vec_free_elements(&args_ty);
vec_free(&args_ty);
return sym;
}
}
}
table = table->prev;
}
for (size_t i=0; i<args_ty.size; i++)
{
type_free(args_ty.data[i]);
}
vec_free_elements(&args_ty);
vec_free(&args_ty);
if (self->prev)
{
return sym_table_fetch(self->prev, name, NULL);
} }
return NULL; return NULL;
@ -120,9 +205,10 @@ 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_try_by_name(self, name); struct sym* s = sym_table_fetch(self, name, NULL);
if (s && s->parent == self->root) if (s && s->parent == self->root
&& type_equals(s->type, new_type))
{ {
return 1; return 1;
} }
@ -150,9 +236,10 @@ 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_try_by_name(self, name); struct sym* s = sym_table_fetch(self, name, NULL);
if (s && s->parent == self->root && s->is_global) if (s && s->parent == self->root && s->is_global
&& type_equals(s->type, new_type))
{ {
return 1; return 1;
} }

View File

@ -31,7 +31,14 @@ void sym_table_free(struct sym_table* self);
void sym_table_push_table(struct sym_table* self); void sym_table_push_table(struct sym_table* self);
void sym_table_pop_table(struct sym_table* self); void sym_table_pop_table(struct sym_table* self);
struct sym* sym_table_try_by_name(struct sym_table* self, char* const name); struct sym* sym_table_fetch(struct sym_table* self,
char* const name,
struct type* type);
struct sym* sym_table_fetch_fun(struct sym_table* self,
char* const name,
struct node* args);
int sym_table_declare_const(struct sym_table* self, int sym_table_declare_const(struct sym_table* self,
char* const name, char* const name,
struct type* new_type); struct type* new_type);

View File

@ -81,8 +81,10 @@ int type_checker_check(struct type_checker* self,
case NODE_CALL: { case NODE_CALL: {
struct node* target = node->children.data[0]; struct node* target = node->children.data[0];
struct node* args = node->children.data[1]; struct node* args = node->children.data[1];
struct sym* entry = sym_table_try_by_name(&self->sym_table,
target->value); struct sym* entry = sym_table_fetch_fun(&self->sym_table,
target->value,
args);
if (!entry) if (!entry)
{ {
@ -95,7 +97,6 @@ int type_checker_check(struct type_checker* self,
struct type* ty = entry->type; struct type* ty = entry->type;
assert(ty); assert(ty);
if (ty->subtypes.size - 1 != args->children.size) if (ty->subtypes.size - 1 != args->children.size)
{ {
self->error_line = node->line; self->error_line = node->line;
@ -278,8 +279,9 @@ int type_checker_check(struct type_checker* self,
struct node* ident = node->children.data[0]; struct node* ident = node->children.data[0];
struct node* expr = node->children.data[1]; struct node* expr = node->children.data[1];
struct sym* entry = sym_table_try_by_name(&self->sym_table, struct sym* entry = sym_table_fetch(&self->sym_table,
ident->value); ident->value,
NULL);
if (!entry) if (!entry)
{ {
@ -318,10 +320,19 @@ int type_checker_check(struct type_checker* self,
case NODE_VARDECL: case NODE_VARDECL:
case NODE_CONSTDECL:{ case NODE_CONSTDECL:{
struct sym* entry = sym_table_try_by_name(&self->sym_table, struct type type;
node->value); type_init(&type, TYPE_VOID);
if (entry && entry->parent == self->sym_table.root) type_resolver_resolve(&self->resolver, node->children.data[0], &type);
struct sym* entry = sym_table_fetch(&self->sym_table,
node->value,
&type);
type_free(&type);
if (entry && entry->parent == self->sym_table.root
&& type_equals(entry->type, &type))
{ {
snprintf(self->error_msg, GUX_STR_SIZE, snprintf(self->error_msg, GUX_STR_SIZE,
"%s is already defined", node->value); "%s is already defined", node->value);

View File

@ -43,12 +43,14 @@ int type_resolver_resolve(struct type_resolver* self,
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)
{ {
type_copy(call_type.subtypes.data[0], type); type_copy(call_type.subtypes.data[0], type);
} }
type_free(&call_type); type_free(&call_type);
} return 0; } return 0;
case NODE_FUN: { case NODE_FUN: {
@ -83,14 +85,14 @@ int type_resolver_resolve(struct type_resolver* self,
type_copy(ty, type); type_copy(ty, type);
sym_table_declare(self->sym_table, node->value, ty, //sym_table_declare(self->sym_table, node->value, ty,
node->type == NODE_VARDECL); // node->type == NODE_VARDECL);
} return 0; } return 0;
case NODE_IDENT: { case NODE_IDENT: {
struct sym* entry = sym_table_try_by_name(self->sym_table, struct sym* entry = sym_table_fetch(self->sym_table,
node->value); node->value, NULL);
if (strcmp(node->value, "this") == 0) if (strcmp(node->value, "this") == 0)
{ {

View File

@ -6,7 +6,7 @@ Test(sym_table, simple) {
struct sym_table table; struct sym_table table;
sym_table_init(&table, NULL); sym_table_init(&table, NULL);
struct sym* sym = sym_table_try_by_name(&table, "hello"); struct sym* sym = sym_table_fetch(&table, "hello", NULL);
cr_assert_eq(sym, 0); cr_assert_eq(sym, 0);
struct type* ty = malloc(sizeof(struct type)); struct type* ty = malloc(sizeof(struct type));
@ -15,7 +15,7 @@ Test(sym_table, simple) {
int err = sym_table_declare_const(&table, "hello", ty); int err = sym_table_declare_const(&table, "hello", ty);
cr_assert_eq(err, 0); cr_assert_eq(err, 0);
sym = sym_table_try_by_name(&table, "hello"); sym = sym_table_fetch(&table, "hello", NULL);
cr_assert_neq(sym, 0); cr_assert_neq(sym, 0);
cr_assert_str_eq("hello", sym->name); cr_assert_str_eq("hello", sym->name);
@ -58,15 +58,15 @@ Test(sym_table, scope) {
struct sym* sym; struct sym* sym;
sym = sym_table_try_by_name(&table, "abc"); sym = sym_table_fetch(&table, "abc", NULL);
cr_assert_eq(sym->type->kind, TYPE_STRING); cr_assert_eq(sym->type->kind, TYPE_STRING);
sym_table_pop_table(&table); sym_table_pop_table(&table);
sym = sym_table_try_by_name(&table, "abc"); sym = sym_table_fetch(&table, "abc", NULL);
cr_assert_eq(sym->type->kind, TYPE_FLOAT); cr_assert_eq(sym->type->kind, TYPE_FLOAT);
sym_table_pop_table(&table); sym_table_pop_table(&table);
sym = sym_table_try_by_name(&table, "abc"); sym = sym_table_fetch(&table, "abc", NULL);
cr_assert_eq(sym->type->kind, TYPE_INT); cr_assert_eq(sym->type->kind, TYPE_INT);
sym_table_free(&table); sym_table_free(&table);
@ -84,7 +84,7 @@ Test(sym_table, outer_scope) {
sym_table_push_table(&table); sym_table_push_table(&table);
sym_table_push_table(&table); sym_table_push_table(&table);
struct sym* sym = sym_table_try_by_name(&table, "abc"); struct sym* sym = sym_table_fetch(&table, "abc", NULL);
cr_assert_eq(sym->type->kind, TYPE_INT); cr_assert_eq(sym->type->kind, TYPE_INT);
sym_table_free(&table); sym_table_free(&table);

View File

@ -65,3 +65,14 @@ fun empty(n: string) {
} }
empty('useless'); empty('useless');
fun first(n: int) -> int {
return 27;
}
fun first(n: float) -> int {
return 79;
}
assert first(4) == 27;
assert first(7.3) == 79;