summaryrefslogtreecommitdiffstats
path: root/src/execute.c
diff options
context:
space:
mode:
authorWilliam Langford <wlangfor@gmail.com>2018-08-17 22:47:13 -0400
committerWilliam Langford <wlangfor@gmail.com>2018-08-17 23:15:48 -0400
commit0673dee1b38db5d49ae3f8cda0ba53fa4021c3ba (patch)
tree4b6f2dedc4115a3dcec65778d5faad42236fa459 /src/execute.c
parent3dc5f4e948b1114c37a9afd3060dacf099892689 (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.c12
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;