Fix destructuring alternation
Attempting to use the existing FORK_OPT opcode resulted in difficulty knowing when to pop an error message off the stack and when not to. This commit makes DESTRUCTURE_ALT a real opcode that is identical to FORK_OPT, except for never pushing the error message onto the stack when continuing from an error backtrack. Some small changes were necessary to the DUP/POP behavior surrounding destructuring to accomodate this.
This commit is contained in:
1 parent
3dc5f4e948
commit
0673dee1b3
4 files changed
+122
-21
No files matched your search
+9
-3
@@ -799,21 +799,27 @@ jv jq_next(jq_state *jq) {
|
||||
}
|
||||
|
||||
case FORK_OPT:
|
||||
case DESTRUCTURE_ALT:
|
||||
case FORK: {
|
||||
stack_save(jq, pc - 1, stack_get_pos(jq));
|
||||
pc++; // skip offset this time
|
||||
break;
|
||||
}
|
||||
|
||||
case ON_BACKTRACK(FORK_OPT): {
|
||||
case ON_BACKTRACK(FORK_OPT):
|
||||
case ON_BACKTRACK(DESTRUCTURE_ALT): {
|
||||
if (jv_is_valid(jq->error)) {
|
||||
// `try EXP ...` backtracked here (no value, `empty`), so we backtrack more
|
||||
jv_free(stack_pop(jq));
|
||||
goto do_backtrack;
|
||||
}
|
||||
// `try EXP ...` exception caught in EXP
|
||||
jv_free(stack_pop(jq)); // free the input
|
||||
stack_push(jq, jv_invalid_get_msg(jq->error)); // push the error's message
|
||||
// DESTRUCTURE_ALT doesn't want the error message on the stack,
|
||||
// as we would just want to throw it away anyway.
|
||||
if (opcode != ON_BACKTRACK(DESTRUCTURE_ALT)) {
|
||||
jv_free(stack_pop(jq)); // free the input
|
||||
stack_push(jq, jv_invalid_get_msg(jq->error)); // push the error's message
|
||||
}
|
||||
jq->error = jv_null();
|
||||
uint16_t offset = *pc++;
|
||||
pc += offset;
|
||||
|
||||
Reference in new issue
Block a user