Skip to content
This repository has been archived by the owner on Feb 3, 2021. It is now read-only.

Commit

Permalink
Enable regex-based assertions.
Browse files Browse the repository at this point in the history
  • Loading branch information
pmichaud committed May 24, 2010
1 parent 52d3856 commit 1b1fe32
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 11 deletions.
9 changes: 7 additions & 2 deletions src/NQP/Actions.pm
Original file line number Diff line number Diff line change
Expand Up @@ -817,12 +817,17 @@ class NQP::RegexActions is Regex::P6Regex::Actions {
method metachar:sym<{ }>($/) { make $<codeblock>.ast; }

method metachar:sym<nqpvar>($/) {
make PAST::Regex.new( '!INTERPOLATE', $<var>.ast, :pasttype<subrule>,
:subtype<method>, :node($/) );
make PAST::Regex.new( '!INTERPOLATE', $<var>.ast,
:pasttype<subrule>, :subtype<method>, :node($/));
}

method assertion:sym<{ }>($/) { make $<codeblock>.ast; }

method assertion:sym<var>($/) {
make PAST::Regex.new( '!INTERPOLATE_REGEX', $<var>.ast,
:pasttype<subrule>, :subtype<method>, :node($/));
}

method codeblock($/) {
my $block := $<block>.ast;
$block.blocktype('immediate');
Expand Down
3 changes: 3 additions & 0 deletions src/NQP/Grammar.pm
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,9 @@ grammar NQP::Regex is Regex::P6Regex::Grammar {
]?
}

token assertion:sym<var> {
<?[$@]> <var=.LANG('MAIN', 'variable')>
}

token codeblock {
<block=.LANG('MAIN','pblock')>
Expand Down
47 changes: 45 additions & 2 deletions src/Regex/Cursor.pir
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,9 @@ and the longest match is returned.
if $I0 goto var_array

var_scalar:
$I0 = does var, ['Sub']
$I0 = isa var, ['Sub']
if $I0 goto var_sub
$I0 = isa var, ['Eval']
if $I0 goto var_sub

var_string:
Expand Down Expand Up @@ -745,7 +747,7 @@ and the longest match is returned.
array_loop:
unless var_it goto array_done
elem = shift var_it
$I0 = does elem, ['Sub']
$I0 = isa elem, ['Sub']
if $I0 goto array_sub
array_string:
$S0 = elem
Expand All @@ -771,6 +773,47 @@ and the longest match is returned.
.return (cur)
.end


=item !INTERPOLATE_REGEX(var)

Same as C<!INTERPOLATE> above, except that any non-regex values
are first compiled to regexes prior to being matched.

=cut

.sub '!INTERPOLATE_REGEX' :method
.param pmc var

$I0 = isa var, ['Sub']
if $I0 goto done

.local pmc p6regex
p6regex = compreg 'Regex::P6Regex'

$I0 = does var, 'array'
if $I0 goto var_array
var = p6regex.'compile'(var)
goto done

var_array:
.local pmc var_it, elem
var_it = iter var
var = new ['ResizablePMCArray']
var_loop:
unless var_it goto done
elem = shift var_it
$I0 = isa elem, ['Sub']
if $I0 goto var_next
elem = p6regex.'compile'(elem)
var_next:
push var, elem
goto var_loop

done:
.tailcall self.'!INTERPOLATE'(var)
.end


=back

=head2 Vtable functions
Expand Down
14 changes: 7 additions & 7 deletions t/nqp/49-regex-interpolation.t
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@ ok("ac+d" ~~ /a @foo d/, 'plain array interpolates as alternations of litera
ok(!("abbbbbd" ~~ /a @foo d/), 'plain array interpolates as alternations of literals 3');
ok(!("acccccd" ~~ /a @foo d/), 'plain array interpolates as alternations of literals 4');

@foo := [ "b", "bb", "bbc", "bc" ];
my @ltm := [ "b", "bb", "bbc", "bc" ];

ok(("abd" ~~ / @foo /) eq 'b', 'array finds longest match 1');
ok(("abbd" ~~ / @foo /) eq 'bb', 'array finds longest match 2');
ok(("abbcd" ~~ / @foo /) eq 'bbc', 'array finds longest match 3');
ok(("abccd" ~~ / @foo /) eq 'bc', 'array finds longest match 4');
ok(("abd" ~~ / @ltm /) eq 'b', 'array finds longest match 1');
ok(("abbd" ~~ / @ltm /) eq 'bb', 'array finds longest match 2');
ok(("abbcd" ~~ / @ltm /) eq 'bbc', 'array finds longest match 3');
ok(("abccd" ~~ / @ltm /) eq 'bc', 'array finds longest match 4');

ok(!("ab+d" ~~ /a <$b> d/), 'scalar assertion interpolates as regex 1');
ok("abbbbbd" ~~ /a <$b> d/, 'scalar assertion interpolates as regex 2');

=begin END
ok(!("ab+d" ~~ /a <$b> d/), 'scalar assertion interpolates as regex 1');
ok("abbbbbd" ~~ /a <$b> d/, 'scalar assertion interpolates as regex 2');
ok(!("ab+d" ~~ /a <@foo> d/), 'array assertion interpolates as alternations of regexen 1');
ok(!("ac+d" ~~ /a <@foo> d/), 'array assertion interpolates as alternations of regexen 2');
ok("abbbbbd" ~~ /a <@foo> d/, 'array assertion interpolates as alternations of regexen 3');
Expand Down

0 comments on commit 1b1fe32

Please sign in to comment.