use warnings;
use Carp qw/croak/;
-use List::Util qw/reduce/;
use B qw/class ppname svref_2object OPf_KIDS/;
$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;
return $r;
}
-sub add {
- reduce {
- $a->{$_} += $b->{$_} for keys %$b;
- $a
- } map { (ref) ? $_ : { $_ => 1 } } grep defined, @_;
-}
-
my %ops;
$ops{$_} = 1 for scalops;
if (null $op) {
# If the logop has no else branch, it can also return the *scalar* result of
# the conditional
- $l3 = { 1 => $c };
+ $l3 = { 1 => 1 };
} else {
($r3, $l3) = $self->inspect($op);
}
$op = $op->first;
redo;
}
- diag "> $n ($c)" if $DEBUG;
+ diag "> $n" if $DEBUG;
my ($rc, $lc) = $self->inspect($op);
+ $c = 1 - count $r;
+ diag Dumper [ $c, $r, \@l, $rc, $lc ] if $DEBUG;
$r = add $r, scale $c, $rc if defined $rc;
- if ($rc and not defined $lc) {
+ if (not defined $lc) {
@l = ();
last;
}
push @l, scale $c, $lc;
- $c *= count $lc if defined $lc;
}
- my $l = combine @l;
+# diag Dumper \@l if $DEBUG;
+ my $l = scale +(1 - count $r), normalize combine @l;
return $r, $l;
}
}
$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;
}
}
my $c = 1 - count $r;
- return $r, ($l && $c) ? { 'list' => $c } : undef
+ return $r, $c ? { 'list' => $c } : undef
}
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;
}
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;
}
L<perl> 5.8.1.
-L<Carp> (standard since perl 5), L<B> (since perl 5.005), L<XSLoader> (since perl 5.006) and L<List::Util> (since perl 5.007003).
+L<Carp> (standard since perl 5), L<B> (since perl 5.005) and L<XSLoader> (since perl 5.006).
=head1 AUTHOR