Benchmark-Perl-Formance-Cargo

 view release on metacpan or  search on metacpan

share/P6STD/CursorBase.pmc  view on Meta::CPAN

    my $tpos = shift;

    $self->panic("Unexpected EOF") if $tpos > length($::ORIG);
    if (DEBUG & DEBUG::cursors) {
        my $peek = substr($::ORIG,$tpos,20);
        $peek =~ s/\n/\\n/g;
        $peek =~ s/\t/\\t/g;
        $self->deb("cursor to $tpos --------->$GREEN$peek$CLEAR");
    }
    my %r = %$self;
#    $r{_from} = $self->{_pos} // 0;
    $r{_pos} = $tpos;

    bless \%r, ref $self;
}

sub cursor_force { my $self = shift;
    my $tpos = shift;

    $self->panic("Unexpected EOF") if $tpos > length($::ORIG);
    if (DEBUG & DEBUG::cursors) {
        my $peek = substr($::ORIG,$tpos,20);
        $peek =~ s/\n/\\n/g;
        $peek =~ s/\t/\\t/g;
        $self->deb("cursor to $tpos --------->$GREEN$peek$CLEAR");
    }
    my %r = %$self;
#    $r{_from} = $self->{_pos} // 0;
    $r{_pos} = $::HIGHWATER = $tpos;

    bless \%r, ref $self;
}

sub cursor_rev { my $self = shift;
    my $fpos = shift;

    if (DEBUG & DEBUG::cursors) {
        my $peek = substr($::ORIG,$fpos,20);
        $peek =~ s/\n/\\n/g;
        $peek =~ s/\t/\\t/g;
        $self->deb("cursor_ref to $fpos --------->$GREEN$peek$CLEAR");
    }
    my %r = %$self;
    $r{_pos} = $fpos;

    bless \%r, ref $self;
}

#############################################################
# Regex service routines
#############################################################

sub callm { my $self = shift;
    my $arg = shift;
    my $class = ref($self) || $self;

    my $lvl = 0;
    my $extralvl = 0;
    my @subs;
    if (DEBUG & DEBUG::callm_show_subnames) {
        while (my @c = caller($lvl)) {
            $lvl++;
            my $s = $c[3];
            if ($s =~ /::_/) {
                next;
            }
            elsif ($s =~ /^(?:Cursor|CursorBase)?::/) {
                next;
            }
            elsif ($s =~ /^LazyMap::/) {
                next;
            }
            elsif ($s =~ /^\(eval\)/) {
                next;
            }
            else {
                $extralvl = $lvl unless $extralvl;
                $s =~ s/.*:://;
                push @subs, $s;
            }
        }
    }
    else {
        while (my @c = caller($lvl)) { $lvl++; }
    }
    my ($package, $file, $line, $subname, $hasargs) = caller(1);
    my $name = $subname;
    if (defined $arg) { 
        $name .= " " . $arg;
    }
    my $pos = '?';
    $self->deb($name, " [", $file, ":", $line, "] $class") if DEBUG & DEBUG::trace_call;
    if (DEBUG & DEBUG::callm_show_subnames) {
        $RED . join(' ', reverse @subs) . $CLEAR . ':' x $extralvl;
    }
    else {
        ':' x $lvl;
    }
}

sub retm {
    return $_[0] unless DEBUG & DEBUG::trace_call;
    my $self = shift;
    warn "Returning non-Cursor: $self\n" unless exists $self->{_pos};
    my ($package, $file, $line, $subname, $hasargs) = caller(1);
    $self->deb($subname, " returning @{[$self->{_pos}]}");
    $self;
}

sub _MATCHIFY { my $self = shift;
    my $S = shift;
    my $name = shift;
    return () unless @_;
    my $xact = $self->{_xact};
    my @result = lazymap( sub { my $x = shift; $x->{_xact} = $xact; $x->_REDUCE($S, $name)->retm() }, @_);
    if (wantarray) {
        @result;
    }
    else {
        $result[0];
    }
}

sub _MATCHIFYr { my $self = shift;
    my $S = shift;
    my $name = shift;
    return () unless @_;
    my $var = shift;
#    $var->{_from} = $self->{_from};
    my $xact = $self->{_xact};
    $var->{_xact} = $xact;
    $var->_REDUCE($S, $name)->retm();
}

sub _SCANf { my $self = shift;

    local $CTX = $self->callm if DEBUG & DEBUG::trace_call;
    my $eos = @::ORIG;

    my $pos = $self->{_pos};
    my $C = $self->cursor_xact("SCANf $pos");
    my $xact = $C->xact;

    lazymap( sub { $self->cursor($_[0])->retm() }, LazyRange->new($xact, $pos,$eos) );
}

