diff --git a/c/compile.c b/c/compile.c index f9f738d8..dc90aed3 100644 --- a/c/compile.c +++ b/c/compile.c @@ -418,7 +418,10 @@ static void compile(struct bytecode* bc, block b) { default: assert(0 && "Unknown type of argument"); case CLOSURE_CREATE: code[pos++] = curr->bound_by->imm.intval | ARG_NEWCLOSURE; - if (i == 0) desired_params = bc->subfunctions[curr->bound_by->imm.intval]->nclosures; + if (i == 0) { + inst* i = curr->bound_by; + desired_params = i->compiled->subfunctions[i->imm.intval]->nclosures; + } break; case CLOSURE_PARAM: code[pos++] = curr->bound_by->imm.intval; diff --git a/c/execute.c b/c/execute.c index 75aaec09..9aa85b29 100644 --- a/c/execute.c +++ b/c/execute.c @@ -104,9 +104,10 @@ static struct closure make_closure(struct forkable_stack* stk, frame_ptr fr, uin if (idx & ARG_NEWCLOSURE) { int subfn_idx = idx & ~ARG_NEWCLOSURE; assert(subfn_idx < frame_self(fr)->bc->nsubfunctions); - return closure_new(stk, frame_self(fr)->bc->subfunctions[subfn_idx]); + struct closure cl = {frame_self(fr)->bc->subfunctions[subfn_idx], + forkable_stack_to_idx(stk, fr)}; + return cl; } else { - // FIXME: set pc return *frame_closure_arg(fr, idx); } } @@ -214,6 +215,9 @@ json_t* jq_next() { uint16_t v = *pc++; frame_ptr fp = frame_get_level(&frame_stk, frame_current(&frame_stk), level); json_t** var = frame_local_var(fp, v); + printf("V%d = ", v); + json_dumpf(*var, stdout, JSON_ENCODE_ANY); + printf("\n"); stack_push(stackval_replace(stack_pop(), *var)); break; } @@ -411,7 +415,8 @@ void jq_init(struct bytecode* bc, json_t* input) { forkable_stack_init(&fork_stk, 10240); // FIXME: lower this number, see if it breaks stack_push(stackval_root(input)); - frame_push(&frame_stk, closure_new_toplevel(bc), 0); + struct closure top = {bc, -1}; + frame_push(&frame_stk, top, 0); frame_push_backtrack(&frame_stk, bc->code); } diff --git a/c/frame_layout.h b/c/frame_layout.h index b2e590eb..fcbd1dc3 100644 --- a/c/frame_layout.h +++ b/c/frame_layout.h @@ -79,17 +79,6 @@ static frame_ptr frame_get_level(struct forkable_stack* stk, frame_ptr fr, int l return fr; } -static struct closure closure_new_toplevel(struct bytecode* bc) { - struct closure cl = {bc, -1}; - return cl; -} - -static struct closure closure_new(struct forkable_stack* stk, struct bytecode* bc) { - struct closure cl = {bc, - forkable_stack_to_idx(stk, frame_current(stk))}; - return cl; -} - static frame_ptr frame_push(struct forkable_stack* stk, struct closure cl, uint16_t* retaddr) { frame_ptr fp = forkable_stack_push(stk, frame_size(cl.bc)); struct continuation* cc = frame_self(fp); diff --git a/c/testdata b/c/testdata index 6e40b9ae..95e40781 100644 --- a/c/testdata +++ b/c/testdata @@ -143,6 +143,8 @@ def f: (1000,2000); f 1000 2000 +# test backtracking through function calls and returns +# this test is *evil* [[20,10][1,0] as $x | def f: (100,200) as $y | def g: [$x + $y, .]; . + $x | g; f[0] | [f][0][1] | f] "woo, testing!" [[110.0, 130.0], [210.0, 130.0], [110.0, 230.0], [210.0, 230.0], [120.0, 160.0], [220.0, 160.0], [120.0, 260.0], [220.0, 260.0]] @@ -154,3 +156,7 @@ def f(x): x | x; f([.], . + [42]) [[1,2,3,42]] [1,2,3,42,42] +# test closures and lexical scoping +def id(x):x; 2000 as $x | def f(x):1 as $x | id([$x, x, x]); def g(x): 100 as $x | f($x,$x+x); g($x) +"more testing" +[1,100,2100.0,100,2100.0]