Skip to content

Instantly share code, notes, and snippets.

@lizmat
Created October 2, 2015 11:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lizmat/9f95a6f75f27cebecd65 to your computer and use it in GitHub Desktop.
Save lizmat/9f95a6f75f27cebecd65 to your computer and use it in GitHub Desktop.
Trying to implement sink-all for: for @A -> $a, $b {} case
diff --git a/src/core/Any-iterable-methods.pm b/src/core/Any-iterable-methods.pm
index 95e0c67..dc6ea6f 100644
--- a/src/core/Any-iterable-methods.pm
+++ b/src/core/Any-iterable-methods.pm
@@ -296,6 +296,67 @@ augment class Any {
&& nqp::eqaddr($result, IterationEnd);
$result
}
+
+ method sink-all() {
+ $!value-buffer.DEFINITE
+ ?? nqp::setelems($!value-buffer, 0)
+ !! ($!value-buffer := IterationBuffer.new);
+
+ if !$!did-init && nqp::can(&!block, 'fire_phasers') {
+ $!did-init = 1;
+ $!CAN_FIRE_PHASERS = 1;
+ $!NEXT = +&!block.phasers('NEXT');
+ nqp::p6setfirstflag(&!block) if &!block.phasers('FIRST');
+ }
+ my $result;
+ my int $redo = 1;
+ until nqp::eqaddr($result, IterationEnd) {
+ if $!source.push-exactly($!value-buffer, $!count) =:= IterationEnd
+ && nqp::elems($!value-buffer) == 0 {
+ $result := IterationEnd
+ }
+ else {
+ nqp::while(
+ $redo,
+ nqp::stmts(
+ $redo = 0,
+ nqp::handle(
+ nqp::stmts(
+ ($result := nqp::p6invokeflat(&!block, $!value-buffer)),
+ ($!did-iterate = 1),
+ (nqp::setelems($!value-buffer, 0)),
+ ($redo = 1
+ unless nqp::eqaddr(
+ $!source.push-exactly($!value-buffer, $!count),
+ IterationEnd)
+ && nqp::elems($!value-buffer) == 0),
+ nqp::if($!NEXT, &!block.fire_phasers('NEXT')),
+ ),
+ 'LABELED', nqp::decont($!label),
+ 'NEXT', nqp::stmts(
+ ($!did-iterate = 1),
+ nqp::if($!NEXT, &!block.fire_phasers('NEXT')),
+ (nqp::setelems($!value-buffer, 0)),
+ nqp::eqaddr($!source.push-exactly($!value-buffer, $!count), IterationEnd)
+ && nqp::elems($!value-buffer) == 0
+ ?? ($result := IterationEnd)
+ !! ($redo = 1)),
+ 'REDO', $redo = 1,
+ 'LAST', nqp::stmts(
+ ($!did-iterate = 1),
+ ($result := IterationEnd)
+ )
+ )
+ ),
+ :nohandler);
+ }
+ &!block.fire_phasers('LAST')
+ if $!CAN_FIRE_PHASERS
+ && $!did-iterate
+ && nqp::eqaddr($result, IterationEnd);
+ }
+ IterationEnd
+ }
}.new(&block, source, $count, $label));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment