🐛 major closure issues.

main
bog 2023-12-24 20:24:41 +01:00
parent 84f5425804
commit 85c289af2a
9 changed files with 81 additions and 23 deletions

View File

@ -413,9 +413,9 @@ int compiler_run(compiler_t* compiler, node_t* node, program_t* program)
fun->arg_base = *compiler->id; fun->arg_base = *compiler->id;
compiler_run(&comp, (node_t*) node->children.data[1], &fun->program); compiler_run(&comp, (node_t*) node->children.data[1], fun->program);
compiler_run(&comp, (node_t*) node->children.data[2], &fun->program); compiler_run(&comp, (node_t*) node->children.data[2], fun->program);
program_push_instr(&fun->program, OP_RET, RZ_NO_PARAM); program_push_instr(fun->program, OP_RET, RZ_NO_PARAM);
prepass_free(&pre); prepass_free(&pre);
tysolver_free(&tysolver); tysolver_free(&tysolver);

View File

@ -6,7 +6,9 @@
void fun_init(fun_t* fun, struct tysy* tysy, err_t* err) void fun_init(fun_t* fun, struct tysy* tysy, err_t* err)
{ {
assert(fun); assert(fun);
program_init(&fun->program); fun->program = malloc(sizeof(program_t));
program_init(fun->program);
fun->err = err; fun->err = err;
fun->sym = malloc(sizeof(sym_t)); fun->sym = malloc(sizeof(sym_t));
sym_init((sym_t*) fun->sym, (tysy_t*) tysy, err); sym_init((sym_t*) fun->sym, (tysy_t*) tysy, err);
@ -34,6 +36,10 @@ fun_t* fun_new_clone(fun_t* fun)
clone->base = fun->base; clone->base = fun->base;
clone->arg_base = fun->arg_base; clone->arg_base = fun->arg_base;
program_free(clone->program);
free(clone->program);
clone->program = program_new_clone(fun->program);
for (size_t i=0; i<fun->closure.size; i++) for (size_t i=0; i<fun->closure.size; i++)
{ {
fun_capture(clone, fun_capture(clone,
@ -47,7 +53,10 @@ fun_t* fun_new_clone(fun_t* fun)
void fun_free(fun_t* fun) void fun_free(fun_t* fun)
{ {
assert(fun); assert(fun);
program_free(&fun->program);
program_free(fun->program);
free(fun->program);
fun->program = NULL;
sym_free((sym_t*) fun->sym); sym_free((sym_t*) fun->sym);
free(fun->sym); free(fun->sym);

View File

@ -15,7 +15,7 @@ typedef struct {
} closure_entry_t; } closure_entry_t;
typedef struct { typedef struct {
program_t program; program_t* program;
err_t* err; err_t* err;
struct sym* sym; struct sym* sym;
struct tysy* tysy; struct tysy* tysy;

View File

@ -13,8 +13,8 @@ void heap_free(heap_t* heap)
{ {
for (size_t i=0; i<heap->size; i++) for (size_t i=0; i<heap->size; i++)
{ {
//value_free(heap->data[i]); value_free(heap->data[i]);
//free(heap->data[i]); free(heap->data[i]);
} }
free(heap->data); free(heap->data);

View File

@ -15,6 +15,32 @@ void program_init(program_t* program)
program->values.data = NULL; program->values.data = NULL;
} }
program_t* program_new_clone(program_t* program)
{
assert(program);
program_t* clone = malloc(sizeof(program_t));
program_init(clone);
for (size_t i=0; i<program->size; i++)
{
program_push_instr(clone,
program->ops[i],
program->params[i]);
}
for (size_t i=0; i<program->values.size; i++)
{
char m[512]; value_str(program->values.data[i], m, 512);
program_push_new_value(clone,
value_new_clone(program->values.data[i]));
}
return clone;
}
void program_free(program_t* program) void program_free(program_t* program)
{ {
assert(program); assert(program);

View File

@ -21,6 +21,7 @@ typedef struct {
} program_t; } program_t;
void program_init(program_t* program); void program_init(program_t* program);
program_t* program_new_clone(program_t* program);
void program_free(program_t* program); void program_free(program_t* program);
size_t program_push_instr(program_t* program, Opcode op, param_t param); size_t program_push_instr(program_t* program, Opcode op, param_t param);

View File

@ -18,17 +18,32 @@ value_t* value_new_clone(value_t* value)
value_t* clone = malloc(sizeof(value_t)); value_t* clone = malloc(sizeof(value_t));
value_init(clone, value->type, value->line); value_init(clone, value->type, value->line);
clone->value = value->value;
if (value->type->kind == TYPE_STR) if (value->type->kind == TYPE_STR)
{ {
clone->value.str = strdup(value->value.str); clone->value.str = strdup(value->value.str);
} }
else if (value->type->kind == TYPE_NUM)
if (value->type->kind == TYPE_FUN) {
clone->value.num = value->value.num;
}
else if (value->type->kind == TYPE_FUN)
{ {
clone->value.fun = fun_new_clone(value->value.fun); clone->value.fun = fun_new_clone(value->value.fun);
} }
else if (value->type->kind == TYPE_REF)
{
clone->value.ref = value->value.ref;
}
else if (value->type->kind == TYPE_BOOL)
{
clone->value.bool = value->value.bool;
}
else
{
fprintf(stderr, "Cannot clone value of unknown type '%s'.",
TypeKindStr[value->type->kind]);
abort();
}
return clone; return clone;
} }

View File

@ -86,7 +86,7 @@ void vm_frame_push(vm_t* vm, fun_t* fun)
if (fun != NULL) if (fun != NULL)
{ {
frame->program = &fun->program; frame->program = fun->program;
frame->locals = (locals_t*) fun->locals; frame->locals = (locals_t*) fun->locals;
} }
else else
@ -103,8 +103,6 @@ int vm_frame_pop(vm_t* vm)
if (vm->top_frame->fun) if (vm->top_frame->fun)
{ {
fun_free(vm->top_frame->fun);
free(vm->top_frame->fun);
vm->top_frame->fun = NULL; vm->top_frame->fun = NULL;
} }
@ -120,6 +118,7 @@ int vm_frame_pop(vm_t* vm)
vm_frame_free(vm->top_frame); vm_frame_free(vm->top_frame);
free(vm->top_frame); free(vm->top_frame);
vm->top_frame = NULL;
vm->top_frame = prev; vm->top_frame = prev;
@ -487,7 +486,6 @@ int vm_exec_instr(vm_t* vm, Opcode op, param_t param)
if (vm->top_frame->fun) if (vm->top_frame->fun)
{ {
fun_t* fun = vm->top_frame->fun; fun_t* fun = vm->top_frame->fun;
closure_entry_t* closure = fun_try_find_closure(fun, param); closure_entry_t* closure = fun_try_find_closure(fun, param);
@ -508,7 +506,9 @@ int vm_exec_instr(vm_t* vm, Opcode op, param_t param)
} break; } break;
case OP_MKFUN: { case OP_MKFUN: {
value_t* value = vm_pop(vm); value_t* value = value_new_clone(vm_pop(vm));
assert(value->type->kind == TYPE_FUN);
size_t addr = heap_alloc(&vm->heap, value); size_t addr = heap_alloc(&vm->heap, value);
value_t* ref = tysy_new_ref(vm->tysy, addr, value->line); value_t* ref = tysy_new_ref(vm->tysy, addr, value->line);
@ -518,7 +518,9 @@ int vm_exec_instr(vm_t* vm, Opcode op, param_t param)
locals_t* loc = &vm->locals; locals_t* loc = &vm->locals;
assert(value->type->kind == TYPE_FUN); assert(value->type->kind == TYPE_FUN);
fun_t* fun = value->value.fun; fun_t* fun = value->value.fun;
frame_t* frame = vm->top_frame;
if (vm->top_frame->fun) if (vm->top_frame->fun)
{ {
@ -527,18 +529,20 @@ int vm_exec_instr(vm_t* vm, Opcode op, param_t param)
else if (prev && prev->fun) else if (prev && prev->fun)
{ {
loc = (locals_t*) prev->fun->locals; loc = (locals_t*) prev->fun->locals;
frame = prev;
} }
else if (prev) else if (prev)
{ {
loc = prev->locals; loc = prev->locals;
frame = prev;
} }
if (loc) if (loc)
{ {
for (size_t i=0; i<loc->size; i++) for (size_t i=0; i<loc->size; i++)
{ {
int id = vm->top_frame->locals->data[i]->id; int id = frame->locals->data[i]->id;
value_t* loc_val = vm->top_frame->stack[addr]; value_t* loc_val = frame->stack[loc->data[i]->addr];
fun_capture(fun, id, loc_val); fun_capture(fun, id, loc_val);
} }
@ -571,10 +575,12 @@ int vm_exec_instr(vm_t* vm, Opcode op, param_t param)
} }
value_t* fun_val = heap_deref(&vm->heap, fun_ref->value.ref); value_t* fun_val = heap_deref(&vm->heap, fun_ref->value.ref);
assert(fun_val);
assert(fun_val->type->kind == TYPE_FUN); assert(fun_val->type->kind == TYPE_FUN);
fun_t* fun = fun_new_clone(fun_val->value.fun); assert(fun_val->value.fun);
fun_t* fun = fun_val->value.fun;
vm->top_frame->pc++; vm->top_frame->pc++;
vm_frame_push(vm, fun); vm_frame_push(vm, fun);
@ -595,6 +601,7 @@ int vm_exec_instr(vm_t* vm, Opcode op, param_t param)
vm->top_frame->sp - 1); vm->top_frame->sp - 1);
} }
} break; } break;
case OP_RET: { case OP_RET: {

View File

@ -1,14 +1,14 @@
# FUNCTIONS # FUNCTIONS
# ========= # =========
fun double(n) fun double(n)
n * 2 return n * 2
end end
assert double(4) == 8 assert double(4) == 8
assert 8 == double(4) assert 8 == double(4)
assert double(4) != 10 assert (double(4) == 10) == false
assert 9 != double(4) assert (9 == double(4)) == false
assert double(double(double(3))) == 24 assert double(double(double(3))) == 24