Skip to content

Commit

Permalink
Add While/Until iterators
Browse files Browse the repository at this point in the history
- While: pass on values until the first false value returned by block
- Until: don't pass values on until the first true value returned by block
  • Loading branch information
lizmat committed Nov 22, 2017
1 parent f40c381 commit 2c1a286
Showing 1 changed file with 68 additions and 0 deletions.
68 changes: 68 additions & 0 deletions src/core/Rakudo/Iterator.pm
Expand Up @@ -3318,6 +3318,41 @@ class Rakudo::Iterator {
}.new(iterator, with, unique)
}

# Returns an iterator that takes a source iterator and a Callable. It
# passes on all values from the source iterator from the moment the
# Callable returns a trueish value.
method Until(\iter, &cond) {
class :: does Iterator {
has $!iter;
has $!cond;

method SET-SELF(\iter, \cond) {
$!iter := iter;
$!cond := cond;
self
}
method new(\iter,\cond) { nqp::create(self).SET-SELF(iter,cond) }

method pull-one() is raw {
nqp::if(
$!cond,
nqp::stmts(
nqp::until(
nqp::eqaddr((my $pulled := $!iter.pull-one),IterationEnd)
|| $!cond($pulled),
nqp::null
),
($!cond := nqp::null),
$pulled
),
$!iter.pull-one
)
}
method is-lazy() { $!iter.is-lazy }
method sink-all(--> IterationEnd) { $!iter.sink-all }
}.new(iter, &cond)
}

# Returns an iterator from a given iterator where the occurrence of
# a Whatever value indicates that last value seen from the source
# iterator should be repeated indefinitely until either another
Expand Down Expand Up @@ -3376,6 +3411,39 @@ class Rakudo::Iterator {
}.new(source)
}

# Returns an iterator that takes a source iterator and a Callable. It
# passes on values from the source iterator while the Callable returns
# a trueish value. Once a falsish value is returnedm, the iterator ends.

This comment has been minimized.

Copy link
@MasterDuke17

MasterDuke17 Nov 22, 2017

Contributor

"returnedm"

This comment has been minimized.

Copy link
@zoffixznet

zoffixznet Nov 23, 2017

Contributor

Thanks. Fixed in 7939014

method While(\iter, &cond) {
class :: does Iterator {
has $!iter;
has &!cond;
has $!done;

method SET-SELF(\iter, \cond) {
$!iter := iter;
&!cond := cond;
$!done := nqp::null;
self
}
method new(\iter,\cond) { nqp::create(self).SET-SELF(iter,cond) }

method pull-one() is raw {
nqp::ifnull(
$!done,
nqp::if(
nqp::eqaddr((my $pulled := $!iter.pull-one),IterationEnd)
|| nqp::isfalse(&!cond($pulled)),
($!done := IterationEnd),
$pulled
)
)
}
method is-lazy() { $!iter.is-lazy }
method sink-all(--> IterationEnd) { $!iter.sink-all }
}.new(iter, &cond)
}

# Returns an iterator that handles all properties of a -while- with
# a condition. Takes a Callable to be considered the body of the loop,
# and a Callable for the condition..
Expand Down

0 comments on commit 2c1a286

Please sign in to comment.