Compare commits

...

2 Commits

Author SHA1 Message Date
bog 85875d2d94 function overloading. 2024-02-17 23:35:58 +01:00
bog 6420e283a1 🐛 🐛 void function and compiler segfault. 2024-02-17 22:06:20 +01:00
8 changed files with 181 additions and 39 deletions

View File

@ -76,6 +76,7 @@ int compiler_compile(struct compiler* self,
struct node* ident = idents.data[j];
struct type* ty = malloc(sizeof(struct type));
type_init(ty, TYPE_VOID);
compiler_get_type(self, param, ty);
sym_table_declare_const(&compiler.sym_table,
@ -125,8 +126,15 @@ int compiler_compile(struct compiler* self,
compiler_compile(self, arg, program);
}
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)
{
entry = sym_table_fetch(&self->sym_table,
target->value,
NULL);
}
assert(entry);
@ -246,8 +254,16 @@ int compiler_compile(struct compiler* self,
case NODE_ASSIGN: {
struct node* ident = node->children.data[0];
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);
if (compiler_compile(self, expr, program) != 0)
@ -259,8 +275,9 @@ int compiler_compile(struct compiler* self,
} break;
case NODE_IDENT: {
struct sym* entry = sym_table_try_by_name(&self->sym_table,
node->value);
struct sym* entry = sym_table_fetch(&self->sym_table,
node->value,
NULL);
if (!entry)
{
@ -300,8 +317,9 @@ int compiler_compile(struct compiler* self,
sym_table_declare(&self->sym_table, node->value, ty,
node->type == NODE_VARDECL);
struct sym* entry = sym_table_try_by_name(&self->sym_table,
node->value);
struct sym* entry = sym_table_fetch(&self->sym_table,
node->value,
ty);
assert(entry);

View File

@ -1,5 +1,6 @@
#include "sym_table.h"
#include "commons.h"
#include "type_resolver.h"
#include "vec.h"
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;
}
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);
@ -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];
if (strcmp(sym->name, name) == 0)
if (strcmp(sym->name, name) == 0
&& (type == NULL || type_equals(type, sym->type)))
{
return sym;
}
@ -92,7 +96,88 @@ struct sym* sym_table_try_by_name(struct sym_table* self, char* const name)
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;
@ -120,9 +205,10 @@ int sym_table_declare(struct sym_table* self,
assert(self);
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;
}
@ -150,9 +236,10 @@ int sym_table_declare_global(struct sym_table* self,
assert(self);
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;
}

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_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,
char* const name,
struct type* new_type);

View File

@ -81,8 +81,10 @@ int type_checker_check(struct type_checker* self,
case NODE_CALL: {
struct node* target = node->children.data[0];
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)
{
@ -95,7 +97,6 @@ int type_checker_check(struct type_checker* self,
struct type* ty = entry->type;
assert(ty);
if (ty->subtypes.size - 1 != args->children.size)
{
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* expr = node->children.data[1];
struct sym* entry = sym_table_try_by_name(&self->sym_table,
ident->value);
struct sym* entry = sym_table_fetch(&self->sym_table,
ident->value,
NULL);
if (!entry)
{
@ -318,10 +320,19 @@ int type_checker_check(struct type_checker* self,
case NODE_VARDECL:
case NODE_CONSTDECL:{
struct sym* entry = sym_table_try_by_name(&self->sym_table,
node->value);
struct type type;
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,
"%s is already defined", node->value);

View File

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

View File

@ -6,7 +6,7 @@ Test(sym_table, simple) {
struct sym_table table;
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);
struct type* ty = malloc(sizeof(struct type));
@ -15,7 +15,7 @@ Test(sym_table, simple) {
int err = sym_table_declare_const(&table, "hello", ty);
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_str_eq("hello", sym->name);
@ -58,15 +58,15 @@ Test(sym_table, scope) {
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);
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);
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);
sym_table_free(&table);
@ -84,7 +84,7 @@ Test(sym_table, outer_scope) {
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);
sym_table_free(&table);

View File

@ -64,4 +64,15 @@ fun empty(n: string) {
return;
}
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;

View File

@ -208,13 +208,19 @@ int vm_exec(struct vm* self, struct program* program)
vec_free(&args);
struct value* ret_val =
fun->program.constant_pool.data[my_frame->stack[my_frame->sp - 1]];
(my_frame->sp > 0)
? fun->program.constant_pool.data
[my_frame->stack[my_frame->sp - 1]]
: NULL;
struct value* new_ret = value_new_clone(ret_val);
struct value* new_ret = ret_val ? value_new_clone(ret_val) : NULL;
vm_remove_frame(self);
vm_push(self, program_push_constant(program, new_ret));
if (new_ret)
{
vm_push(self, program_push_constant(program, new_ret));
}
self->pc = ret_addr + 1;