diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-02-16 19:51:44 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-02-16 19:51:44 -0800 |
commit | 1251a804e742ddb4963af5d48213d20358ee639a (patch) | |
tree | a7af754cddeceb091e80de1385710c8deef0cdef /match.c | |
parent | fca282dfac0b6e27c67afab2fcd8cc67a31d6c17 (diff) | |
download | txr-1251a804e742ddb4963af5d48213d20358ee639a.tar.gz txr-1251a804e742ddb4963af5d48213d20358ee639a.tar.bz2 txr-1251a804e742ddb4963af5d48213d20358ee639a.zip |
Bugfix: h_trailer has to intercept accept.
* match.c (h_trailer): Add the unwind handling for intercepting
the block return driven by @(accept) and fixing up the position, so the
semantics of trailer isn't violated, similarly to how it is done in
v_trailer.
Diffstat (limited to 'match.c')
-rw-r--r-- | match.c | 34 |
1 files changed, 26 insertions, 8 deletions
@@ -1201,17 +1201,35 @@ static val h_parallel(match_line_ctx *c) static val h_trailer(match_line_ctx *c) { - val result = match_line(ml_specline(*c, rest(c->specline))); - cons_bind (new_bindings, new_pos, result); - val elem = first(c->specline); + val ret = nil; - if (!new_pos) { - LOG_MISMATCH("trailer"); - return nil; + uw_simple_catch_begin; + + { + val result = match_line(ml_specline(*c, rest(c->specline))); + cons_bind (new_bindings, new_pos, result); + val elem = first(c->specline); + + if (!new_pos) { + LOG_MISMATCH("trailer"); + ret = nil; + } + + LOG_MATCH("trailer", new_pos); + ret = cons(new_bindings, plus(c->pos, c->base)); + } + + uw_unwind { + uw_frame_t *ex = uw_current_exit_point(); + if (ex && ex->uw.type == UW_BLOCK && ex->bl.protocol == accept_s) { + set(vecref_l(ex->bl.result, one), cons(c->data, c->data_lineno)); + set(vecref_l(ex->bl.result, two), plus(c->pos, c->base)); + } } - LOG_MATCH("trailer", new_pos); - return cons(new_bindings, plus(c->pos, c->base)); + uw_catch_end; + + return ret; } static val h_fun(match_line_ctx *c) |