Remove the YIELD opcode (use RET instead)
This commit is contained in:
1 parent
e83e51eb56
commit
1e2851cdb3
3 files changed
+22
-18
No files matched your search
@@ -507,13 +507,7 @@ static int compile(struct locfile* locations, struct bytecode* bc, block b) {
|
|||||||
int var_frame_idx = 0;
|
int var_frame_idx = 0;
|
||||||
bc->nsubfunctions = 0;
|
bc->nsubfunctions = 0;
|
||||||
errors += expand_call_arglist(locations, &b);
|
errors += expand_call_arglist(locations, &b);
|
||||||
if (bc->parent) {
|
b = BLOCK(b, gen_op_simple(RET));
|
||||||
// functions should end in a return
|
|
||||||
b = BLOCK(b, gen_op_simple(RET));
|
|
||||||
} else {
|
|
||||||
// the toplevel should YIELD;BACKTRACK; when it finds an answer
|
|
||||||
b = BLOCK(b, gen_op_simple(YIELD), gen_op_simple(BACKTRACK));
|
|
||||||
}
|
|
||||||
for (inst* curr = b.first; curr; curr = curr->next) {
|
for (inst* curr = b.first; curr; curr = curr->next) {
|
||||||
if (!curr->next) assert(curr == b.last);
|
if (!curr->next) assert(curr == b.last);
|
||||||
int length = opcode_describe(curr->op)->length;
|
int length = opcode_describe(curr->op)->length;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ struct jq_state {
|
|||||||
jv path;
|
jv path;
|
||||||
int subexp_nest;
|
int subexp_nest;
|
||||||
int debug_trace_enabled;
|
int debug_trace_enabled;
|
||||||
|
int initial_execution;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -149,7 +150,8 @@ jv jq_next(jq_state *jq) {
|
|||||||
uint16_t* pc = stack_restore(jq);
|
uint16_t* pc = stack_restore(jq);
|
||||||
assert(pc);
|
assert(pc);
|
||||||
|
|
||||||
int backtracking = 0;
|
int backtracking = !jq->initial_execution;
|
||||||
|
jq->initial_execution = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
uint16_t opcode = *pc;
|
uint16_t opcode = *pc;
|
||||||
|
|
||||||
@@ -465,13 +467,6 @@ jv jq_next(jq_state *jq) {
|
|||||||
pc += offset;
|
pc += offset;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case YIELD: {
|
|
||||||
jv value = stack_pop(jq);
|
|
||||||
stack_save(jq, pc);
|
|
||||||
stack_switch(jq);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CALL_BUILTIN: {
|
case CALL_BUILTIN: {
|
||||||
int nargs = *pc++;
|
int nargs = *pc++;
|
||||||
@@ -510,10 +505,25 @@ jv jq_next(jq_state *jq) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case RET: {
|
case RET: {
|
||||||
pc = *frame_current_retaddr(&jq->frame_stk);
|
uint16_t* retaddr = *frame_current_retaddr(&jq->frame_stk);
|
||||||
frame_pop(&jq->frame_stk);
|
if (retaddr) {
|
||||||
|
// function return
|
||||||
|
pc = retaddr;
|
||||||
|
frame_pop(&jq->frame_stk);
|
||||||
|
} else {
|
||||||
|
// top-level return, yielding value
|
||||||
|
jv value = stack_pop(jq);
|
||||||
|
stack_save(jq, pc - 1);
|
||||||
|
stack_push(jq, jv_null());
|
||||||
|
stack_switch(jq);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ON_BACKTRACK(RET): {
|
||||||
|
// resumed after top-level return
|
||||||
|
goto do_backtrack;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -538,6 +548,7 @@ void jq_init(struct bytecode* bc, jv input, jq_state **jq, int flags) {
|
|||||||
} else {
|
} else {
|
||||||
new_jq->debug_trace_enabled = 0;
|
new_jq->debug_trace_enabled = 0;
|
||||||
}
|
}
|
||||||
|
new_jq->initial_execution = 1;
|
||||||
*jq = new_jq;
|
*jq = new_jq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ OP(POP, NONE, 1, 0)
|
|||||||
OP(LOADV, VARIABLE, 1, 1)
|
OP(LOADV, VARIABLE, 1, 1)
|
||||||
OP(STOREV, VARIABLE, 1, 0)
|
OP(STOREV, VARIABLE, 1, 0)
|
||||||
OP(INDEX, NONE, 2, 1)
|
OP(INDEX, NONE, 2, 1)
|
||||||
OP(YIELD, NONE, 1, 0)
|
|
||||||
OP(EACH, NONE, 1, 1)
|
OP(EACH, NONE, 1, 1)
|
||||||
OP(FORK, BRANCH, 0, 0)
|
OP(FORK, BRANCH, 0, 0)
|
||||||
OP(JUMP, BRANCH, 0, 0)
|
OP(JUMP, BRANCH, 0, 0)
|
||||||
|
|||||||
Reference in new issue
Block a user