/
LoL.pm
84 lines (73 loc) · 2.15 KB
/
LoL.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
class LoL { # declared in BOOTSTRAP
# class LoL is List {
# has Mu $!descriptor;
method new(|) {
my Mu $args := nqp::p6argvmarray();
nqp::shift($args);
nqp::p6list($args, self.WHAT, Mu);
}
method at_pos($pos is copy) {
$pos = $pos.Int;
self.exists_pos($pos)
?? nqp::findmethod(List, 'at_pos')(self, $pos)
!! nqp::p6bindattrinvres(my $v, Scalar, '$!whence',
-> { nqp::findmethod(List, 'STORE_AT_POS')(self, $pos, $v) } )
}
multi method perl(LoL:D \SELF:) {
self.WHAT.perl ~ '.new(' ~ self.map({.perl}).join(', ') ~ ')'
~ ('.item' if nqp::iscont(SELF));
}
method REIFY(Parcel \parcel, Mu \nextiter) {
my Mu $rpa := nqp::getattr(parcel, Parcel, '$!storage');
my Mu $iter := nqp::iterator($rpa);
my int $i = 0;
while $iter {
nqp::bindpos($rpa, $i, my $v = nqp::shift($iter));
$i = $i + 1;
}
nqp::findmethod(List, 'REIFY')(self, parcel, nextiter)
}
method STORE_AT_POS(\pos, Mu $v is copy) {
nqp::findmethod(List, 'STORE_AT_POS')(self, pos, $v);
}
}
sub infix:<X>(**@lol) {
my @l;
@l[0] = (@lol[0].flat,).list;
my int $i = 0;
my int $n = @lol.elems - 1;
my Mu $v := nqp::list();
gather {
while $i >= 0 {
if @l[$i] {
nqp::bindpos($v, $i, @l[$i].shift);
if $i >= $n { take nqp::p6parcel(nqp::clone($v), nqp::null()) }
else {
$i = $i + 1;
@l[$i] = (@lol[$i].flat,).list;
}
}
else { $i = $i - 1 }
}
}
};
sub infix:<Z>(**@lol) {
my @l = @lol.map({ (.flat,).list.item });
gather {
my $loop = 1;
while $loop {
my $p := @l.map({ $loop = 0 unless $_; .shift }).eager.Parcel;
take $p if $loop;
}
}
}
my &zip := &infix:<Z>;
sub roundrobin(**@lol) {
my @l = @lol.map({ (.flat,).list.item });
gather {
my $p;
while $p := @l.grep(*.Bool).map(*.shift).eager.Parcel {
take $p;
}
}
}