Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
In a token foo { <bar>+ }, the captures would not be stored. This was…
… due to a bad interaction between :r and the cstack; the bstack contains the current cstack index we're at, but we don't grow the bstack when :r is on. We thus lost the count of captures, popping the entire cstack. This adds an extra bstack frame when :r is on to keep such counts, fixing the issue.
  • Loading branch information
jnthn committed Nov 18, 2011
1 parent 7fc7a08 commit 87bb1c3
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/QAST/Compiler.nqp
Expand Up @@ -289,6 +289,7 @@ class QAST::Compiler is HLL::Compiler {
my $prefix := self.unique('rxquant' ~ $backtrack);
my $looplabel := self.post_new('Label', :result($prefix ~ '_loop'));
my $donelabel := self.post_new('Label', :result($prefix ~ '_done'));
my $rcslabel := self.post_new('Label', :result($prefix ~ '_ratchet_cstack'));
my $min := $node.min || 0;
my $max := $node.max // -1;
my $needrep := $min > 1 || $max > 1;
Expand Down Expand Up @@ -318,6 +319,8 @@ class QAST::Compiler is HLL::Compiler {
$ops.push($donelabel);
}
else {
self.regex_mark($ops, $rcslabel, -1, 0) # to track cstack as we ratchet
if $backtrack eq 'r' && $max != 1;
if $min == 0 { self.regex_mark($ops, $donelabel, %*REG<pos>, 0); }
elsif $needmark { self.regex_mark($ops, $donelabel, -1, 0); }
$ops.push($looplabel);
Expand All @@ -331,10 +334,16 @@ class QAST::Compiler is HLL::Compiler {
}
unless $max == 1 {
self.regex_mark($ops, $donelabel, %*REG<pos>, %*REG<rep>);
$ops.push_pirop('nqp_rxsetcaps', %*REG<bstack>, %*REG<cstack>)
if $backtrack eq 'r';
$ops.push(self.regex_post($sep)) if $sep;
$ops.push_pirop('goto', $looplabel);
}
$ops.push($donelabel);
if $backtrack eq 'r' && $max != 1 {
self.regex_commit($ops, $rcslabel); # pop cstack/ratchet tracking mark
$ops.push($rcslabel);
}
$ops.push_pirop('lt', %*REG<rep>, +$node.min, %*REG<fail>)
if $min > 1;
}
Expand Down
11 changes: 11 additions & 0 deletions src/ops/nqp.ops
Expand Up @@ -1678,6 +1678,11 @@ Push a new backtracking mark onto $1 with label $2, position $3, and count $4

Set $1 to be the index of latest mark frame $3 in stack $2.

=item nqp_rxsetcaps(ptr, cstack)

Sets the top cstack count in $1 to be the elements in $2, or 0 if it's null.
Used to not lose count when doing ratcheting and replacing marks.

=cut

*/
Expand Down Expand Up @@ -1705,6 +1710,12 @@ inline op nqp_rxpeek(out INT, in PMC, in LABEL) :base_core {
$1 = ptr;
}

inline op nqp_rxsetcaps(in PMC, in PMC) :base_core {
PMC *bstack = $1;
VTABLE_set_integer_keyed_int(interp, bstack,
VTABLE_elements(interp, bstack) - 5,
PMC_IS_NULL($2) ? 0 : VTABLE_elements(interp, $2));
}

/*

Expand Down

0 comments on commit 87bb1c3

Please sign in to comment.