🐛 major closure issues.
parent
84f5425804
commit
85c289af2a
|
@ -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);
|
||||||
|
|
13
lib/fun.c
13
lib/fun.c
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
23
lib/value.c
23
lib/value.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
23
lib/vm.c
23
lib/vm.c
|
@ -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: {
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue