[svn:parrot] r41561 - in branches/pct-rx/compilers/pct/src: PAST Regex
pmichaud at svn.parrot.org
pmichaud at svn.parrot.org
Tue Sep 29 20:58:50 UTC 2009
Author: pmichaud
Date: Tue Sep 29 20:58:49 2009
New Revision: 41561
URL: https://trac.parrot.org/parrot/changeset/41561
Log:
[pct-rx]: Add some Cursor methods.
Modified:
branches/pct-rx/compilers/pct/src/PAST/Compiler-Regex.pir
branches/pct-rx/compilers/pct/src/Regex/Cursor.pir
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:40:40 2009 (r41560)
+++ branches/pct-rx/compilers/pct/src/PAST/Compiler-Regex.pir Tue Sep 29 20:58:49 2009 (r41561)
@@ -61,7 +61,8 @@
$P0 = self.'post_regex'(node)
ops.'push'($P0)
ops.'push'(faillabel)
- self.'!cursorop'(ops, '!mark_cut', 3, rep, pos, '$I10')
+ self.'!cursorop'(ops, '!mark_fail', 3, rep, pos, '$I10')
+ ops.'push_pirop'('lt', pos, 0, faillabel)
ops.'push_pirop'('jump', '$I10')
.return (ops)
.end
@@ -417,7 +418,7 @@
peekcut = '!mark_peek'
if backtrack != 'r' goto greedy_1
needmark = 1
- peekcut = '!mark_cut'
+ peekcut = '!mark_commit'
greedy_1:
if min == 0 goto greedy_2
unless needmark goto greedy_loop
Modified: branches/pct-rx/compilers/pct/src/Regex/Cursor.pir
==============================================================================
--- branches/pct-rx/compilers/pct/src/Regex/Cursor.pir Tue Sep 29 15:40:40 2009 (r41560)
+++ branches/pct-rx/compilers/pct/src/Regex/Cursor.pir Tue Sep 29 20:58:49 2009 (r41561)
@@ -23,10 +23,106 @@
.return ()
.end
-=head2 Methods
+=head2 Private methods
=over 4
+=item !mark_push(rep, pos, mark)
+
+Push a new backtracking point onto the cursor with the given
+C<rep>, C<pos>, and backtracking C<mark>. (The C<mark> is typically
+the address of a label to branch to when backtracking occurs.)
+
+=cut
+
+.sub '!mark_push' :method
+ .param int rep
+ .param int pos
+ .param int mark
+
+ .local pmc bstack, mstack
+ bstack = getattribute self, '@!bstack'
+ mstack = getattribute self, '@!mstack'
+
+ push bstack, mark
+ push bstack, pos
+ push bstack, rep
+ $I0 = mstack
+ push bstack, $I0
+.end
+
+=item !mark_fail([mark])
+
+Remove the most recent C<mark> and backtrack the cursor to the
+point given by that mark. If no C<mark> is provided, then
+backtracks the most recent mark. Returns the backtracked
+values of repetition count, cursor position, and mark (address).
+
+=cut
+
+.sub '!mark_fail' :method
+ .param int mark :optional
+ .param int has_mark :opt_flag
+
+ .local pmc bstack, mstack
+ bstack = getattribute self, '@!bstack'
+ bstack = getattribute self, '@!mstack'
+
+ # get the frame associated with the mark
+ .local int bptr, rep, pos, mark, mptr
+ bptr = self.'!mark_bptr'(mark, has_mark)
+
+ # retrieve the mark, pos, rep, and match index from the frame
+ mark = bstack[bptr]
+ $I0 = bptr + 1
+ pos = bstack[$I0]
+ inc $I0
+ rep = bstack[$I0]
+ inc $I0
+ mptr = bstack[$I0]
+
+ # release the backtracked stack elements
+ assign bstack, bptr
+ assign mstack, mptr
+
+ .local pmc match
+ match = mstack[-1]
+
+ # return mark values
+ .return (rep, pos, mark, match)
+.end
+
+
+=item '!mark_commit'(mark)
+
+Like C<!mark_fail> above this backtracks the cursor to C<mark>
+(releasing any intermediate marks), but preserves the current
+match state.
+
+=cut
+
+.sub '!mark_commit' :method
+ .param int mark
+
+ # preserve the current match object
+ .local pmc mstack, match
+ mstack = getattribute self, '@!mstack'
+
+ # backtrack
+ .local int rep, pos, mark
+ (rep, pos, mark, $P0) = self.'!mark_fail'(mark)
+
+ # if match we backtracked to is the same as this one,
+ # we don't need to preserve it specially
+ $I0 = issame $P0, match
+ if $I0 goto done
+ # save current match state
+ push mstack, match
+
+ done:
+ .return (rep, pos, mark, match)
+.end
+
=back
=head1 AUTHORS
More information about the parrot-commits
mailing list