Skip to content

Commit

Permalink
Fix .push-all/.skip-all on SlippyIterators
Browse files Browse the repository at this point in the history
Fixes RT#132109: https://rt.perl.org/Ticket/Display.html?id=132109

The implemented methods forget to check whether we're currently
$!slipping, which causes loss of all the remaining elements in the
currently slipping Slip.

Fix by add ing a check for $!slipping and doing self.skip-one and
pushing (or skipping) those values before we go into the main
loop of pulling more from the source iterator.
  • Loading branch information
zoffixznet committed Sep 30, 2017
1 parent 9bbfed1 commit 41896b7
Showing 1 changed file with 153 additions and 98 deletions.
251 changes: 153 additions & 98 deletions src/core/Any-iterable-methods.pm
Expand Up @@ -159,6 +159,15 @@ Did you mean to add a stub (\{...\}) or did you mean to .classify?"
my int $done;
my $pulled;
my $value;

nqp::if(
$!slipping,
nqp::until(
nqp::eqaddr(($value := self.slip-one),IterationEnd),
$target.push($value)
)
);

until $done
|| nqp::eqaddr(($value := $!source.pull-one),IterationEnd) {
nqp::stmts(
Expand Down Expand Up @@ -211,6 +220,14 @@ Did you mean to add a stub (\{...\}) or did you mean to .classify?"
)
);

nqp::if(
$!slipping,
nqp::until(
nqp::eqaddr(self.slip-one,IterationEnd),
nqp::null
)
);

my int $stopped;
my int $done;
my $value;
Expand Down Expand Up @@ -424,49 +441,68 @@ Did you mean to add a stub (\{...\}) or did you mean to .classify?"
}

