Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
allow code block in ** quantifiers, / foo ** { $three..$seven } /
The code block in a quantifier can either provide a range object that
is used for min and maximum quantity, or it provides a single numeric
item that is used to match exactly that many times.
  • Loading branch information
FROGGS committed Jul 25, 2014
1 parent 189d1ce commit b772b66
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 2 deletions.
32 changes: 31 additions & 1 deletion src/Perl6/Actions.nqp
Expand Up @@ -7277,7 +7277,37 @@ class Perl6::RegexActions is QRegex::P6Regex::Actions does STDActions {
:rxtype<subrule>, :subtype<method>, :node($/));
}
}


method quantifier:sym<**>($/) {
my $qast;
if $<codeblock> {
$qast := QAST::Regex.new( :rxtype<dynquant>, :node($/),
QAST::Op.new( :op('callmethod'), :name('DYNQUANT_LIMITS'),
QAST::Var.new( :name(''), :scope('lexical') ),
$<codeblock>.ast
),
);
}
else {
my $min := $<min>.ast;
my $max := -1;
if ! $<max> { $max := $min }
elsif $<max> ne '*' {
$max := $<max>.ast;
$/.CURSOR.panic("Empty range") if $min > $max;
}
$qast := QAST::Regex.new( :rxtype<quant>, :min($min), :max($max), :node($/) );
}
make backmod($qast, $<backmod>);
}

sub backmod($ast, $backmod) {
if $backmod eq ':' { $ast.backtrack('r') }
elsif $backmod eq ':?' || $backmod eq '?' { $ast.backtrack('f') }
elsif $backmod eq ':!' || $backmod eq '!' { $ast.backtrack('g') }
$ast;
}

method metachar:sym<rakvar>($/) {
make QAST::Regex.new( QAST::Node.new(
QAST::SVal.new( :value('INTERPOLATE') ),
Expand Down
14 changes: 13 additions & 1 deletion src/core/Cursor.pm
Expand Up @@ -161,7 +161,19 @@ my class Cursor does NQPCursorRole {
self."!cursor_start_cur"()
}
}


method DYNQUANT_LIMITS($mm) {
if $mm ~~ Range {
die 'Range minimum in quantifier (**) cannot be +Inf' if $mm.min == Inf;
die 'Range maximum in quantifier (**) cannot be -Inf' if $mm.max == -Inf;
nqp::list_i($mm.min < 0 ?? 0 !! $mm.min, $mm.max == Inf ?? -1 !! $mm.max)
}
else {
fail 'Fixed quantifier cannot be infinite' if $mm == -Inf || $mm == Inf;
nqp::list_i($mm, $mm)
}
}

method OTHERGRAMMAR($grammar, $name, |) {
my $lang_cursor := $grammar.'!cursor_init'(self.target(), :p(self.pos()));
$lang_cursor."$name"();
Expand Down

0 comments on commit b772b66

Please sign in to comment.