From 082f81525cadeb985c945501a962971ddf77ddc6 Mon Sep 17 00:00:00 2001 From: Jeremy Studer Date: Sat, 31 Mar 2018 20:48:59 -0400 Subject: [PATCH] Add laziness check in slow path 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" --- src/core/List.pm6 | 2 +- src/core/Rakudo/Iterator.pm6 | 38 +++++++++++++++++++++--------------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/core/List.pm6 b/src/core/List.pm6 index d58e5058faa..d73a96eeda3 100644 --- a/src/core/List.pm6 +++ b/src/core/List.pm6 @@ -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:( |do .is-lazy for @a, @b ) || @a <=> @b } multi sub infix:(@a, @b) { diff --git a/src/core/Rakudo/Iterator.pm6 b/src/core/Rakudo/Iterator.pm6 index d42f9ab3393..032726bfa92 100644 --- a/src/core/Rakudo/Iterator.pm6 +++ b/src/core/Rakudo/Iterator.pm6 @@ -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), @@ -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),