Author: pmichaud
Date: Sat Dec 13 22:12:47 2008
New Revision: 33874
Modified:
trunk/compilers/pge/PGE/Exp.pir
trunk/compilers/pge/PGE/Perl6Regex.pir
Log:
[pge]: Add <?{{...}}> and <!{{...}}> code assertions (PIR).
Modified: trunk/compilers/pge/PGE/Exp.pir
==============================================================================
--- trunk/compilers/pge/PGE/Exp.pir (original)
+++ trunk/compilers/pge/PGE/Exp.pir Sat Dec 13 22:12:47 2008
@@ -1432,19 +1432,23 @@
## two different compilers. Also, if the sources can be lengthy
## we might be well served to use a hashed representation of
## the source.
- code.'emit'(<<" CODE", label, next, lang, value)
+ code.'emit'(<<" CODE", label, lang, value)
%0: # closure
- $S1 = %3
+ $S1 = %2
$P0 = get_hll_global ['PGE';'Match'], '%!cache'
$P1 = $P0[$S1]
unless null $P1 goto %0_1
- $P1 = compreg %2
+ $P1 = compreg %1
$P1 = $P1($S1)
$P0[$S1] = $P1
%0_1:
+ CODE
+ $I0 = self['iszerowidth']
+ if $I0 goto closure_zerowidth
+ code.'emit'(<<" CODE", next)
mpos = pos
($P0 :optional, $I0 :opt_flag) = $P1(mob)
- if $I0 == 0 goto %1
+ if $I0 == 0 goto %0
mob.'result_object'($P0)
push ustack, pos
local_branch cstack, succeed
@@ -1454,6 +1458,21 @@
goto fail
CODE
.return ()
+ closure_zerowidth:
+ ## we're doing a <?{{ or <!{{ assertion.
+ .local string test
+ test = 'if'
+ $I0 = self['isnegated']
+ unless $I0 goto have_test
+ test = 'unless'
+ have_test:
+ code.'emit'(<<" CODE", test, next)
+ mpos = pos
+ $P0 = $P1(mob)
+ %0 $P0 goto %1
+ goto fail
+ CODE
+ .return ()
.end
.namespace [ 'PGE';'Exp';'Action' ]
Modified: trunk/compilers/pge/PGE/Perl6Regex.pir
==============================================================================
--- trunk/compilers/pge/PGE/Perl6Regex.pir (original)
+++ trunk/compilers/pge/PGE/Perl6Regex.pir Sat Dec 13 22:12:47 2008
@@ -218,7 +218,9 @@
optable.'newtok'('term:<commit>', 'equiv'=>'term:', 'nows'=>1,
'match'=>'PGE::Exp::Cut')
$P0 = get_global 'parse_closure'
- optable.'newtok'("term:{{", 'equiv'=>'term:', 'nows'=>1,
'parsed'=>$P0)
+ optable.'newtok'("term:{{", 'equiv'=>'term:', 'nows'=>1, 'parsed'=>$P0)
+ optable.'newtok'("term:<?{{", 'equiv'=>'term:', 'nows'=>1, 'parsed'=>$P0)
+ optable.'newtok'("term:<!{{", 'equiv'=>'term:', 'nows'=>1, 'parsed'=>$P0)
$P0 = get_global 'parse_action'
optable.'newtok'("term:{*}", 'equiv'=>'term:', 'nows'=>1,
'parsed'=>$P0)
@@ -1078,6 +1080,8 @@
.sub 'parse_closure'
.param pmc mob
+ .local pmc key
+ key = mob['KEY']
.local string target
.local int pos, len
(mob, pos, target) = mob.'new'(mob, 'grammar'=>'PGE::Exp::Closure')
@@ -1089,8 +1093,19 @@
inc pos
goto init
body:
- $S0 = repeat "}", len
- $I0 = index target, $S0, pos
+ .local string close
+ close = repeat "}", len
+ if key == '<?{{' goto assert_pos
+ if key == '<!{{' goto assert_neg
+ goto have_close
+ assert_neg:
+ mob['isnegated'] = 1
+ assert_pos:
+ mob['iszerowidth'] = 1
+ concat close, '>'
+ inc len
+ have_close:
+ $I0 = index target, close, pos
if $I0 < pos goto err_noclose
$I1 = $I0 - pos
$S1 = substr target, pos, $I1