Skip to content

Commit a9b250f

Browse files
committed
Initial implementation of <after ...>. Flips the target string and the AST (though probably missing some cases in the latter) then just parses as per normal - but backwards.
1 parent 879321b commit a9b250f

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

src/QRegex/Cursor.nqp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,19 @@ role NQPCursorRole {
206206
$cur;
207207
}
208208

209+
# Expects to get a regex whose syntax tree was flipped during the
210+
# compile.
211+
method after($regex) {
212+
my $cur := self."!cursor_start"();
213+
nqp::bindattr_s($cur, $?CLASS, '$!target', $!target.reverse());
214+
nqp::bindattr_i($cur, $?CLASS, '$!from', nqp::chars($!target) - $!pos);
215+
nqp::bindattr_i($cur, $?CLASS, '$!pos', nqp::chars($!target) - $!pos);
216+
nqp::getattr_i($regex($cur), $?CLASS, '$!pos') >= 0 ??
217+
$cur."!cursor_pass"($!pos, 'after') !!
218+
$cur."!cursor_fail"();
219+
$cur;
220+
}
221+
209222
method ws() {
210223
# skip over any whitespace, fail if between two word chars
211224
my $cur := self."!cursor_start"();

src/QRegex/P6Regex/Actions.nqp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,9 @@ class QRegex::P6Regex::Actions is HLL::Actions {
358358
for $<arglist>[0].ast.list { $qast[0].push( $_ ) }
359359
}
360360
elsif $<nibbler> {
361-
$qast[0].push(buildsub($<nibbler>[0].ast, :anon(1)));
361+
$name eq 'after' ??
362+
$qast[0].push(buildsub(self.flip_ast($<nibbler>[0].ast), :anon(1))) !!
363+
$qast[0].push(buildsub($<nibbler>[0].ast, :anon(1)));
362364
}
363365
}
364366
make $qast;
@@ -516,6 +518,21 @@ class QRegex::P6Regex::Actions is HLL::Actions {
516518
$ast.subtype('capture');
517519
}
518520

521+
method flip_ast($qast) {
522+
if $qast.rxtype eq 'literal' {
523+
$qast[0] := $qast[0].reverse();
524+
}
525+
elsif $qast.rxtype eq 'concat' {
526+
my @tmp;
527+
while +@($qast) { @tmp.push(@($qast).shift) }
528+
while @tmp { @($qast).push(self.flip_ast(@tmp.pop)) }
529+
}
530+
elsif $qast.rxtype eq 'pastnode' {
531+
# Don't go exploring these
532+
}
533+
else {
534+
for @($qast) { self.flip_ast($_) }
535+
}
536+
$qast
537+
}
519538
}
520-
521-

0 commit comments

Comments
 (0)