summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-02-23 19:28:34 -0800
committerKaz Kylheku <kaz@kylheku.com>2017-02-23 19:28:34 -0800
commit77491d210b391d82cbf1a9b623092fb3caadba90 (patch)
tree07767da97e7d482dbf128d82c09b7cef500e582d /eval.c
parent93131fc82a2d16e68c03d143ff473d73c040bea8 (diff)
downloadtxr-77491d210b391d82cbf1a9b623092fb3caadba90.tar.gz
txr-77491d210b391d82cbf1a9b623092fb3caadba90.tar.bz2
txr-77491d210b391d82cbf1a9b623092fb3caadba90.zip
bugfix: integrate finally clause with accept.
The test case for this issue is: @(next :list '#"the quick brown fox jumped") @(block b) @(try) @the @(accept b) @(finally) @quick @(end) @(end) Inside the try-protected clause, we bind the variable the to the string "the". Then we initiate an accept whose exit point is the block b. There are two problems: the finally clause executes against the input stream beginning with "the", even though "the" was consumed in the protected block. Secondly, the binding captures by finally is thrown away; the accept control transfer continues and only one variable emerges from the block: the variable the. In this patch we obtain a different behavior. The processing of the finally clause detects that an accept transfer is passing through. The clause is executed against the input stream that is being communicated by the accept, in this case the stream which beings with the second line "quick", so the quick variable gets bound to this string. Secondly, the bindings being communicated by the accept are hijacked and replaced with the new environment captured by the finally clause. Thus, in this case, the quick variable emerges out of the block. Lastly, if the finally block fails to match, the accept transfer is converted to a @(fail) transfer and continues to the block. * match.c (v_take_accept): New static function. (v_block); Use v_take_accept function to update the match_files_ctx state from a caught accept. That is to say, the code to do this moves into that function, and is just called. This way we can share that logic with the finally processing in v_try. (v_try): Detect an accept transfer by checking the exit point. If one is going on, then accept the input and bindings into the current context and process the clause in that context. Afterward, update the accept result object with the new position and bindings or convert to a failure.
Diffstat (limited to 'eval.c')
0 files changed, 0 insertions, 0 deletions