X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=lib%2FSub%2FNary.pm;h=611f780d617ad220649149b56ab64094db53cb59;hb=fd35681c6f0a1e84d407dbe4fcc7a3c25e4d8851;hp=f21c8f81446aa64aff112b2f49f22bfb7fa47939;hpb=91deeda20173f3d35c5b936c9e6db1cbe08f0e00;p=perl%2Fmodules%2FSub-Nary.git diff --git a/lib/Sub/Nary.pm b/lib/Sub/Nary.pm index f21c8f8..611f780 100644 --- a/lib/Sub/Nary.pm +++ b/lib/Sub/Nary.pm @@ -6,7 +6,6 @@ use strict; use warnings; use Carp qw/croak/; -use List::Util qw/reduce/; use B qw/class ppname svref_2object OPf_KIDS/; @@ -178,12 +177,6 @@ sub name ($) { $n eq 'null' ? substr(ppname($_[0]->targ), 3) : $n } -sub scale { - my ($c, $r) = @_; - return unless defined $r; - return (ref $r) ? { map { $_ => $r->{$_} * $c } keys %$r } : { $r => $c }; -} - sub power { my ($p, $n, $c) = @_; return unless defined $p; @@ -199,13 +192,6 @@ sub power { return $r; } -sub add { - reduce { - $a->{$_} += $b->{$_} for keys %$b; - $a - } map { (ref) ? $_ : { $_ => 1 } } grep defined, @_; -} - my %ops; $ops{$_} = 1 for scalops; @@ -502,10 +488,17 @@ sub pp_leaveloop { } $op = $op->sibling; - my $r = (name($op->first) eq 'and') ? ($self->inspect($op->first->first->sibling))[0] - : ($self->inspect($op))[0]; + my $r; + if (name($op->first) eq 'and') { + ($r, my $l) = ($self->inspect($op->first->first))[0]; + return $r, $l if $r and zero $l; + $r = ($self->inspect($op->first->first->sibling))[0]; + } else { + $r = ($self->inspect($op))[0]; + } + my $c = 1 - count $r; - diag "& leaveloop" if $DEBUG; + diag "& leaveloop $c" if $DEBUG; return $r, $c ? { 0 => $c } : undef; } @@ -536,7 +529,7 @@ sub pp_flip { } my $c = 1 - count $r; - return $r, ($l && $c) ? { 'list' => $c } : undef + return $r, $c ? { 'list' => $c } : undef } sub pp_grepwhile { @@ -548,19 +541,18 @@ sub pp_grepwhile { my ($r2, $l2) = $self->inspect($op->sibling); return $r2, $l2 if $r2 and zero $l2; - diag Dumper [ $r2, $l2 ] if $DEBUG; - my $c = count $l2; # First one to happen + my $c2 = count $l2; # First one to happen my ($r1, $l1) = $self->inspect($op); - diag Dumper [ $r1, $l1 ] if $DEBUG; - return (add $r2, scale $c, $r1), undef if $r1 and zero $l1 and not zero $l2; - return { 'list' => 1 }, undef if list $l2; + return (add $r2, scale $c2, $r1), undef if $r1 and zero $l1 and not zero $l2; + diag Dumper [ [ $r1, $l1 ], [ $r2, $l2 ] ] if $DEBUG; + my $c1 = count $l1; $l2 = { $l2 => 1 } unless ref $l2; - my $r = add $r2, scale $c, - normalize - add map { power $r1, $_, $l2->{$_} } keys %$l2; - $c = 1 - count $r; + my $r = add $r2, + scale $c2, + add map { scale $l2->{$_}, cumulate $r1, $_, $c1 } keys %$l2; + my $c = 1 - count $r; return $r, $c ? { ((zero $l2) ? 0 : 'list') => $c } : undef; } @@ -573,17 +565,18 @@ sub pp_mapwhile { my ($r2, $l2) = $self->inspect($op->sibling); return $r2, $l2 if $r2 and zero $l2; - my $c = count $l2; # First one to happen + my $c2 = count $l2; # First one to happen my ($r1, $l1) = $self->inspect($op); - return (add $r2, scale $c, $r1), undef if $r1 and zero $l1 and not zero $l2; + return (add $r2, scale $c2, $r1), undef if $r1 and zero $l1 and not zero $l2; diag Dumper [ [ $r1, $l1 ], [ $r2, $l2 ] ] if $DEBUG; + my $c1 = count $l1; $l2 = { $l2 => 1 } unless ref $l2; - my $r = add $r2, scale $c, - normalize - add map { power $r1, $_, $l2->{$_} } keys %$l2; - $c = 1 - count $r; + my $r = add $r2, + scale $c2, + add map { scale $l2->{$_}, cumulate $r1, $_, $c1 } keys %$l2; + my $c = 1 - count $r; my $l = scale $c, normalize add map { power $l1, $_, $l2->{$_} } keys %$l2; return $r, $l; } @@ -602,7 +595,7 @@ C isn't specialized when encountered in the optree. L 5.8.1. -L (standard since perl 5), L (since perl 5.005), L (since perl 5.006) and L (since perl 5.007003). +L (standard since perl 5), L (since perl 5.005) and L (since perl 5.006). =head1 AUTHOR