Compare commits
No commits in common. "3f3835839061bc1d9c67f19ed18d1532f47fbd83" and "9ab09e85f60e1a6c50a7cedaf8811c14e4807b76" have entirely different histories.
3f38358390
...
9ab09e85f6
190
src/compiler.c
190
src/compiler.c
|
@ -11,9 +11,6 @@ void compiler_init(compiler* self)
|
|||
self->binfo.capacity = 1;
|
||||
self->binfo.data = malloc(sizeof(block_info*) * self->binfo.capacity);
|
||||
|
||||
self->fun_stack.size = 0;
|
||||
self->fun_stack.capacity = 1;
|
||||
self->fun_stack.data = malloc(sizeof(char*) * self->fun_stack.capacity);
|
||||
}
|
||||
|
||||
void compiler_free(compiler* self)
|
||||
|
@ -24,17 +21,6 @@ void compiler_free(compiler* self)
|
|||
free(self->sym);
|
||||
self->sym = NULL;
|
||||
|
||||
for (size_t i=0; i<self->fun_stack.size; i++)
|
||||
{
|
||||
free(self->fun_stack.data[i]);
|
||||
}
|
||||
|
||||
free(self->fun_stack.data);
|
||||
|
||||
self->fun_stack.size = 0;
|
||||
self->fun_stack.capacity = 0;
|
||||
self->fun_stack.data = NULL;
|
||||
|
||||
for (size_t i=0; i<self->binfo.size; i++)
|
||||
{
|
||||
block_info_free(self->binfo.data[i]);
|
||||
|
@ -48,39 +34,6 @@ void compiler_free(compiler* self)
|
|||
self->binfo.data = NULL;
|
||||
}
|
||||
|
||||
void compiler_push_fun(compiler* self, char* fun_name)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
if (self->fun_stack.size >= self->fun_stack.capacity)
|
||||
{
|
||||
self->fun_stack.capacity *= 2;
|
||||
self->fun_stack.data = realloc(
|
||||
self->fun_stack.data,
|
||||
sizeof(char*) * self->fun_stack.capacity
|
||||
);
|
||||
}
|
||||
|
||||
self->fun_stack.data[self->fun_stack.size] = str_new(fun_name);
|
||||
self->fun_stack.size++;
|
||||
}
|
||||
|
||||
void compiler_pop_fun(compiler* self)
|
||||
{
|
||||
assert(self);
|
||||
assert(self->fun_stack.size > 0);
|
||||
|
||||
free(self->fun_stack.data[self->fun_stack.size - 1]);
|
||||
self->fun_stack.size--;
|
||||
}
|
||||
|
||||
char* compiler_top_fun(compiler* self)
|
||||
{
|
||||
assert(self);
|
||||
assert(self->fun_stack.size > 0);
|
||||
return self->fun_stack.data[self->fun_stack.size - 1];
|
||||
}
|
||||
|
||||
block_info* compiler_current_info(compiler* self)
|
||||
{
|
||||
assert(self);
|
||||
|
@ -214,32 +167,6 @@ void compile_node(compiler* self, node* root, program* prog)
|
|||
program_add_instr(prog, OP_ADEREF, NO_PARAM);
|
||||
}
|
||||
// Variables stuff
|
||||
else if (root->type == NODE_FUNDECL)
|
||||
{
|
||||
cstatic cs;
|
||||
cstatic_init(&cs);
|
||||
type* ty = cstatic_resolve_new(&cs,
|
||||
self->sym,
|
||||
root->children.data[1]);
|
||||
|
||||
size_t id = symtable_declare(
|
||||
self->sym,
|
||||
root->children.data[0]->value,
|
||||
ty,
|
||||
root->children.data[1]
|
||||
);
|
||||
|
||||
|
||||
compiler_push_fun(self, root->children.data[0]->value);
|
||||
compile_node(self, root->children.data[1], prog);
|
||||
compiler_pop_fun(self);
|
||||
|
||||
program_add_instr(prog, OP_STORE, id);
|
||||
|
||||
type_free(ty);
|
||||
free(ty);
|
||||
cstatic_free(&cs);
|
||||
}
|
||||
else if (root->type == NODE_CONSTDECL)
|
||||
{
|
||||
cstatic cs;
|
||||
|
@ -256,20 +183,7 @@ void compile_node(compiler* self, node* root, program* prog)
|
|||
root->children.data[1]
|
||||
);
|
||||
|
||||
int is_fn = root->children.data[1]->type == NODE_FUN;
|
||||
|
||||
if (is_fn)
|
||||
{
|
||||
compiler_push_fun(self, root->children.data[0]->value);
|
||||
}
|
||||
|
||||
compile_node(self, root->children.data[1], prog);
|
||||
|
||||
if (is_fn)
|
||||
{
|
||||
compiler_pop_fun(self);
|
||||
}
|
||||
|
||||
program_add_instr(prog, OP_STORE, id);
|
||||
|
||||
type_free(ty);
|
||||
|
@ -297,22 +211,9 @@ void compile_node(compiler* self, node* root, program* prog)
|
|||
root->children.data[1]
|
||||
);
|
||||
|
||||
int is_fn = root->children.data[1]->type == NODE_FUN;
|
||||
|
||||
if (is_fn)
|
||||
{
|
||||
compiler_push_fun(self, root->children.data[0]->value);
|
||||
}
|
||||
|
||||
compile_node(self, root->children.data[1], prog);
|
||||
|
||||
if (is_fn)
|
||||
{
|
||||
compiler_pop_fun(self);
|
||||
}
|
||||
|
||||
program_add_instr(prog, OP_STORE, id);
|
||||
|
||||
|
||||
type_free(ty);
|
||||
free(ty);
|
||||
cstatic_free(&cs);
|
||||
|
@ -369,7 +270,6 @@ void compile_node(compiler* self, node* root, program* prog)
|
|||
int lhs = cstatic_resolve_base_type(&cs,
|
||||
self->sym,
|
||||
root->children.data[0]);
|
||||
|
||||
int rhs = cstatic_resolve_base_type(&cs, self->sym,
|
||||
root->children.data[1]);
|
||||
|
||||
|
@ -443,70 +343,64 @@ void compile_node(compiler* self, node* root, program* prog)
|
|||
}
|
||||
else if (root->type == NODE_FUN)
|
||||
{
|
||||
|
||||
// prepare compiler
|
||||
// init body
|
||||
compiler comp;
|
||||
compiler_init(&comp);
|
||||
program* fun_prog = malloc(sizeof(program));
|
||||
program_init(fun_prog);
|
||||
node* block = root->children.data[root->children.size - 1];
|
||||
|
||||
// prepare program
|
||||
program local_prog;
|
||||
program_init(&local_prog);
|
||||
|
||||
// resolve function type
|
||||
cstatic cs;
|
||||
cstatic_init(&cs);
|
||||
type* fn_ty = cstatic_resolve_new(&cs, self->sym, root);
|
||||
|
||||
// prepare environment (parameters and function)
|
||||
|
||||
// add params
|
||||
for (size_t i=0; i<root->children.size; i++)
|
||||
{
|
||||
node* param = root->children.data[i];
|
||||
if (param->type != NODE_FUN_PARAM) { continue; }
|
||||
|
||||
char* name = param->children.data[0]->value;
|
||||
type* ty = type_new_from_node(param->children.data[1]);
|
||||
|
||||
symtable_declare(
|
||||
comp.sym,
|
||||
name,
|
||||
ty,
|
||||
param
|
||||
);
|
||||
if (param->type == NODE_FUN_PARAM)
|
||||
{
|
||||
char const* param_name = param->children.data[0]->value;
|
||||
type* param_ty =
|
||||
type_new_from_node(param->children.data[1]);
|
||||
|
||||
type_free(ty); free(ty);
|
||||
symtable_declare(comp.sym, param_name
|
||||
, param_ty
|
||||
, param->children.data[0]);
|
||||
|
||||
type_free(param_ty); free(param_ty);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char* fun_name = compiler_top_fun(self);
|
||||
// compile body
|
||||
compile_node(&comp, block, fun_prog);
|
||||
compiler_free(&comp);
|
||||
|
||||
symtable_declare(
|
||||
comp.sym,
|
||||
fun_name,
|
||||
fn_ty,
|
||||
root
|
||||
);
|
||||
|
||||
// compile fun block
|
||||
node* fun_block = root->children.data[root->children.size - 1];
|
||||
compile_node(&comp, fun_block, &local_prog);
|
||||
//char c[1024]; node_str(root, c, 1024); printf("%s\n", c);
|
||||
|
||||
// create value
|
||||
// init fun object
|
||||
cstatic cs;
|
||||
cstatic_init(&cs);
|
||||
|
||||
fun* fn = malloc(sizeof(fun));
|
||||
fun_init(fn, fn_ty, (struct program*) &local_prog);
|
||||
type* ty = cstatic_resolve_new(&cs, self->sym, root);
|
||||
|
||||
fun_init(fn, ty, (struct program*) fun_prog);
|
||||
program_free(fun_prog); free(fun_prog); fun_prog = NULL;
|
||||
|
||||
type_free(ty); free(ty);
|
||||
|
||||
// create value
|
||||
value* val = malloc(sizeof(value));
|
||||
value_init_fun(val, fn, root->lineno);
|
||||
cstatic_free(&cs);
|
||||
|
||||
// push it
|
||||
program_add_instr(
|
||||
prog,
|
||||
OP_PUSH,
|
||||
program_add_pool(prog, val)
|
||||
);
|
||||
|
||||
// push value
|
||||
program_add_instr(prog, OP_PUSH, program_add_pool(prog, val));
|
||||
|
||||
// free stuff
|
||||
program_free(&local_prog);
|
||||
compiler_free(&comp);
|
||||
type_free(fn_ty); free(fn_ty);
|
||||
value_free(val); free(val);
|
||||
fun_free(fn); free(fn);
|
||||
|
||||
cstatic_free(&cs);
|
||||
}
|
||||
else if (root->type == NODE_CALL)
|
||||
{
|
||||
|
|
|
@ -16,20 +16,11 @@ typedef struct {
|
|||
block_info** data;
|
||||
} binfo;
|
||||
|
||||
struct {
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
char** data;
|
||||
} fun_stack;
|
||||
|
||||
} compiler;
|
||||
|
||||
void compiler_init(compiler* self);
|
||||
void compiler_free(compiler* self);
|
||||
|
||||
void compiler_push_fun(compiler* self, char* fun_name);
|
||||
void compiler_pop_fun(compiler* self);
|
||||
char* compiler_top_fun(compiler* self);
|
||||
|
||||
block_info* compiler_current_info(compiler* self);
|
||||
block_info* compiler_find_info(compiler* self, int kind);
|
||||
|
|
227
src/cstatic.c
227
src/cstatic.c
|
@ -7,7 +7,7 @@ void cstatic_init(cstatic* self)
|
|||
|
||||
self->fun_types.size = 0;
|
||||
self->fun_types.capacity = 1;
|
||||
self->fun_types.data = malloc(sizeof(fun_info*) * self->fun_types.capacity);
|
||||
self->fun_types.data = malloc(sizeof(type*) * self->fun_types.capacity);
|
||||
}
|
||||
|
||||
void cstatic_free(cstatic* self)
|
||||
|
@ -16,8 +16,8 @@ void cstatic_free(cstatic* self)
|
|||
|
||||
for (size_t i=0; i<self->fun_types.size; i++)
|
||||
{
|
||||
type_free(self->fun_types.data[i]->ty);
|
||||
free(self->fun_types.data[i]->ty);
|
||||
type_free(self->fun_types.data[i]);
|
||||
free(self->fun_types.data[i]);
|
||||
}
|
||||
|
||||
free(self->fun_types.data);
|
||||
|
@ -63,6 +63,7 @@ type* cstatic_resolve_new(cstatic* self, symtable* sym, node* ast)
|
|||
type_new_from_node(
|
||||
ast->children.data[i]->children.data[1]
|
||||
);
|
||||
|
||||
type_add_sub_type(ty, param_ty);
|
||||
type_free(param_ty); free(param_ty);
|
||||
|
||||
|
@ -73,7 +74,7 @@ type* cstatic_resolve_new(cstatic* self, symtable* sym, node* ast)
|
|||
&& ast->children.data[i]->type == NODE_FUN_RET)
|
||||
{
|
||||
node* ret = ast->children.data[i];
|
||||
|
||||
|
||||
for (size_t i=0; i<ret->children.size; i++)
|
||||
{
|
||||
type* r = type_new_from_node(ret->children.data[i]);
|
||||
|
@ -89,46 +90,20 @@ type* cstatic_resolve_new(cstatic* self, symtable* sym, node* ast)
|
|||
if (ast->type == NODE_CALL)
|
||||
{
|
||||
char const* fun_name = ast->children.data[0]->value;
|
||||
|
||||
symentry* entry = symtable_find(sym, fun_name);
|
||||
fun_info* info = NULL;
|
||||
|
||||
if (self->fun_types.size > 0)
|
||||
{
|
||||
info = cstatic_top_fun(self);
|
||||
}
|
||||
assert(entry);
|
||||
|
||||
type* fun_type = NULL;
|
||||
|
||||
if (entry)
|
||||
{
|
||||
fun_type = entry->ty;
|
||||
}
|
||||
else if (info && info->name && strcmp(info->name, fun_name) == 0)
|
||||
{
|
||||
fun_type = info->ty;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr
|
||||
, "E(%d): cannot call unknown function '%s'.\n"
|
||||
, ast->children.data[0]->lineno
|
||||
, fun_name);
|
||||
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
type* fun_type = entry->ty;
|
||||
assert(fun_type);
|
||||
|
||||
|
||||
size_t ret_count = fun_type->sub_types.size;
|
||||
|
||||
if (ret_count > 0)
|
||||
{
|
||||
type* ret_type =
|
||||
fun_type->sub_types.data[ret_count - 1];
|
||||
|
||||
type* ret_type = fun_type->sub_types.data[ret_count - 1];
|
||||
assert(ret_type);
|
||||
|
||||
|
||||
if (ret_type->kind == KIND_RETURN)
|
||||
{
|
||||
type* res = type_new_clone(ret_type);
|
||||
|
@ -185,9 +160,7 @@ type* cstatic_resolve_new(cstatic* self, symtable* sym, node* ast)
|
|||
return ty;
|
||||
}
|
||||
|
||||
if (ast->type == NODE_VARDECL
|
||||
|| ast->type == NODE_CONSTDECL
|
||||
|| ast->type == NODE_FUNDECL)
|
||||
if (ast->type == NODE_VARDECL)
|
||||
{
|
||||
type* ty = cstatic_resolve_new(self,
|
||||
sym,
|
||||
|
@ -365,7 +338,7 @@ int cstatic_check(cstatic* self, node* ast, symtable* sym, char* msg, size_t siz
|
|||
{
|
||||
assert(self);
|
||||
assert(ast);
|
||||
|
||||
|
||||
// BLOCK
|
||||
if (ast->type == NODE_BLOCK)
|
||||
{
|
||||
|
@ -392,7 +365,9 @@ int cstatic_check(cstatic* self, node* ast, symtable* sym, char* msg, size_t siz
|
|||
if (ast->type == NODE_FUN)
|
||||
{
|
||||
type* ty = cstatic_resolve_new(self, sym, ast);
|
||||
|
||||
|
||||
cstatic_push_fun(self, ty);
|
||||
|
||||
type_free(ty); free(ty);
|
||||
|
||||
symtable* inner_table = symtable_new_clone(sym);
|
||||
|
@ -419,7 +394,9 @@ int cstatic_check(cstatic* self, node* ast, symtable* sym, char* msg, size_t siz
|
|||
msg,
|
||||
size
|
||||
);
|
||||
|
||||
symtable_free(inner_table); free(inner_table);
|
||||
cstatic_pop_fun(self);
|
||||
|
||||
|
||||
return status;
|
||||
|
@ -429,12 +406,7 @@ int cstatic_check(cstatic* self, node* ast, symtable* sym, char* msg, size_t siz
|
|||
if (ast->type == NODE_RETURN)
|
||||
{
|
||||
type* ret_ty = cstatic_resolve_new(self, sym, ast);
|
||||
|
||||
int status_inner = cstatic_check_children(self, ast, sym, msg, size);
|
||||
|
||||
if (!status_inner) { return status_inner; }
|
||||
|
||||
type* fun_ty = cstatic_top_fun(self)->ty;
|
||||
type* fun_ty = cstatic_top_fun(self);
|
||||
|
||||
type* fun_res = NULL;
|
||||
|
||||
|
@ -449,7 +421,7 @@ int cstatic_check(cstatic* self, node* ast, symtable* sym, char* msg, size_t siz
|
|||
}
|
||||
|
||||
assert(fun_res);
|
||||
assert(ret_ty);
|
||||
|
||||
int status = cstatic_check_same_type_ptr(
|
||||
self,
|
||||
ast,
|
||||
|
@ -477,32 +449,16 @@ int cstatic_check(cstatic* self, node* ast, symtable* sym, char* msg, size_t siz
|
|||
{
|
||||
char const* fun_name = ast->children.data[0]->value;
|
||||
symentry* entry = symtable_find(sym, fun_name);
|
||||
assert(entry);
|
||||
|
||||
type* fun_type = NULL;
|
||||
|
||||
if (entry)
|
||||
{
|
||||
fun_type = entry->ty;
|
||||
}
|
||||
else
|
||||
{
|
||||
fun_info* info = cstatic_top_fun(self);
|
||||
|
||||
if (info && info->name)
|
||||
{
|
||||
fun_type = info->ty;
|
||||
}
|
||||
}
|
||||
type* fun_type = entry->ty;
|
||||
|
||||
assert(fun_type);
|
||||
|
||||
node* args = ast->children.data[1];
|
||||
size_t arity = 0;
|
||||
|
||||
for (size_t i=0; i<fun_type->sub_types.size; i++)
|
||||
{
|
||||
type* ty = fun_type->sub_types.data[i];
|
||||
|
||||
if (ty->kind != KIND_RETURN)
|
||||
{
|
||||
arity++;
|
||||
|
@ -557,7 +513,7 @@ int cstatic_check(cstatic* self, node* ast, symtable* sym, char* msg, size_t siz
|
|||
}
|
||||
|
||||
// Children
|
||||
/*for (size_t i=0; i<ast->children.size; i++)
|
||||
for (size_t i=0; i<ast->children.size; i++)
|
||||
{
|
||||
int status = cstatic_check(self, ast->children.data[i],
|
||||
sym,
|
||||
|
@ -568,59 +524,6 @@ int cstatic_check(cstatic* self, node* ast, symtable* sym, char* msg, size_t siz
|
|||
return 0;
|
||||
}
|
||||
|
||||
}*/
|
||||
|
||||
if (ast->type == NODE_VARDECL
|
||||
|| ast->type == NODE_CONSTDECL
|
||||
|| ast->type == NODE_FUNDECL)
|
||||
{
|
||||
char const* name = ast->children.data[0]->value;
|
||||
|
||||
symentry* entry = symtable_find(sym, name);
|
||||
if (entry && entry->scope >= sym->scope)
|
||||
{
|
||||
fprintf(stderr, "E(%d): '%s' is already defined.\n",
|
||||
ast->lineno,
|
||||
name);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
type* ty = cstatic_resolve_new(self, sym, ast->children.data[1]);
|
||||
|
||||
if (ty->base_type == TY_FUNCTION)
|
||||
{
|
||||
cstatic_push_fun(self, ast->children.data[0]->value, ty);
|
||||
int status =
|
||||
cstatic_check(self, ast->children.data[1], sym, msg, size);
|
||||
cstatic_pop_fun(self);
|
||||
|
||||
if (!status) { return status; }
|
||||
}
|
||||
else
|
||||
{
|
||||
int status =
|
||||
cstatic_check(self, ast->children.data[1], sym, msg, size);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
assert(ty);
|
||||
|
||||
if (ast->type == NODE_VARDECL)
|
||||
{
|
||||
symtable_declare_mut(sym, name, ty, ast->children.data[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
symtable_declare(sym, name, ty, ast->children.data[1]);
|
||||
}
|
||||
|
||||
type_free(ty);
|
||||
free(ty);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Arrays
|
||||
|
@ -822,6 +725,36 @@ int cstatic_check(cstatic* self, node* ast, symtable* sym, char* msg, size_t siz
|
|||
|
||||
return 1;
|
||||
}
|
||||
if (ast->type == NODE_VARDECL
|
||||
|| ast->type == NODE_CONSTDECL)
|
||||
{
|
||||
char const* name = ast->children.data[0]->value;
|
||||
symentry* entry = symtable_find(sym, name);
|
||||
|
||||
if (entry && entry->scope >= sym->scope)
|
||||
{
|
||||
fprintf(stderr, "E(%d): '%s' is already defined.\n",
|
||||
ast->lineno,
|
||||
name);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
type* ty = cstatic_resolve_new(self, sym, ast->children.data[1]);
|
||||
assert(ty);
|
||||
|
||||
if (ast->type == NODE_VARDECL)
|
||||
{
|
||||
symtable_declare_mut(sym, name, ty, ast->children.data[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
symtable_declare(sym, name, ty, ast->children.data[1]);
|
||||
}
|
||||
|
||||
type_free(ty);
|
||||
free(ty);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Types Operations
|
||||
if (ast->type == NODE_MUL)
|
||||
|
@ -1063,36 +996,6 @@ int cstatic_check(cstatic* self, node* ast, symtable* sym, char* msg, size_t siz
|
|||
}
|
||||
}
|
||||
|
||||
for (size_t i=0; i<ast->children.size; i++)
|
||||
{
|
||||
int status = cstatic_check(self, ast->children.data[i],
|
||||
sym,
|
||||
msg, size);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cstatic_check_children(cstatic* self, node* lhs, symtable* sym, char* msg, size_t size)
|
||||
{
|
||||
for (size_t i=0; i<lhs->children.size; i++)
|
||||
{
|
||||
int status = cstatic_check(self, lhs->children.data[i],
|
||||
sym,
|
||||
msg, size);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1265,7 +1168,7 @@ int cstatic_check_same_type(cstatic* self, node* lhs, node* rhs, symtable* sym,
|
|||
return 1;
|
||||
}
|
||||
|
||||
void cstatic_push_fun(cstatic* self, char* name, type* fun_ty)
|
||||
void cstatic_push_fun(cstatic* self, type* fun_ty)
|
||||
{
|
||||
assert(self);
|
||||
assert(fun_ty);
|
||||
|
@ -1275,18 +1178,11 @@ void cstatic_push_fun(cstatic* self, char* name, type* fun_ty)
|
|||
self->fun_types.capacity *= 2;
|
||||
self->fun_types.data = realloc(
|
||||
self->fun_types.data,
|
||||
sizeof(fun_info*) * self->fun_types.capacity
|
||||
sizeof(type*) * self->fun_types.capacity
|
||||
);
|
||||
}
|
||||
|
||||
self->fun_types.data[self->fun_types.size] = malloc(sizeof(fun_info));
|
||||
self->fun_types.data[self->fun_types.size]->ty = type_new_clone(fun_ty);
|
||||
|
||||
if (name)
|
||||
{
|
||||
self->fun_types.data[self->fun_types.size]->name = str_new(name);
|
||||
}
|
||||
|
||||
self->fun_types.data[self->fun_types.size] = type_new_clone(fun_ty);
|
||||
self->fun_types.size++;
|
||||
|
||||
}
|
||||
|
@ -1295,20 +1191,13 @@ void cstatic_pop_fun(cstatic* self)
|
|||
{
|
||||
assert(self->fun_types.size > 0);
|
||||
|
||||
type_free(self->fun_types.data[self->fun_types.size - 1]->ty);
|
||||
free(self->fun_types.data[self->fun_types.size - 1]->ty);
|
||||
|
||||
if (self->fun_types.data[self->fun_types.size - 1]->name)
|
||||
{
|
||||
free(self->fun_types.data[self->fun_types.size - 1]->name);
|
||||
}
|
||||
|
||||
type_free(self->fun_types.data[self->fun_types.size - 1]);
|
||||
free(self->fun_types.data[self->fun_types.size - 1]);
|
||||
|
||||
self->fun_types.size--;
|
||||
}
|
||||
|
||||
fun_info* cstatic_top_fun(cstatic* self)
|
||||
type* cstatic_top_fun(cstatic* self)
|
||||
{
|
||||
assert(self->fun_types.size > 0);
|
||||
return self->fun_types.data[self->fun_types.size - 1];
|
||||
|
|
|
@ -7,16 +7,11 @@
|
|||
|
||||
#define TYPE_END (-1)
|
||||
|
||||
typedef struct {
|
||||
type* ty;
|
||||
char* name;
|
||||
} fun_info;
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
fun_info** data;
|
||||
type** data;
|
||||
} fun_types;
|
||||
} cstatic;
|
||||
|
||||
|
@ -29,8 +24,6 @@ int cstatic_resolve_base_type(cstatic* self, symtable* sym, node* ast);
|
|||
type* cstatic_resolve_new(cstatic* self, symtable* sym, node* ast);
|
||||
int cstatic_check(cstatic* self, node* ast, symtable* sym, char* msg, size_t size);
|
||||
|
||||
int cstatic_check_children(cstatic* self, node* lhs, symtable* sym, char* msg, size_t size);
|
||||
|
||||
int cstatic_check_type(cstatic* self, node* lhs, symtable* sym,
|
||||
char* msg, size_t size, type* types, ...);
|
||||
|
||||
|
@ -44,7 +37,7 @@ int cstatic_check_same_type_ptr(cstatic* self,
|
|||
int cstatic_check_same_type(cstatic* self, node* lhs, node* rhs, symtable* sym,
|
||||
char* msg, size_t size);
|
||||
|
||||
void cstatic_push_fun(cstatic* self, char* name, type* fun_ty);
|
||||
void cstatic_push_fun(cstatic* self, type* fun_ty);
|
||||
void cstatic_pop_fun(cstatic* self);
|
||||
fun_info* cstatic_top_fun(cstatic* self);
|
||||
type* cstatic_top_fun(cstatic* self);
|
||||
#endif
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
G(NODE_IF), G(NODE_ELSE), G(NODE_BLOCK), \
|
||||
G(NODE_WHILE), G(NODE_CONTINUE), G(NODE_BREAK), \
|
||||
G(NODE_COLON), G(NODE_FUN_TYPE), G(NODE_RETURN), G(NODE_FUN), \
|
||||
G(NODE_FUN_PARAM), G(NODE_FUN_RET), G(NODE_CALL), G(NODE_ARGS), \
|
||||
G(NODE_FUNDECL)
|
||||
G(NODE_FUN_PARAM), G(NODE_FUN_RET), G(NODE_CALL), G(NODE_ARGS)
|
||||
|
||||
|
||||
#include "mutils.h"
|
||||
|
|
62
src/parser.y
62
src/parser.y
|
@ -29,7 +29,7 @@
|
|||
%token BREAK
|
||||
%left ASSERT
|
||||
%token <str> TYPE BOOLEAN INTEGER FLOAT STRING IDENT
|
||||
%type <n_children> expr exprs prog array builtins fun_body
|
||||
%type <n_children> expr exprs prog array builtins
|
||||
%type <n_children> expr_list type type_list ident if
|
||||
%type <n_children> fun_rets fun_params fun_param fun
|
||||
%type <n_children> fun_ret_list fun_call fun_args any instr
|
||||
|
@ -595,49 +595,33 @@ fun_rets:
|
|||
;
|
||||
|
||||
fun:
|
||||
FUN ident fun_body {
|
||||
FUN OPAR fun_params CPAR fun_rets block END {
|
||||
node* n = malloc(sizeof(node));
|
||||
node_init(n, NODE_FUN, "", line);
|
||||
size_t const SZ = $3;
|
||||
node* all[SZ];
|
||||
|
||||
node* block_node = stack_pop();
|
||||
assert(block_node);
|
||||
|
||||
for (size_t i=0; i<SZ; i++)
|
||||
node* ret_node = stack_pop();
|
||||
assert(ret_node);
|
||||
|
||||
if ($3 > 0)
|
||||
{
|
||||
all[SZ - 1 - i] = stack_pop();
|
||||
}
|
||||
|
||||
node* ident_node = stack_pop();
|
||||
node* params[$3];
|
||||
|
||||
for (size_t i=0; i<SZ; i++)
|
||||
{
|
||||
node_add_child(n, all[i]);
|
||||
}
|
||||
|
||||
node* fdecl = malloc(sizeof(node));
|
||||
node_init(fdecl, NODE_FUNDECL, "", line);
|
||||
|
||||
node_add_child(fdecl, ident_node);
|
||||
node_add_child(fdecl, n);
|
||||
|
||||
stack_push(fdecl);
|
||||
$$ = 1;
|
||||
}
|
||||
for (size_t i=0; i<$3; i++)
|
||||
{
|
||||
params[i] = stack_pop();
|
||||
}
|
||||
|
||||
| FUN fun_body {
|
||||
node* n = malloc(sizeof(node));
|
||||
node_init(n, NODE_FUN, "", line);
|
||||
size_t const SZ = $2;
|
||||
node* all[SZ];
|
||||
|
||||
for (size_t i=0; i<SZ; i++)
|
||||
{
|
||||
all[SZ - 1 - i] = stack_pop();
|
||||
for (size_t i=0; i<$3; i++)
|
||||
{
|
||||
node_add_child(n, params[$3 - 1 - i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i=0; i<SZ; i++)
|
||||
{
|
||||
node_add_child(n, all[i]);
|
||||
}
|
||||
node_add_child(n, ret_node);
|
||||
node_add_child(n, block_node);
|
||||
|
||||
stack_push(n);
|
||||
|
||||
|
@ -645,12 +629,6 @@ fun:
|
|||
}
|
||||
;
|
||||
|
||||
fun_body:
|
||||
OPAR fun_params CPAR fun_rets block END {
|
||||
$$ = $2 + $4 + $5;
|
||||
}
|
||||
;
|
||||
|
||||
fun_args:
|
||||
expr_list {
|
||||
node* n = malloc(sizeof(node));
|
||||
|
|
|
@ -35,7 +35,6 @@ type* type_init_from_node(node* root)
|
|||
for (size_t i=0; i< rets->children.size; i++)
|
||||
{
|
||||
type* t = type_new_from_node(rets->children.data[i]);
|
||||
t->kind = KIND_RETURN;
|
||||
type_add_sub_type(ty, t);
|
||||
type_free(t); free(t);
|
||||
}
|
||||
|
|
37
src/vm.c
37
src/vm.c
|
@ -1150,11 +1150,7 @@ void vm_call(vm* self, int param)
|
|||
{
|
||||
assert(self);
|
||||
|
||||
vm v;
|
||||
vm_init(&v);
|
||||
|
||||
|
||||
// get arguments
|
||||
// get function and parameters
|
||||
value* args[param];
|
||||
|
||||
for (int i=0; i<param; i++)
|
||||
|
@ -1162,30 +1158,33 @@ void vm_call(vm* self, int param)
|
|||
args[param - 1 - i] = vm_pop_value(self);
|
||||
}
|
||||
|
||||
value* fun_val = vm_pop_value(self);
|
||||
fun* f = fun_val->val.fun_val;
|
||||
|
||||
// create new ecxecution environment
|
||||
vm v;
|
||||
vm_init(&v);
|
||||
|
||||
for (int i=0; i<param; i++)
|
||||
{
|
||||
vm_set(&v, i, args[i]);
|
||||
vm_set(&v, i, args[i]);
|
||||
}
|
||||
|
||||
// execute function
|
||||
vm_exec(&v, (program*) f->prog);
|
||||
|
||||
// get calling function
|
||||
value* function_val = vm_pop_value(self);
|
||||
fun* function = function_val->val.fun_val;
|
||||
vm_set(&v, param, function_val);
|
||||
|
||||
// execute and finalize
|
||||
value* ret = value_new_clone(v.stack.data[v.stack.size - 1]);
|
||||
vm_push_value(self, ret);
|
||||
|
||||
vm_exec(&v, (program*) function->prog);
|
||||
vm_push_value(self, value_new_clone(v.stack.data[v.stack.size - 1]));
|
||||
|
||||
|
||||
// cleanup
|
||||
vm_free(&v);
|
||||
value_free(function_val); free(function_val);
|
||||
|
||||
|
||||
for (int i=0; i<param; i++)
|
||||
{
|
||||
value_free(args[i]); free(args[i]);
|
||||
}
|
||||
|
||||
value_free(fun_val); free(fun_val);
|
||||
|
||||
self->pc++;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,38 +30,3 @@ end
|
|||
|
||||
assert 43 == *d
|
||||
|
||||
fun e (n as int) as int
|
||||
return n * 2
|
||||
end
|
||||
|
||||
assert 14 == e 7
|
||||
|
||||
fun f (n as int) as int
|
||||
if n == 0
|
||||
return 1
|
||||
end
|
||||
|
||||
return n * f(n - 1)
|
||||
end
|
||||
|
||||
assert 120 == f 5
|
||||
|
||||
fun h (n as int, m as fun<int:int>) as int
|
||||
return (m (m n))
|
||||
end
|
||||
|
||||
fun i (n as int) as int
|
||||
return n * 3
|
||||
end
|
||||
|
||||
assert 27 == h 3, i
|
||||
|
||||
fun j (n as int) as int
|
||||
fun j_inner (n as int) as int
|
||||
return n * 2
|
||||
end
|
||||
|
||||
return j_inner (j_inner n)
|
||||
end
|
||||
|
||||
assert 32 == j 8
|
||||
|
|
Loading…
Reference in New Issue