[svn:parrot] r41559 - in branches/pct-rx: compilers/pct/src/PAST examples/regex
pmichaud at svn.parrot.org
pmichaud at svn.parrot.org
Tue Sep 29 15:10:14 UTC 2009
Author: pmichaud
Date: Tue Sep 29 15:10:13 2009
New Revision: 41559
URL: https://trac.parrot.org/parrot/changeset/41559
Log:
[pct-rx]: Infrastructure for inlined cursor operations, reduce actions.
Added:
branches/pct-rx/examples/regex/06-reduce-past.nqp
Modified:
branches/pct-rx/compilers/pct/src/PAST/Compiler-Regex.pir
branches/pct-rx/examples/regex/01-literal-past.nqp
Modified: branches/pct-rx/compilers/pct/src/PAST/Compiler-Regex.pir
==============================================================================
--- branches/pct-rx/compilers/pct/src/PAST/Compiler-Regex.pir Tue Sep 29 15:05:22 2009 (r41558)
+++ branches/pct-rx/compilers/pct/src/PAST/Compiler-Regex.pir Tue Sep 29 15:10:13 2009 (r41559)
@@ -37,7 +37,7 @@
.local string prefix, rname, rtype
prefix = self.'unique'('rx')
concat prefix, '_'
- $P0 = split ' ', 'tgt string pos int off int len int rep int cur pmc'
+ $P0 = split ' ', 'tgt string pos int off int len int rep int cur pmc act pmc'
$P1 = iter $P0
iter_loop:
unless $P1 goto iter_done
@@ -61,15 +61,58 @@
$P0 = self.'post_regex'(node)
ops.'push'($P0)
ops.'push'(faillabel)
- $S0 = concat '(', rep
- concat $S0, ','
- concat $S0, pos
- concat $S0, ',$I10)'
- ops.'push_pirop'('callmethod', "'!mark_cut'", cur, 'result'=>$S0)
+ self.'!cursorop'(ops, '!mark_cut', 3, rep, pos, '$I10')
ops.'push_pirop'('jump', '$I10')
.return (ops)
.end
+=item !cursorop(ops, func, retelems, arg :slurpy)
+
+Helper function to push POST nodes onto C<ops> that perform C<func>
+on the regex's current cursor. By default this ends up being a method
+call on the cursor, but some values of C<func> can result in inlined
+code to perform the equivalent operation without using the method call.
+
+The C<retelems> argument is the number of elements in C<arg> that
+represent return values from the function; any remaining elements in arg
+are passed to the function as input arguments.
+
+=cut
+
+.sub '!cursorop' :method
+ .param pmc ops
+ .param string func
+ .param int retelems
+ .param pmc args :slurpy
+
+ if retelems < 1 goto result_done
+ .local pmc retargs
+ retargs = new ['ResizableStringArray']
+ $I0 = retelems
+ retargs_loop:
+ unless $I0 > 0 goto retargs_done
+ $S0 = shift args
+ push retargs, $S0
+ dec $I0
+ goto retargs_loop
+ retargs_done:
+ .local string result
+ result = join ', ', retargs
+ result = concat '(', result
+ concat result, ')'
+ result_done:
+
+ .local pmc cur
+ cur = self.'!rxregs'('cur')
+ $S0 = self.'escape'(func)
+ $P0 = ops.'push_pirop'('callmethod', $S0, cur, args :flat)
+ if retelems < 1 goto done
+ $P0.'result'(result)
+ done:
+ .return (ops)
+.end
+
+
=item !rxregs(keystr)
Helper function -- looks up the current regex register table
@@ -178,7 +221,7 @@
$S0 = concat name, $S0
alabel = self.'post_new'('Label', 'result'=>$S0)
ops.'push_pirop'('set_addr', '$I10', alabel)
- ops.'push_pirop'('callmethod', '"!mark_push"', cur, 0, pos, '$I10')
+ self.'!cursorop'(ops, '!mark_push', 0, 0, pos, '$I10')
ops.'push'(apost)
ops.'push_pirop'('goto', endlabel)
goto iter_loop
@@ -277,10 +320,41 @@
.sub 'pass' :method :multi(_,['PAST';'Regex'])
.param pmc node
- .local pmc cur, ops
- cur = self.'!rxregs'('cur')
- ops = self.'post_new'('Ops', 'result'=>cur)
- ops.'push_pirop'('yield', cur)
+ .local pmc ops
+ ops = self.'reduce'(node)
+ ops.'push_pirop'('inline', 'inline'=>' # rx pass')
+ $S0 = ops.'result'()
+ ops.'push_pirop'('yield', $S0)
+ .return (ops)
+.end
+
+
+=item reduce
+
+=cut
+
+.sub 'reduce' :method :multi(_,['PAST';'Regex'])
+ .param pmc node
+
+ .local pmc cur, act
+ (cur, act) = self.'!rxregs'('cur act')
+
+ .local pmc ops, name, redlabel
+ ops = self.'post_new'('Ops', 'node'=>node, 'result'=>cur)
+ $P0 = node.'name'()
+ unless $P0 goto done
+ name = self.'as_post'($P0, 'rtype'=>'~')
+ redlabel = self.'post_new'('Label', 'name'=>'rxreduce_')
+
+ ops.'push_pirop'('inline', name, 'inline'=>' # rx reduce %0')
+ ops.'push'(name)
+ ops.'push_pirop'('if_null', act, redlabel)
+ ops.'push_pirop'('find_method', '$P10', act, name)
+ ops.'push_pirop'('if_null', '$P10', redlabel)
+ self.'!cursorop'(ops, '!MATCH', 1, '$P11')
+ ops.'push_pirop'('callmethod', '$P10', act, '$P11')
+ ops.'push'(redlabel)
+ done:
.return (ops)
.end
@@ -312,7 +386,7 @@
.local string qname
.local pmc ops, q1label, q2label, btreg, cpost
- $S0 = concat 'quant', backtrack
+ $S0 = concat 'rxquant', backtrack
qname = self.'unique'($S0)
ops = self.'post_new'('Ops', 'node'=>node)
$S0 = concat qname, '_loop'
@@ -340,22 +414,22 @@
.local int needmark
.local string peekcut
needmark = needrep
- peekcut = '"!mark_peek"'
+ peekcut = '!mark_peek'
if backtrack != 'r' goto greedy_1
needmark = 1
- peekcut = '"!mark_cut"'
+ peekcut = '!mark_cut'
greedy_1:
if min == 0 goto greedy_2
unless needmark goto greedy_loop
- ops.'push_pirop'('callmethod', '"!mark_push"', cur, 0, -1, btreg)
+ self.'!cursorop'(ops, '!mark_push', 0, 0, -1, btreg)
goto greedy_loop
greedy_2:
- ops.'push_pirop'('callmethod', '"!mark_push"', cur, 0, pos, btreg)
+ self.'!cursorop'(ops, '!mark_push', 0, 0, pos, btreg)
greedy_loop:
ops.'push'(q1label)
ops.'push'(cpost)
unless needmark goto greedy_3
- ops.'push_pirop'('callmethod', peekcut, cur, btreg, 'result'=>rep)
+ self.'!cursorop'(ops, peekcut, 1, rep, btreg)
unless needrep goto greedy_3
ops.'push_pirop'('inc', rep)
greedy_3:
@@ -363,7 +437,7 @@
ops.'push_pirop'('ge', rep, max, q2label)
greedy_4:
unless max != 1 goto greedy_5
- ops.'push_pirop'('callmethod', '"!mark_push"', cur, rep, pos, btreg)
+ self.'!cursorop'(ops, '!mark_push', 0, rep, pos, btreg)
ops.'push_pirop'('goto', q1label)
greedy_5:
ops.'push'(q2label)
@@ -381,7 +455,7 @@
goto frugal_2
frugal_1:
ops.'push_pirop'('set_addr', '$I10', q1label)
- ops.'push_pirop'('callmethod', '"!mark_push"', cur, 0, pos, '$I10')
+ self.'!cursorop'(ops, '!mark_push', 0, 0, pos, '$I10')
ops.'push_pirop'('goto', q2label)
frugal_2:
ops.'push'(q1label)
@@ -400,7 +474,7 @@
frugal_6:
unless max != 1 goto frugal_7
ops.'push_pirop'('set_addr', '$I10', q1label)
- ops.'push_pirop'('callmethod', '"!mark_push"', cur, ireg, pos, '$I10')
+ self.'!cursorop'(ops, '!mark_push', 0, ireg, pos, '$I10')
frugal_7:
ops.'push'(q2label)
.return (ops)
Modified: branches/pct-rx/examples/regex/01-literal-past.nqp
==============================================================================
--- branches/pct-rx/examples/regex/01-literal-past.nqp Tue Sep 29 15:05:22 2009 (r41558)
+++ branches/pct-rx/examples/regex/01-literal-past.nqp Tue Sep 29 15:10:13 2009 (r41559)
@@ -1,7 +1,7 @@
# nqp
# regex { 'foo' 'bar' }
-
+say("# regex { 'foo' 'bar' }");
my $past :=
PAST::Regex.new(
PAST::Regex.new('foo', :pasttype('literal')),
Added: branches/pct-rx/examples/regex/06-reduce-past.nqp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ branches/pct-rx/examples/regex/06-reduce-past.nqp Tue Sep 29 15:10:13 2009 (r41559)
@@ -0,0 +1,14 @@
+# nqp
+
+say('# regex xyz { "foo" {*} "bar" }');
+my $past :=
+ PAST::Regex.new(
+ PAST::Regex.new('foo', :pasttype('literal')),
+ PAST::Regex.new(:pasttype('reduce'), :name('xyz')),
+ PAST::Regex.new('bar', :pasttype('literal')),
+ PAST::Regex.new(:pasttype('pass'), :name('xyz')),
+ :pasttype('concat')
+ );
+
+say(PAST::Compiler.compile($past, :target('pir')));
+
More information about the parrot-commits
mailing list