Skip to content

Commit

Permalink
Add laziness check in slow path
Browse files Browse the repository at this point in the history
In the slow path, add laziness check. This fixes a bug with comparison
of lazy arrays where one is exhausted, and when the the number of elems
is compared a Failure occurs ("Lazy Lists Cannot .elems")

In order for the laziness check to work in instances where two identical
lazy lists are compared, modify "ZipIterable" so that all the sub-
iterators are pulled an equal number of times, even if one of the
earlier iterators pulled "IterationEnd"
  • Loading branch information
jstuder-gh committed Apr 1, 2018
1 parent 126d8a8 commit 082f815
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/core/List.pm6
Expand Up @@ -1641,7 +1641,7 @@ proto sub prefix:<|>(|) {*}
multi sub prefix:<|>(\x) { x.Slip }

sub CMP-SLOW(@a, @b) {
(@a Zcmp @b).first(&prefix:<?>) || @a <=> @b
(@a Zcmp @b).first(&prefix:<?>) || &infix:<cmp>( |do .is-lazy for @a, @b ) || @a <=> @b
}

multi sub infix:<cmp>(@a, @b) {
Expand Down
38 changes: 22 additions & 16 deletions src/core/Rakudo/Iterator.pm6
Expand Up @@ -3844,18 +3844,21 @@ class Rakudo::Iterator {
nqp::stmts(
(my int $i = -1),
(my int $elems = nqp::elems($!iters)),
(my int $is_iterend = 0),
(my $buf :=
nqp::setelems(nqp::create(IterationBuffer),$elems)),
nqp::until(
nqp::iseq_i(($i = nqp::add_i($i,1)),$elems)
|| nqp::eqaddr(
(my $pulled := nqp::atpos($!iters,$i).pull-one),
IterationEnd
),
nqp::bindpos($buf,$i,$pulled)
nqp::while(
nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
nqp::if(
nqp::eqaddr(
(my $pulled := nqp::atpos($!iters,$i).pull-one), IterationEnd
),
$is_iterend = 1,
nqp::bindpos($buf,$i,$pulled)
)
),
nqp::if(
nqp::islt_i($i,$elems), # at least one exhausted
$is_iterend, # at least one exhausted
nqp::stmts(
#?if jvm
($!iters := Mu),
Expand Down Expand Up @@ -3930,18 +3933,21 @@ class Rakudo::Iterator {
nqp::stmts(
(my int $i = -1),
(my int $elems = nqp::elems($!iters)),
(my int $is_iterend = 0),
(my $list :=
nqp::setelems(nqp::create(IterationBuffer),$elems)),
nqp::until(
nqp::iseq_i(($i = nqp::add_i($i,1)),$elems)
|| nqp::eqaddr(
(my $pulled := nqp::atpos($!iters,$i).pull-one),
IterationEnd
),
nqp::bindpos($list,$i,$pulled)
nqp::while(
nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
nqp::if(
nqp::eqaddr(
(my $pulled := nqp::atpos($!iters,$i).pull-one), IterationEnd
),
$is_iterend = 1,
nqp::bindpos($list,$i,$pulled)
)
),
nqp::if(
nqp::islt_i($i,$elems), # at least one exhausted
$is_iterend, # at least one exhausted
nqp::stmts(
#?if jvm
($!iters := Mu),
Expand Down

0 comments on commit 082f815

Please sign in to comment.