🐛 closures and module import repared.
parent
6e6534acbd
commit
2f73e3a0ca
|
@ -21,6 +21,5 @@ void exec_execute(struct exec* self,
|
|||
|
||||
void exec_capture_env(struct exec* self,
|
||||
struct state* state,
|
||||
struct fun* fun,
|
||||
struct env* env);
|
||||
struct fun* fun);
|
||||
#endif
|
||||
|
|
|
@ -14,6 +14,7 @@ struct closure
|
|||
struct fun
|
||||
{
|
||||
int id;
|
||||
int base;
|
||||
struct prog* prog;
|
||||
struct sym* sym;
|
||||
struct vec closures;
|
||||
|
@ -23,7 +24,7 @@ void closure_init(struct closure* self, int id, struct value* value);
|
|||
struct closure* closure_new_clone(struct closure* self);
|
||||
void closure_free(struct closure* self);
|
||||
|
||||
void fun_init(struct fun* self, struct prog* new_prog);
|
||||
void fun_init(struct fun* self, struct prog* new_prog, int base);
|
||||
void fun_free(struct fun* self);
|
||||
struct fun* fun_new_clone(struct fun* self);
|
||||
|
||||
|
|
|
@ -130,9 +130,6 @@ SK state_eq(struct state* self);
|
|||
int state_add_global(struct state* self,
|
||||
struct value* value);
|
||||
|
||||
struct global* state_try_get_global(struct state* self,
|
||||
int id);
|
||||
|
||||
void state_call(struct state* self, struct fun* fun);
|
||||
void state_ret(struct state* self);
|
||||
SK state_add_nfun(struct state* self,
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
#define SK_NO_NATIVE (-1)
|
||||
#include "value.h"
|
||||
|
||||
|
||||
extern int IdCounter;
|
||||
|
||||
struct symbol
|
||||
{
|
||||
int id;
|
||||
|
@ -28,8 +31,6 @@ struct env
|
|||
struct sym
|
||||
{
|
||||
struct sym* parent;
|
||||
int id_counter;
|
||||
int closure_counter;
|
||||
int native_counter;
|
||||
int global_counter;
|
||||
struct env* env;
|
||||
|
@ -40,7 +41,6 @@ struct env* env_new_clone(struct env* self);
|
|||
void env_free(struct env* self);
|
||||
|
||||
struct symbol* env_try_get(struct env* self, char const* name);
|
||||
struct symbol* env_try_find(struct env* self, char const* name);
|
||||
struct symbol* env_try_get_by_id(struct env* self, int id);
|
||||
|
||||
void symbol_init(struct symbol* self,
|
||||
|
|
|
@ -367,7 +367,7 @@ void compiler_compile(struct compiler* self,
|
|||
struct prog* p = malloc(sizeof(struct prog));
|
||||
prog_init(p);
|
||||
|
||||
fun_init(fun, p);
|
||||
fun_init(fun, p, IdCounter);
|
||||
natives_populate(state, fun->sym);
|
||||
|
||||
// Self value
|
||||
|
@ -666,34 +666,24 @@ void compiler_compile_if(struct compiler* self,
|
|||
}
|
||||
}
|
||||
|
||||
TypeKind compiler_node_type(struct compiler* self,
|
||||
struct node* node)
|
||||
{
|
||||
assert(self);
|
||||
assert(node);
|
||||
|
||||
switch (node->kind)
|
||||
{
|
||||
case NODE_INT: return TYPE_INT;
|
||||
default: {
|
||||
fprintf(stderr, "cannot find node type of '%s'",
|
||||
NodeKindStr[node->kind]);
|
||||
abort();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
struct symbol* compiler_find(struct compiler* self,
|
||||
char* name,
|
||||
struct sym* sym,
|
||||
struct node* node)
|
||||
{
|
||||
struct symbol* symbol = NULL;
|
||||
struct sym* itr = sym;
|
||||
struct sym* itr = sym->parent;
|
||||
|
||||
symbol = sym_try_get(sym, name);
|
||||
if (symbol)
|
||||
{
|
||||
return symbol;
|
||||
}
|
||||
|
||||
while (itr)
|
||||
{
|
||||
symbol = sym_try_get(itr, name);
|
||||
|
||||
if (symbol)
|
||||
{
|
||||
if (self->funs.size > 0)
|
||||
|
|
|
@ -179,11 +179,11 @@ void exec_execute(struct exec* self,
|
|||
size_t k = params.size - 1 - i;
|
||||
struct value* val = params.data[k];
|
||||
state_push(state, val->type, val->val, val->line);
|
||||
state_local_store(state, i+1);
|
||||
state_local_store(state, fun->base + i);
|
||||
}
|
||||
|
||||
state_push(state, f->type, f->val, f->line);
|
||||
state_local_store(state, params.size + 1);
|
||||
state_local_store(state, fun->base + params.size);
|
||||
|
||||
vec_free_elements(¶ms, NULL);
|
||||
vec_free(¶ms);
|
||||
|
@ -227,9 +227,9 @@ void exec_execute(struct exec* self,
|
|||
switch (constant->type)
|
||||
{
|
||||
case TYPE_FUN: {
|
||||
struct fun* fun =
|
||||
struct fun* fun =
|
||||
fun_new_clone(constant->val.fun);
|
||||
exec_capture_env(self, state, fun, sym->env);
|
||||
exec_capture_env(self, state, fun);
|
||||
|
||||
state_push_fun(
|
||||
state,
|
||||
|
@ -402,14 +402,13 @@ void exec_execute(struct exec* self,
|
|||
|
||||
void exec_capture_env(struct exec* self,
|
||||
struct state* state,
|
||||
struct fun* fun,
|
||||
struct env* env)
|
||||
struct fun* fun)
|
||||
{
|
||||
(void) self;
|
||||
|
||||
struct env* itr = fun->sym->env;
|
||||
|
||||
if (itr)
|
||||
while (itr)
|
||||
{
|
||||
for (size_t i=0; i<itr->symbols.size; i++)
|
||||
{
|
||||
|
@ -417,7 +416,6 @@ void exec_capture_env(struct exec* self,
|
|||
for (size_t j=0; j<state->frames.size; j++)
|
||||
{
|
||||
size_t k = state->frames.size - j - 1;
|
||||
// HOW TO CHOOSE FRAME ?
|
||||
struct frame* frame = state->frames.data[k];
|
||||
|
||||
if (symbol->closure_id != SK_NO_CLOSURE)
|
||||
|
@ -435,26 +433,9 @@ void exec_capture_env(struct exec* self,
|
|||
loc->addr
|
||||
);
|
||||
|
||||
printf("capture %d\n", symbol->closure_id);
|
||||
fun_capture(fun, symbol->closure_id, val);
|
||||
fun_capture(fun, symbol->id, val);
|
||||
break;
|
||||
}
|
||||
|
||||
// struct local* loc =
|
||||
// state_try_get_local_by_id(
|
||||
// state,
|
||||
// symbol->closure_id
|
||||
// );
|
||||
//
|
||||
// if(!loc) { continue; }
|
||||
//
|
||||
// struct value* val =
|
||||
// state_try_get_value(
|
||||
// state,
|
||||
// loc->addr
|
||||
// );
|
||||
//
|
||||
// fun_capture(fun, symbol->id, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,10 +27,11 @@ void closure_free(struct closure* self)
|
|||
free(self->value);
|
||||
}
|
||||
|
||||
void fun_init(struct fun* self, struct prog* new_prog)
|
||||
void fun_init(struct fun* self, struct prog* new_prog, int base)
|
||||
{
|
||||
assert(self);
|
||||
self->id = FunId;
|
||||
self->base = base;
|
||||
FunId++;
|
||||
self->prog = new_prog;
|
||||
self->sym = malloc(sizeof(struct sym));
|
||||
|
@ -54,7 +55,7 @@ struct fun* fun_new_clone(struct fun* self)
|
|||
{
|
||||
(void) self;
|
||||
struct fun* clone = malloc(sizeof(struct fun));
|
||||
fun_init(clone, prog_new_clone(self->prog));
|
||||
fun_init(clone, prog_new_clone(self->prog), self->base);
|
||||
sym_free(clone->sym);
|
||||
free(clone->sym);
|
||||
clone->sym = sym_new_clone(self->sym);
|
||||
|
|
|
@ -487,7 +487,7 @@ void state_module_load(struct state* self,
|
|||
struct value* mod_value = state_try_deref(self, ref_val->val.ref);
|
||||
struct module* module = mod_value->val.mod;
|
||||
|
||||
struct symbol* symbol = sym_try_get_by_id(
|
||||
struct symbol const* symbol = sym_try_get_by_id(
|
||||
module->sym,
|
||||
id
|
||||
);
|
||||
|
@ -931,22 +931,6 @@ int state_add_global(struct state* self,
|
|||
return addr;
|
||||
}
|
||||
|
||||
struct global* state_try_get_global(struct state* self,
|
||||
int id)
|
||||
{
|
||||
for (size_t i=0; i<self->globals.size; i++)
|
||||
{
|
||||
struct global* glob = self->globals.data[i];
|
||||
|
||||
if (glob->id == id)
|
||||
{
|
||||
return glob;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void state_call(struct state* self, struct fun* fun)
|
||||
{
|
||||
assert(self);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "sym.h"
|
||||
|
||||
int IdCounter = 0;
|
||||
|
||||
void env_init(struct env* self)
|
||||
{
|
||||
assert(self);
|
||||
|
@ -64,11 +66,6 @@ struct symbol* env_try_get(struct env* self, char const* name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct symbol* env_try_find(struct env* self, char const* name)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct symbol* env_try_get_by_id(struct env* self, int id)
|
||||
{
|
||||
assert(self);
|
||||
|
@ -119,8 +116,6 @@ void sym_init(struct sym* self)
|
|||
{
|
||||
assert(self);
|
||||
self->parent = NULL;
|
||||
self->id_counter = 1;
|
||||
self->closure_counter = 1;
|
||||
self->native_counter = 1;
|
||||
self->global_counter = 1;
|
||||
self->env = malloc(sizeof(struct env));
|
||||
|
@ -135,8 +130,6 @@ struct sym* sym_new_clone(struct sym* self)
|
|||
env_free(clone->env);
|
||||
free(clone->env);
|
||||
|
||||
clone->id_counter = self->id_counter;
|
||||
clone->closure_counter = self->closure_counter;
|
||||
clone->parent = self->parent;
|
||||
clone->env = self->env ? env_new_clone(self->env) : NULL;
|
||||
|
||||
|
@ -157,12 +150,11 @@ int sym_decl_var(struct sym* self, char const* name,
|
|||
assert(self);
|
||||
assert(name);
|
||||
struct symbol* symbol = malloc(sizeof(struct symbol));
|
||||
symbol_init(symbol, self->id_counter, name, node, self->env);
|
||||
|
||||
symbol_init(symbol, IdCounter, name, node, self->env);
|
||||
IdCounter++;
|
||||
vec_push(&self->env->symbols, symbol);
|
||||
|
||||
self->id_counter++;
|
||||
return self->id_counter - 1;
|
||||
return symbol->id;
|
||||
}
|
||||
|
||||
int sym_decl_const(struct sym* self, char const* name,
|
||||
|
@ -171,12 +163,12 @@ int sym_decl_const(struct sym* self, char const* name,
|
|||
assert(self);
|
||||
assert(name);
|
||||
struct symbol* symbol = malloc(sizeof(struct symbol));
|
||||
symbol_init(symbol, self->id_counter, name, node, self->env);
|
||||
symbol_init(symbol, IdCounter, name, node, self->env);
|
||||
IdCounter++;
|
||||
symbol->is_const = true;
|
||||
vec_push(&self->env->symbols, symbol);
|
||||
|
||||
self->id_counter++;
|
||||
return self->id_counter - 1;
|
||||
return symbol->id;
|
||||
}
|
||||
|
||||
int sym_decl_closure(struct sym* self, int id, char const* name,
|
||||
|
@ -186,15 +178,15 @@ int sym_decl_closure(struct sym* self, int id, char const* name,
|
|||
assert(name);
|
||||
|
||||
struct symbol* symbol = malloc(sizeof(struct symbol));
|
||||
symbol_init(symbol, self->closure_counter, name, node,
|
||||
symbol_init(symbol, IdCounter, name, node,
|
||||
self->env);
|
||||
IdCounter++;
|
||||
symbol->is_const = false;
|
||||
symbol->closure_id = id;
|
||||
symbol->fun = fun;
|
||||
vec_push(&self->env->symbols, symbol);
|
||||
|
||||
self->closure_counter++;
|
||||
return self->closure_counter - 1;
|
||||
return symbol->id;
|
||||
}
|
||||
|
||||
int sym_decl_global(struct sym* self,
|
||||
|
|
Loading…
Reference in New Issue