Combinator
view release on metacpan or search on metacpan
lib/Combinator.pm view on Meta::CPAN
undef $_[0][2];
}
}
sub cv_cb { # (cv, cb)
if( $_[0][0] ) {
$_[0][1] = $_[1];
}
else {
$_[1](@{$_[0][2]});
undef $_[0][2];
}
}
sub ser {
my $depth = shift;
if( @_ <= 1 ) { # next only
return $_[0];
}
my $code = shift;
unshift @_, $depth;
my $next = &ser;
replace_code($depth, $code);
$code =~ s/$opt{next}/(do{my\$t=\$Combinator::cv1;++\$t->[0];sub{if(\$t){Combinator::cv_end(\$t,\\\@_);undef\$t}else{my(undef,\$f,\$l)=caller;warn"next should be invoked only once at \$f line \$l.\\n"}}})/g;
my $out = "local\$Combinator::guard=Guard::guard{Combinator::cv_end(\$Combinator::cv0,\\\@_)};local\$Combinator::cv1=[1];$code;--\$Combinator::cv1->[0];Combinator::cv_cb(\$Combinator::cv1,Combinator::att_sub(\$Combinator::head,\$Combinator::cv0,s...
return $out;
}
sub com { # depth, code, head
my($depth, $code, $head) = @_;
my @ser;
$code .= "\n" if( substr($code, -1) eq "\n" );
push @ser, $1 while( $code =~ m/(?:^|$ser_pat)($token_pat*?)(?=$ser_pat|$)/gs );
if( @ser == 1 && $head !~ $cir_par_pat && $head !~ $cir_begin_pat && $head !~ $nex_begin_pat ) {
replace_code($depth, @ser);
return "{$ser[0]}";
}
my $delayed = $head =~ $nex_begin_pat;
my $out = (
$delayed ?
"(do{++\$Combinator::cv1->[0];Combinator::att_sub(do{\\(my\$t=1)},\$Combinator::cv1,sub{if(!\${\$_[0]}){my(undef,\$f,\$l)=caller;warn\"nex should be invoked only once at \$f line \$l.\\n\";return}--\${\$_[0]};shift;local\$Combinator::...
"{&{sub{local\$Combinator::cv0=\$Combinator::cv1;++\$Combinator::cv0->[0];"
)."local\$Combinator::head=[1,Devel::Caller::caller_cv(0)];" .
ser($depth+1, @ser, $head =~ /^(?:$cir_par_pat|$cir_begin_pat)$/ ? "--\$Combinator::cv0->[0];\$Combinator::cv1=\$Combinator::cv0;Combinator::cv_end(\$Combinator::head,\\\@_)" : "Combinator::cv_end(\$Combinator::cv0,\\\@_)") .
(
$delayed ?
"})})" :
"}}}"
);
return $out;
}
sub replace_code {
my $depth = shift;
$_[0] =~ s[$com_pat]{
my $code = $1;
my $out = '';
while( $code =~ /($begin_pat|$par_pat|$cir_par_pat)($token_pat*?)(?=($par_pat|$cir_par_pat|$end_pat))/g ) {
my $fragment = $2;
$out .= com($depth, $fragment, $1);
}
$out;
}ge;
}
FILTER {
replace_code(0, $_);
if( $opt{verbose} ) {
my $verbose_code = $_;
my $n = $line_shift;
$verbose_code =~ s/^/sprintf"%6d: ", ++$n/gem;
print "Code after filtering:\n$verbose_code\nEnd Of Code\n";
}
};
1; # End of Combinator
( run in 1.044 second using v1.01-cache-2.11-cpan-364913b4093 )