method push-all($target --> IterationEnd) {
nqp::until(
nqp::eqaddr((my $value := $!source.pull-one),IterationEnd),
nqp::stmts(
(my int $redo = 1),
nqp::while(
$redo,
nqp::stmts(
($redo = 0),
nqp::handle(
nqp::if(
nqp::istype((my $result := &!block($value)),Slip),
self.slip-all($result,$target),
$target.push($result)
),
'LABELED', $!label,
'REDO', ($redo = 1),
'LAST', return,
'NEXT', nqp::null, # need NEXT for next LABEL support
)
),
:nohandler
nqp::stmts(
(my $value),
nqp::if(
$!slipping,
nqp::until(
nqp::eqaddr(($value := self.slip-one),IterationEnd),
$target.push($value)
)
),
nqp::until(
nqp::eqaddr(($value := $!source.pull-one),IterationEnd),
nqp::stmts(
(my int $redo = 1),
nqp::while(
$redo,
nqp::stmts(
($redo = 0),
nqp::handle(
nqp::if(
nqp::istype((my $result := &!block($value)),Slip),
self.slip-all($result,$target),
$target.push($result)
),
'LABELED', $!label,
'REDO', ($redo = 1),
'LAST', return,
'NEXT', nqp::null, # need NEXT for next LABEL support
)
),
:nohandler
)
)
)
)
}

method sink-all(--> IterationEnd) {
nqp::until(
nqp::eqaddr((my $value := $!source.pull-one()),IterationEnd),
nqp::stmts(
(my int $redo = 1),
nqp::while(
$redo,
nqp::stmts(
($redo = 0),
nqp::handle( # doesn't sink
&!block($value),
'LABELED', $!label,
'NEXT', nqp::null, # need NEXT for next LABEL support
'REDO', ($redo = 1),
'LAST', return
),
:nohandler
nqp::stmts(
nqp::if(
$!slipping,
nqp::until(
nqp::eqaddr(self.slip-one,IterationEnd),
nqp::null
)
),
nqp::until(
nqp::eqaddr((my $value := $!source.pull-one()),IterationEnd),
nqp::stmts(
(my int $redo = 1),
nqp::while(
$redo,
nqp::stmts(
($redo = 0),
nqp::handle( # doesn't sink
&!block($value),
'LABELED', $!label,
'NEXT', nqp::null, # need NEXT for next LABEL support
'REDO', ($redo = 1),
'LAST', return
),
:nohandler
)
)
)
)
Expand Down Expand Up @@ -554,78 +590,97 @@ Did you mean to add a stub (\{...\}) or did you mean to .classify?"
}

method push-all($target --> IterationEnd) {
nqp::until(
nqp::eqaddr((my $value := $!source.pull-one),IterationEnd),
nqp::stmts(
(my int $redo = 1),
nqp::while(
$redo,
nqp::stmts(
($redo = 0),
nqp::handle(
nqp::if(
nqp::eqaddr(
(my $value2 := $!source.pull-one),
IterationEnd
),
nqp::stmts(
(my $result := &!block($value)),
nqp::stmts(
(my $value),
nqp::if(
$!slipping,
nqp::until(
nqp::eqaddr(($value := self.slip-one),IterationEnd),
$target.push($value)
)
),
nqp::until(
nqp::eqaddr(($value := $!source.pull-one),IterationEnd),
nqp::stmts(
(my int $redo = 1),
nqp::while(
$redo,
nqp::stmts(
($redo = 0),
nqp::handle(
nqp::if(
nqp::eqaddr(
(my $value2 := $!source.pull-one),
IterationEnd
),
nqp::stmts(
(my $result := &!block($value)),
nqp::if(
nqp::istype($result,Slip),
self.slip-all($result,$target),
$target.push($result)
),
return
),
nqp::if(
nqp::istype($result,Slip),
nqp::istype(
($result := &!block($value,$value2)),
Slip
),
self.slip-all($result,$target),
$target.push($result)
),
return
)
),
nqp::if(
nqp::istype(
($result := &!block($value,$value2)),
Slip
),
self.slip-all($result,$target),
$target.push($result)
)
),
'LABELED', $!label,
'REDO', ($redo = 1),
'LAST', return,
'NEXT', nqp::null, # need NEXT for next LABEL support
)
),
:nohandler
'LABELED', $!label,
'REDO', ($redo = 1),
'LAST', return,
'NEXT', nqp::null, # need NEXT for next LABEL support
)
),
:nohandler
)
)
)
)
}

method sink-all(--> IterationEnd) {
nqp::until(
nqp::eqaddr((my $value := $!source.pull-one()),IterationEnd),
nqp::stmts(
(my int $redo = 1),
nqp::while(
$redo,
nqp::stmts(
($redo = 0),
nqp::handle( # doesn't sink
nqp::if(
nqp::eqaddr(
(my $value2 := $!source.pull-one),
IterationEnd
),
nqp::stmts(
(&!block($value)),
return
nqp::stmts(
nqp::if(
$!slipping,
nqp::until(
nqp::eqaddr(self.slip-one,IterationEnd),
nqp::null,
)
),
nqp::until(
nqp::eqaddr((my $value := $!source.pull-one()),IterationEnd),
nqp::stmts(
(my int $redo = 1),
nqp::while(
$redo,
nqp::stmts(
($redo = 0),
nqp::handle( # doesn't sink
nqp::if(
nqp::eqaddr(
(my $value2 := $!source.pull-one),
IterationEnd
),
nqp::stmts(
(&!block($value)),
return
),
(&!block($value,$value2))
),
(&!block($value,$value2))
),
'LABELED', $!label,
'NEXT', nqp::null, # need NEXT for next LABEL support
'REDO', ($redo = 1),
'LAST', return
)
),
:nohandler
'LABELED', $!label,
'NEXT', nqp::null, # need NEXT for next LABEL support
'REDO', ($redo = 1),
'LAST', return
)
),
:nohandler
)
)
)
)
Expand Down

0 comments on commit 41896b7

Please sign in to comment.