🐛 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;
|
||||
|
||||
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);
|
||||
|
|
13
lib/fun.c
13
lib/fun.c
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
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_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;
|
||||
}
|
||||
|
|
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)
|
||||
{
|
||||
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: {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue