summaryrefslogtreecommitdiffstats
path: root/match.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-02-16 19:51:44 -0800
committerKaz Kylheku <kaz@kylheku.com>2017-02-16 19:51:44 -0800
commit1251a804e742ddb4963af5d48213d20358ee639a (patch)
treea7af754cddeceb091e80de1385710c8deef0cdef /match.c
parentfca282dfac0b6e27c67afab2fcd8cc67a31d6c17 (diff)
downloadtxr-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.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/match.c b/match.c
index 4c7594a5..b8e1f1b4 100644
--- a/match.c
+++ b/match.c
@@ -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)