sub _SCANg { my $self = shift;

    local $CTX = $self->callm if DEBUG & DEBUG::trace_call;
    my $pos = $self->{_pos};
    my $eos = @::ORIG;
    my $C = $self->cursor_xact("SCANg $pos");
    my $xact = $C->xact;

    lazymap( sub { $C->cursor($_[0])->retm() }, LazyRangeRev->new($xact, $eos,$pos) );
}

sub _STARf { my $self = shift;
    my $block = shift;
    no warnings 'recursion';

    local $CTX = $self->callm if DEBUG & DEBUG::trace_call;

    my $pos = $self->{_pos};
    my $C = $self->cursor_xact("SCANf $pos");

share/P6STD/CursorBase.pmc  view on Meta::CPAN


    if (DEBUG & DEBUG::autolexer) {
        print ::LOG "JIT DFA node generation:\n";
        _dfa_dump_node($node);
    }

    $node->[0];
}

sub _scan_regexes { my ($class, $key) = @_;
    no strict 'refs';
    (${ $class . "::REGEXES" } //= do {
        my $stash = \ %{ $class . "::" };
        my %over;
        my %proto;

        for my $m (keys %$stash) {
            next if ref $stash->{$m};  # use constant
            next if !defined *{$stash->{$m}}{CODE};
            my ($meth, $p) = $m =~ /^(.*?)(__S_\d\d\d.*)?__PEEK$/ or next;
            #$self->deb("\tfound override for $meth in $m") if DEBUG & DEBUG::autolexer;
            $over{$meth} = 1;
            push @{$proto{$meth}}, $m if $p;
        }

        for (keys %proto) {
            @{$proto{$_}} = sort @{$proto{$_}};
        }

        $proto{ALL} = [ keys %over ];
        \%proto;
    })->{$key};
}

sub _AUTOLEXgenDFA { my ($self, $realkey, $key, $retree) = @_;
    local $::AUTOLEXED{$realkey} = $fakepos;

    my $lang = ref $self;

    $self->deb("AUTOLEXgen $key in $lang") if DEBUG & DEBUG::autolexer;
    my $ast = $retree->{$key};

    UP: {
        # Whenever possible, we want to share a lexer amongst as many grammars
        # as we can.  So we try to float lexers up to superclasses.

        no strict 'refs';
        my $isa = \@{ $lang . "::ISA" };

        # We don't support multiple inheritance (can we?)
        if (@$isa != 1) {
            $self->deb("\tcannot reuse $key; multiply inherited") if DEBUG & DEBUG::autolexer;
            last;
        }

        my $super = $isa->[0];

        my $dic = $ast->{dic} //= do {
            my $i = 1; # skip _AUTOLEXpeek;
            my $pkg = 'CursorBase';
            $pkg = caller($i++) while $pkg eq 'CursorBase';
            #print STDERR "dic run: $pkg\n";
            $self->deb("\tdeclared in class $pkg") if DEBUG & DEBUG::autolexer;
            $pkg;
        };

        my $ar = ${ $lang . "::ALLROLES" } //= do {
            +{ map { $_->name, 1 } ($lang->meta, $lang->meta->calculate_all_roles) }
        };

        # It doesn't make sense to float a lexer above Cursor, or (for 'has'
        # regexes), the class of definition.
        if ($ar->{$dic}) {
            $self->deb("\tcannot reuse $key; at top") if DEBUG & DEBUG::autolexer;
            last;
        }

        my $supercursor = $self->cursor_fresh($super);
        my $superlexer  = eval {
            local %::AUTOLEXED;
            $supercursor->_AUTOLEXpeek($key, $retree)
        };

        if (!$superlexer) {
            $self->deb("\tcannot reuse $key; failed ($@)") if DEBUG & DEBUG::autolexer;
            last;
        }

        my $ml = _scan_regexes($lang, 'ALL');

        for my $meth (@$ml) {
            if ($superlexer->{USED_METHODS}{$meth}) {
                $self->deb("\tcannot reuse $key; $meth overridden/augmented")
                    if DEBUG & DEBUG::autolexer;
                last UP;
            }
        } 

        $self->deb("\treusing ($key, $realkey, $lang, $super).") if DEBUG & DEBUG::autolexer;
        return $superlexer;
    }

    my $dba = $ast->{dba};

    my $d = DEBUG & DEBUG::autolexer;
    print ::LOG "generating DFA lexer for $key -->\n" if $d;
    my $nfa;

    if ($key =~ /(.*):\*$/) {
        my $proto = $1;
        $dba = $proto;
        my $protopat = $1 . '__S_';
        my $protolen = length($protopat);
        my @alts;
        my $j = 0;
        my @stack = $lang;

        while (@stack) {
            no strict 'refs';
            my $class = pop @stack;
            push @stack, reverse @{ $class . "::ISA" };



( run in 0.935 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )