Skip to content

Instantly share code, notes, and snippets.

@lizmat
Last active December 18, 2017 12:55
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/a33a78d54b2571abf24673785dbe2034 to your computer and use it in GitHub Desktop.
Save lizmat/a33a78d54b2571abf24673785dbe2034 to your computer and use it in GitHub Desktop.
my take on infix:<,>(a,b) so far
diff --git a/src/core/List.pm b/src/core/List.pm
index 8bd7c66..21086ed 100644
--- a/src/core/List.pm
+++ b/src/core/List.pm
@@ -1443,41 +1443,39 @@ my class List does Iterable does Positional { # declared in BOOTSTRAP
# The , operator produces a List.
proto sub infix:<,>(|) is pure {*}
multi sub infix:<,>() { nqp::create(List) }
-multi sub infix:<,>(|) {
-
- # look for a Slip in the parameters
- my \in := nqp::p6argvmarray();
- my int $i = -1;
- my int $elems = nqp::elems(in);
- nqp::while(
- (nqp::islt_i(($i = nqp::add_i($i,1)),$elems)
- && nqp::not_i(nqp::istype(nqp::atpos(in,$i),Slip))),
- nqp::null
- );
-
+multi sub infix:<,>(\a) {
+ nqp::if(
+ nqp::istype(a,Slip),
+ Rakudo::Internals.UPGRADE-LIST-WITH-SLIP(nqp::p6argvmarray,0),
+ nqp::p6bindattrinvres(nqp::create(List),List,'$!reified',nqp::p6argvmarray)
+ )
+}
+multi sub infix:<,>(\a,\b) {
nqp::if(
- nqp::iseq_i($i,$elems), # no Slip seen, so just alias input params
- nqp::p6bindattrinvres(nqp::create(List),List,'$!reified',in),
- nqp::stmts( # Slip seen, first copy non-slippy things
- ($elems = $i),
- ($i = -1),
- (my $reified := nqp::setelems(nqp::create(IterationBuffer),$elems)),
- nqp::while(
- nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
- nqp::bindpos($reified,$i,nqp::shift(in))
- ),
- # now set up the List with a future
- (my $list :=
- nqp::p6bindattrinvres(nqp::create(List),List,'$!reified',$reified)),
- nqp::bindattr($list,List,'$!todo',
- my $todo:= nqp::create(List::Reifier)),
- nqp::bindattr($todo,List::Reifier,'$!reified',$reified),
- nqp::bindattr($todo,List::Reifier,'$!future',in),
- nqp::bindattr($todo,List::Reifier,'$!reification-target',$reified),
- $list
+ nqp::istype(a,Slip),
+ Rakudo::Internals.UPGRADE-LIST-WITH-SLIP(nqp::p6argvmarray,0),
+ nqp::if(
+ nqp::istype(b,Slip),
+ Rakudo::Internals.UPGRADE-LIST-WITH-SLIP(nqp::p6argvmarray,1),
+ nqp::p6bindattrinvres(nqp::create(List),List,'$!reified',nqp::p6argvmarray)
)
)
}
+multi sub infix:<,>(|) {
+ nqp::stmts(
+ (my \in := nqp::p6argvmarray),
+ (my int $elems = nqp::elems(in)),
+ (my int $i = -1),
+ nqp::while( # look for Slip in parameters
+ nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
+ nqp::if(
+ nqp::istype(nqp::atpos(in,$i),Slip), # found a Slip, use slow-path
+ (return Rakudo::Internals.UPGRADE-LIST-WITH-SLIP(in,$i))
+ )
+ ),
+ nqp::p6bindattrinvres(nqp::create(List),List,'$!reified',in)
+ )
+}
sub combinations(Int() $n, Int() $k) {
Seq.new(Rakudo::Iterator.Combinations($n,$k,0))
diff --git a/src/core/Rakudo/Internals.pm b/src/core/Rakudo/Internals.pm
index 5e5f940..5957775 100644
--- a/src/core/Rakudo/Internals.pm
+++ b/src/core/Rakudo/Internals.pm
@@ -2,6 +2,7 @@ my class DateTime { ... }
my role IO { ... }
my class IO::Handle { ... }
my class IO::Path { ... }
+my class List::Reifier { ... }
my class Rakudo::Metaops { ... }
my class X::Assignment::ToShaped { ... }
@@ -208,6 +209,27 @@ my class Rakudo::Internals {
)
}
+ # Upgrade the given (auto-HLLized) List with an p6argvmarray to a proper
+ # List with a reified and a todo part, and return the given List.
+ method UPGRADE-LIST-WITH-SLIP(List:D $list, int $from --> List:D) {
+ nqp::stmts(
+ (my \in := nqp::getattr($list,List,'$!reified')),
+ # reuse autogenned List object
+ nqp::bindattr($list,List,'$!reified',my $reified := nqp::list),
+ (my int $i = -1),
+ nqp::while( # copy already reified stuff
+ nqp::islt_i(($i = nqp::add_i($i,1)),$from),
+ nqp::push($reified,nqp::shift(in))
+ ),
+ # now set up the List with a future
+ nqp::bindattr($list,List,'$!todo',my $todo:= nqp::create(List::Reifier)),
+ nqp::bindattr($todo,List::Reifier,'$!reified',$reified),
+ nqp::bindattr($todo,List::Reifier,'$!future',in),
+ nqp::bindattr($todo,List::Reifier,'$!reification-target',$reified),
+ $list
+ )
+ }
+
# fast whitespace trim: str to trim, str to store trimmed str
method TRIM(\string, \trimmed --> Nil) {
my int $pos = nqp::chars(string) - 1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment