-
-
Notifications
You must be signed in to change notification settings - Fork 373
/
Array.pm
133 lines (120 loc) Β· 4.89 KB
/
Array.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
class Array {
# Has attributes and parent List declared in BOOTSTRAP.
method new(|) {
my Mu $args := pir::perl6_current_args_rpa__P();
nqp::shift($args);
nqp::p6list($args, self.WHAT, Bool::True);
}
multi method at_pos(Array:D: $pos) is rw {
my int $p = nqp::unbox_i($pos.Int);
my Mu $items := nqp::p6listitems(self);
# hotpath check for element existence (RT #111848)
nqp::existspos($items, $p)
|| nqp::getattr(self, List, '$!nextiter').defined
&& self.exists($p)
?? nqp::atpos($items, $p)
!! pir::setattribute__0PPsP(my $v, Scalar, '$!whence',
-> { nqp::bindpos($items, $p, $v) } )
}
multi method at_pos(Array:D: int $pos) is rw {
my Mu $items := nqp::p6listitems(self);
# hotpath check for element existence (RT #111848)
nqp::existspos($items, $pos)
|| nqp::getattr(self, List, '$!nextiter').defined
&& self.exists($pos)
?? nqp::atpos($items, $pos)
!! pir::setattribute__0PPsP(my $v, Scalar, '$!whence',
-> { nqp::bindpos($items, $pos, $v) } )
}
proto method bind_pos(|) { * }
multi method bind_pos($pos is copy, \bindval) is rw {
$pos = $pos.Int;
self.gimme($pos + 1);
nqp::bindpos(nqp::getattr(self, List, '$!items'), nqp::unbox_i($pos), bindval);
}
multi method bind_pos(int $pos, \bindval) is rw {
self.gimme($pos + 1);
nqp::bindpos(nqp::getattr(self, List, '$!items'), $pos, bindval)
}
method delete(@array is rw: *@indices) {
my $elems = @array.elems;
my @result;
for @indices -> $index {
my $i = $index ~~ Callable
?? $index($elems)
!! +$index;
@result.push(@array[$i]);
undefine @array[$i];
# next seems unnecessary but handles an obscure
# edge case
if $i == (@array - 1) {
@array.pop;
}
}
@array.pop while ?@array && !defined @array[@array.elems - 1];
return @result;
}
method flattens() { 1 }
multi method perl(Array:D \SELF:) {
nqp::iscont(SELF)
?? '[' ~ self.map({.perl}).join(', ') ~ ']'
!! self.WHAT.perl ~ '.new(' ~ self.map({.perl}).join(', ') ~ ')'
}
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) is rw {
nqp::findmethod(List, 'STORE_AT_POS')(self, pos, $v);
}
method STORE(|) {
# get arguments, shift off invocant
my $args := pir::perl6_current_args_rpa__P();
nqp::shift($args);
# make an array from them (we can't just use ourself for this,
# or @a = @a will go terribly wrong); make it eager
my $list := nqp::p6list($args, Array, Mu);
nqp::bindattr($list, List, '$!flattens', True);
$list.eager;
# clear our items and set our next iterator to be one over
# the array we just created
nqp::bindattr(self, List, '$!items', Mu);
nqp::bindattr(self, List, '$!nextiter', nqp::p6listiter(nqp::list($list), self));
self
}
my role TypedArray[::TValue] does Positional[TValue] {
multi method at_pos($pos is copy, TValue $v? is copy) is rw {
$pos = $pos.Int;
self.exists($pos)
?? nqp::atpos(nqp::getattr(self, List, '$!items'), nqp::unbox_i($pos))
!! pir::setattribute__0PPsP($v, Scalar, '$!whence',
-> { nqp::bindpos(nqp::getattr(self, List, '$!items'), nqp::unbox_i($pos), $v) } )
}
multi method at_pos(int $pos, TValue $v? is copy) is rw {
self.exists($pos)
?? nqp::atpos(nqp::getattr(self, List, '$!items'), $pos)
!! pir::setattribute__0PPsP($v, Scalar, '$!whence',
-> { nqp::bindpos(nqp::getattr(self, List, '$!items'), $pos, $v) } )
}
multi method bind_pos($pos is copy, TValue \bindval) is rw {
$pos = $pos.Int;
self.gimme($pos + 1);
nqp::bindpos(nqp::getattr(self, List, '$!items'), nqp::unbox_i($pos), bindval)
}
multi method bind_pos(int $pos, TValue \bindval) is rw {
self.gimme($pos + 1);
nqp::bindpos(nqp::getattr(self, List, '$!items'), $pos, bindval)
}
# XXX some methods to come here...
}
method PARAMETERIZE_TYPE(Mu $t) {
self but TypedArray[$t.WHAT]
}
}
sub circumfix:<[ ]>(*@elems) is rw { my $x = @elems.eager }