Perl6-Pugs

 view release on metacpan or  search on metacpan

perl5/Pugs-Compiler-Rule/temp/lib/Pugs/Runtime/Rule.pm  view on Meta::CPAN

package Pugs::Runtime::Rule;

=for About

Original file: pX/Common/iterator_engine.pl - fglock

Old docs are after the __END__.

This is a rewrite of the matching engine, aiming to generate the same data structure as
the 'ratchet' version.

- It currently passes all it's tests.

- The algorithm is a bit simpler than the previous version, but the complexity is the same.

TODO

- The structure generated by concat() still looks like a tree, instead of a 'plain' Match.

- There are no tests yet for <before>, hashes, end_of_string, and the rule wrapper.

- It needs a 'direction' flag, in order to implement <after>.

- Captures need an internal 'counter', see the ratchet version for an implementation
and tests.

- Quantified matches could use less stack space.

- Simplify arg list - the functions currently take 8 arguments.

=cut

use strict;
use warnings;
#use Smart::Comments; #for debugging, look also at Filtered-Comments.pm
use Data::Dumper;
use PadWalker qw( peek_my );  # peek_our ); ???

# note: alternation is first match (not longest). 
# note: the list in @$nodes can be modified at runtime
sub alternation {
    my $nodes = shift;
    return sub {
        my @state = $_[1] ? @{$_[1]} : ( 0, 0 );
        $_[3] = bless \{ bool => \0 }, 'Pugs::Runtime::Match::Ratchet';
        while ( $state[0] <= $#$nodes ) {
            $state[1] = $nodes->[ $state[0] ]->( $_[0], $state[1], @_[2,3,4,5,6,7] );
            $state[0]++ unless $state[1];
            last if $_[3] || ${$_[3]}->{abort};
        }
        return unless $_[3];
        return \@state;
    }
}

sub concat {
    my $nodes = shift;
    return sub {
        my @state = $_[1] ? @{$_[1]} : ();
        do {
            my $st = $nodes->[0]->( $_[0], $state[0], @_[2,3,4,5,6,7] );
            return if ! $_[3] || ${$_[3]}->{abort};
            
            
            $_[3] = { match => [ $_[3] ] };
            $state[1] = $nodes->[1]->( $_[0], $state[1], $_[2], $_[3]->{match}[1], 
                         $_[4], $_[3]->{match}[0]->to, @_[6,7] );
            $state[0] = $st unless $state[1];
            
            
        } while !   $_[3]->{match}[1] && 
                ! ${$_[3]->{match}[1]}->{abort} &&
                $state[0]; 
        $_[3] = bless \{
                bool  => \$_[3]{match}[1]->bool,
                str   => \$_[0],
                from  => \$_[3]{match}[0]->from,
                to    => \$_[3]{match}[1]->to,
                named => { %{$_[3]{match}[0]}, %{$_[3]{match}[1]} },
                match => [ @{$_[3]{match}[0]}, @{$_[3]{match}[1]} ],
                capture => ${$_[3]{match}[1]}->{capture},
                abort   => ${$_[3]{match}[1]}->{abort},
        }, 'Pugs::Runtime::Match::Ratchet';
        return \@state;
    }
}

sub constant { 
    my $const = shift;
    my $lconst = length( $const );
    no warnings qw( uninitialized );
    return sub {
        my $bool = $const eq substr( $_[0], $_[5], $lconst );
        $_[3] = bless \{ 
                bool  => \$bool,
                str   => \$_[0],
                from  => \(0 + $_[5]),



( run in 0.878 second using v1.01-cache-2.11-cpan-788537b7465 )