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

Commit

Permalink
Allow PAST::Regex subrule nodes to have arguments to pass to the subr…
Browse files Browse the repository at this point in the history
…ule.

Implement simple backreferences.
  • Loading branch information
pmichaud committed Oct 13, 2009
1 parent 4481429 commit 568cc9b
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 6 deletions.
12 changes: 6 additions & 6 deletions src/PAST/Compiler-Regex.pir
Expand Up @@ -810,9 +810,9 @@ Perform a subrule call.
name = self.'as_post'($P0, 'rtype'=>'*')
ops.'push'(name)

.local pmc subpast, subpost
subpast = node[0]
subpost = self.'as_post'(subpast, 'rtype'=>'*')
.local pmc cpost, posargs, namedargs, subpost
(cpost, posargs, namedargs) = self.'post_children'(node, 'signature'=>'v:')
subpost = shift posargs

.local pmc negate
.local string testop
Expand All @@ -822,11 +822,11 @@ Perform a subrule call.
.local pmc subtype
subtype = node.'subtype'()

ops.'push_pirop'('inline', name, subtype, negate, 'inline'=>" # rx subrule %0 subtype=%1 negate=%2")
ops.'push_pirop'('inline', subpost, subtype, negate, 'inline'=>" # rx subrule %0 subtype=%1 negate=%2")

self.'!cursorop'(ops, '!cursor_pos', 0, pos)
ops.'push'(subpost)
ops.'push_pirop'('callmethod', subpost, cur, 'result'=>'$P10')
ops.'push'(cpost)
ops.'push_pirop'('callmethod', subpost, cur, posargs :flat, namedargs :flat, 'result'=>'$P10')
ops.'push_pirop'(testop, '$P10', fail)
if subtype == 'zerowidth' goto done
ops.'push_pirop'('callmethod', '"pos"', '$P10', 'result'=>pos)
Expand Down
47 changes: 47 additions & 0 deletions src/Regex/Cursor.pir
Expand Up @@ -721,6 +721,53 @@ Perform any action associated with the current regex match.
.end


=item !BACKREF(name)

Match the backreference given by C<name>.

=cut

.sub '!BACKREF' :method
.param string name
.local pmc cur
.local int pos, eos
.local string tgt
(cur, pos, tgt) = self.'!cursor_start'()

# search the cursor cstack for the latest occurrence of C<name>
.local pmc cstack
cstack = getattribute self, '@!cstack'
if null cstack goto pass
.local int cstack_it
cstack_it = elements cstack
cstack_loop:
dec cstack_it
unless cstack_it >= 0 goto pass
.local pmc subcur
subcur = cstack[cstack_it]
$P0 = getattribute subcur, '$!names'
if null $P0 goto cstack_loop
$S0 = $P0
if name != $S0 goto cstack_loop
# we found a matching subcursor, get the literal it matched
cstack_done:
.local int litlen
.local string litstr
$I1 = subcur.'pos'()
$I0 = subcur.'from'()
litlen = $I1 - $I0
litstr = substr tgt, $I0, litlen
# now test the literal against our target
$S0 = substr tgt, pos, litlen
unless $S0 == litstr goto fail
pos += litlen
pass:
cur.'!cursor_pass'(pos, '')
fail:
.return (cur)
.end


=back

=head2 Vtable functions
Expand Down
4 changes: 4 additions & 0 deletions src/Regex/P6Regex/Actions.pm
Expand Up @@ -178,6 +178,10 @@ method metachar:sym<var>($/) {
$past.name($name);
}
}
else {
$past := PAST::Regex.new( '!BACKREF', $name, :pasttype('subrule'),
:subtype('method') );
}
make $past;
}

Expand Down

0 comments on commit 568cc9b

Please sign in to comment.