Skip to content

Commit

Permalink
Introduce R::I.LastFromIterator
Browse files Browse the repository at this point in the history
Return the last value generated from an iterator, or IterationEnd
for an empty iterator. Generalised from List.tail() functionality.
To be used later for Str.match(/./, :nth(*))
  • Loading branch information
lizmat committed Oct 22, 2016
1 parent a3406cb commit 127b3be
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 17 deletions.
24 changes: 7 additions & 17 deletions src/core/Any-iterable-methods.pm
Expand Up @@ -1898,23 +1898,13 @@ Did you mean to add a stub (\{...\}) or did you mean to .classify?"

proto method tail(|) { * }
multi method tail(Any:D:) is raw {
nqp::stmts(
(my $result := IterationEnd),
nqp::if(
(my $iter := self.iterator).is-lazy,
Failure.new(X::Cannot::Lazy.new(:action<tail>)),
nqp::stmts(
nqp::until(
nqp::eqaddr((my $pulled := $iter.pull-one),IterationEnd),
($result := $pulled)
),
nqp::if(
nqp::eqaddr($result,IterationEnd),
Nil,
$result
)
)
)
nqp::if(
nqp::eqaddr((my $pulled :=
Rakudo::Internals.LastFromIterator(self.iterator,'tail')),
IterationEnd
),
Nil,
$pulled
)
}
multi method tail(Any:D: Int(Cool) $n) {
Expand Down
16 changes: 16 additions & 0 deletions src/core/Rakudo/Internals.pm
Expand Up @@ -368,6 +368,22 @@ my class Rakudo::Internals {
}.new(iterator, n, action, $full)
}

# Return the last value of an iterator (if any)
method LastFromIterator(\iterator, $action) is raw {
nqp::if(
iterator.is-lazy,
X::Cannot::Lazy.new(:$action).throw,
nqp::stmts(
(my $result := IterationEnd),
nqp::until(
nqp::eqaddr((my $pulled := iterator.pull-one),IterationEnd),
($result := $pulled)
),
$result
)
)
}

# Iterate over a source iterator and an iterator generating index values
# from a given offset. Optionally, call block if an out-of-bounds index
# value is obtained, or simply return Nil for out of bounds index values
Expand Down

0 comments on commit 127b3be

Please sign in to comment.