diff options
author | William Langford <wlangfor@gmail.com> | 2018-08-17 22:47:13 -0400 |
---|---|---|
committer | William Langford <wlangfor@gmail.com> | 2018-08-17 23:15:48 -0400 |
commit | 0673dee1b38db5d49ae3f8cda0ba53fa4021c3ba (patch) | |
tree | 4b6f2dedc4115a3dcec65778d5faad42236fa459 /src/execute.c | |
parent | 3dc5f4e948b1114c37a9afd3060dacf099892689 (diff) |
Fix destructuring alternationfix-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.
Diffstat (limited to 'src/execute.c')
-rw-r--r-- | src/execute.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/src/execute.c b/src/execute.c index d5672165..8eb41cc7 100644 --- a/src/execute.c +++ b/src/execute.c @@ -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; |