🐛 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;
compiler_run(&comp, (node_t*) node->children.data[1], &fun->program);
compiler_run(&comp, (node_t*) node->children.data[2], &fun->program);
program_push_instr(&fun->program, OP_RET, RZ_NO_PARAM);
compiler_run(&comp, (node_t*) node->children.data[1], fun->program);
compiler_run(&comp, (node_t*) node->children.data[2], fun->program);
program_push_instr(fun->program, OP_RET, RZ_NO_PARAM);
prepass_free(&pre);
tysolver_free(&tysolver);

View File

@ -6,7 +6,9 @@
void fun_init(fun_t* fun, struct tysy* tysy, err_t* err)
{
assert(fun);
program_init(&fun->program);
fun->program = malloc(sizeof(program_t));
program_init(fun->program);
fun->err = err;
fun->sym = malloc(sizeof(sym_t));
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->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++)
{
fun_capture(clone,
@ -47,7 +53,10 @@ fun_t* fun_new_clone(fun_t* fun)
void fun_free(fun_t* fun)
{
assert(fun);
program_free(&fun->program);
program_free(fun->program);
free(fun->program);
fun->program = NULL;
sym_free((sym_t*) fun->sym);
free(fun->sym);

View File

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

View File

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

View File

@ -15,6 +15,32 @@ void program_init(program_t* program)
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)
{
assert(program);

View File

@ -21,6 +21,7 @@ typedef struct {
} program_t;
void program_init(program_t* program);
program_t* program_new_clone(program_t* program);
void program_free(program_t* program);
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_init(clone, value->type, value->line);
clone->value = value->value;
if (value->type->kind == TYPE_STR)
{
clone->value.str = strdup(value->value.str);
}
if (value->type->kind == TYPE_FUN)
else if (value->type->kind == TYPE_NUM)
{
clone->value.num = value->value.num;
}
else if (value->type->kind == TYPE_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;
}

View File

@ -86,7 +86,7 @@ void vm_frame_push(vm_t* vm, fun_t* fun)
if (fun != NULL)
{
frame->program = &fun->program;
frame->program = fun->program;
frame->locals = (locals_t*) fun->locals;
}
else
@ -103,8 +103,6 @@ int vm_frame_pop(vm_t* vm)
if (vm->top_frame->fun)
{
fun_free(vm->top_frame->fun);
free(vm->top_frame->fun);
vm->top_frame->fun = NULL;
}
@ -120,6 +118,7 @@ int vm_frame_pop(vm_t* vm)
vm_frame_free(vm->top_frame);
free(vm->top_frame);
vm->top_frame = NULL;
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)
{
fun_t* fun = vm->top_frame->fun;
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;
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);
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;
assert(value->type->kind == TYPE_FUN);
fun_t* fun = value->value.fun;
frame_t* frame = vm->top_frame;
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)
{
loc = (locals_t*) prev->fun->locals;
frame = prev;
}
else if (prev)
{
loc = prev->locals;
frame = prev;
}
if (loc)
{
for (size_t i=0; i<loc->size; i++)
{
int id = vm->top_frame->locals->data[i]->id;
value_t* loc_val = vm->top_frame->stack[addr];
int id = frame->locals->data[i]->id;
value_t* loc_val = frame->stack[loc->data[i]->addr];
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);
assert(fun_val);
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_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);
}
} break;
case OP_RET: {

View File

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