Skip to content

Commit a54139b

Browse files
committed
Fix backref semantics with multiple captures.
We now look at the most recent contiguous sequence of captures, and the backref is the string from $first.from ..^ $last.to.
1 parent d181c8b commit a54139b

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

src/QRegex/Cursor.nqp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -489,15 +489,29 @@ role NQPCursorRole is export {
489489
method !BACKREF($name) {
490490
my $cur := self."!cursor_start_cur"();
491491
my int $n := $!cstack ?? nqp::elems($!cstack) - 1 !! -1;
492-
$n-- while $n >= 0 && (nqp::isnull(nqp::getattr($!cstack[$n], $?CLASS, '$!name')) ||
493-
nqp::getattr($!cstack[$n], $?CLASS, '$!name') ne $name);
494-
if $n >= 0 {
495-
my $subcur := $!cstack[$n];
496-
my int $litlen := $subcur.pos - $subcur.from;
492+
my $last;
493+
my $first;
494+
while $n >= 0 {
495+
my $cs_cur := $!cstack[$n];
496+
my $cs_name := nqp::getattr($cs_cur, $?CLASS, '$!name');
497+
if !nqp::isnull($cs_name) && $cs_name eq $name {
498+
if nqp::isconcrete($last) {
499+
last unless $cs_cur.pos == $first.from;
500+
}
501+
else {
502+
$last := $cs_cur;
503+
}
504+
$first := $cs_cur;
505+
}
506+
$n--;
507+
}
508+
if nqp::isconcrete($last) {
509+
my int $from := $first.from;
510+
my int $litlen := $last.pos - $from;
497511
my str $target := nqp::getattr_s($!shared, ParseShared, '$!target');
498512
$cur."!cursor_pass"($!pos + $litlen, '')
499513
if nqp::substr($target, $!pos, $litlen)
500-
eq nqp::substr($target, $subcur.from, $litlen);
514+
eq nqp::substr($target, $from, $litlen);
501515
}
502516
$cur;
503517
}

0 commit comments

Comments
 (0)