1. # all sub postcircumfix [] candidates here please
  2. # Generates list of positions to index into the array at. Takes all those
  3. # before something lazy is encountered and eagerly reifies them. If there
  4. # are any lazy things in the slice, then we lazily consider those, but will
  5. # truncate at the first one that is out of range. The optional
  6. # :$eagerize will be called if Whatever/WhateverCode is encountered or if
  7. # clipping of lazy indices is enacted. It should return the number of
  8. # elements of the array if called with Whatever, or do something EXISTS-POSish
  9. # if called with an Int. Before it does so, it may cause the calling code
  10. # to switch to a memoized version of an iterator by modifying variables in
  11. # the caller's scope.
  12. proto sub POSITIONS(|) { * }
  13. multi sub POSITIONS(
  14. \SELF,
  15. \pos,
  16. Callable :$eagerize = -> $idx {
  17. nqp::if(
  18. nqp::istype($idx,Whatever),
  19. nqp::if(nqp::isconcrete(SELF),SELF.elems,0),
  20. SELF.EXISTS-POS($idx)
  21. )
  22. }
  23. ) {
  24. my class IndicesReificationTarget {
  25. has $!target;
  26. has $!star;
  27. method new(\target, \star) {
  28. my \rt = nqp::create(self);
  29. nqp::bindattr(rt, self, '$!target', target);
  30. nqp::bindattr(rt, self, '$!star', star);
  31. rt
  32. }
  33. method push(Mu \value) {
  34. nqp::if(
  35. nqp::istype(value,Callable),
  36. nqp::stmts(
  37. nqp::if(
  38. nqp::istype($!star,Callable),
  39. nqp::bindattr(self,IndicesReificationTarget,'$!star',$!star(*))
  40. ),
  41. # just using value(...) causes stage optimize to die
  42. (my &whatever := value),
  43. nqp::if(
  44. &whatever.count == Inf,
  45. nqp::push($!target, whatever(+$!star)),
  46. nqp::push($!target, whatever(|(+$!star xx &whatever.count)))
  47. )
  48. ),
  49. nqp::push($!target,value)
  50. )
  51. }
  52. }
  53. my \pos-iter = pos.iterator;
  54. my \pos-list = nqp::create(List);
  55. my \eager-indices = nqp::create(IterationBuffer);
  56. my \target = IndicesReificationTarget.new(eager-indices, $eagerize);
  57. nqp::bindattr(pos-list, List, '$!reified', eager-indices);
  58. unless pos-iter.push-until-lazy(target) =:= IterationEnd {
  59. # There are lazy positions to care about too. We truncate at the first
  60. # one that fails to exists.
  61. my \rest-seq = Seq.new(pos-iter).flatmap: -> Int() $i {
  62. nqp::unless(
  63. $eagerize($i),
  64. last,
  65. $i
  66. )
  67. };
  68. my \todo := nqp::create(List::Reifier);
  69. nqp::bindattr(todo, List::Reifier, '$!reified', eager-indices);
  70. nqp::bindattr(todo, List::Reifier, '$!current-iter', rest-seq.iterator);
  71. nqp::bindattr(todo, List::Reifier, '$!reification-target', eager-indices);
  72. nqp::bindattr(pos-list, List, '$!todo', todo);
  73. }
  74. pos-list
  75. }
  76. proto sub postcircumfix:<[ ]>(|) is nodal { * }
  77. multi sub postcircumfix:<[ ]>( \SELF, Any:U $type, |c ) is raw {
  78. die "Indexing requires an instance, tried to do: {try SELF.VAR.name}[ {$type.gist} ]";
  79. }
  80. # @a[int 1]
  81. multi sub postcircumfix:<[ ]>( \SELF, int $pos ) is raw {
  82. SELF.AT-POS($pos);
  83. }
  84. multi sub postcircumfix:<[ ]>( \SELF, int $pos, Mu \assignee ) is raw {
  85. SELF.ASSIGN-POS($pos, assignee);
  86. }
  87. multi sub postcircumfix:<[ ]>(\SELF, int $pos, Mu :$BIND! is raw) is raw {
  88. SELF.BIND-POS($pos, $BIND);
  89. }
  90. multi sub postcircumfix:<[ ]>( \SELF, int $pos, :$delete!, *%other ) is raw {
  91. $delete && nqp::not_i(nqp::elems(nqp::getattr(%other,Map,'$!storage')))
  92. ?? SELF.DELETE-POS($pos)
  93. !! SLICE_ONE_LIST( SELF, $pos, 'delete', $delete, %other );
  94. }
  95. multi sub postcircumfix:<[ ]>( \SELF, int $pos, :$exists!, *%other ) is raw {
  96. $exists && nqp::not_i(nqp::elems(nqp::getattr(%other,Map,'$!storage')))
  97. ?? SELF.EXISTS-POS($pos)
  98. !! SLICE_ONE_LIST( SELF, $pos, 'exists', $exists, %other );
  99. }
  100. multi sub postcircumfix:<[ ]>( \SELF, int $pos, :$kv!, *%other ) is raw {
  101. $kv && nqp::not_i(nqp::elems(nqp::getattr(%other,Map,'$!storage')))
  102. ?? (SELF.EXISTS-POS($pos) ?? ($pos, SELF.AT-POS($pos)) !! ())
  103. !! SLICE_ONE_LIST( SELF, $pos, 'kv', $kv, %other );
  104. }
  105. multi sub postcircumfix:<[ ]>( \SELF, int $pos, :$p!, *%other ) is raw {
  106. $p && nqp::not_i(nqp::elems(nqp::getattr(%other,Map,'$!storage')))
  107. ?? (SELF.EXISTS-POS($pos) ?? Pair.new($pos,SELF.AT-POS($pos)) !! ())
  108. !! SLICE_ONE_LIST( SELF, $pos, 'p', $p, %other );
  109. }
  110. multi sub postcircumfix:<[ ]>( \SELF, int $pos, :$k!, *%other ) is raw {
  111. $k && nqp::not_i(nqp::elems(nqp::getattr(%other,Map,'$!storage')))
  112. ?? (SELF.EXISTS-POS($pos) ?? $pos !! ())
  113. !! SLICE_ONE_LIST( SELF, $pos, 'k', $k, %other );
  114. }
  115. multi sub postcircumfix:<[ ]>( \SELF, int $pos, :$v!, *%other ) is raw {
  116. $v && nqp::not_i(nqp::elems(nqp::getattr(%other,Map,'$!storage')))
  117. ?? (SELF.EXISTS-POS($pos) ?? nqp::decont(SELF.AT-POS($pos)) !! ())
  118. !! SLICE_ONE_LIST( SELF, $pos, 'v', $v, %other );
  119. }
  120. # @a[Int 1]
  121. multi sub postcircumfix:<[ ]>( \SELF, Int:D $pos ) is raw {
  122. SELF.AT-POS($pos);
  123. }
  124. multi sub postcircumfix:<[ ]>( \SELF, Int:D $pos, Mu \assignee ) is raw {
  125. SELF.ASSIGN-POS($pos, assignee);
  126. }
  127. multi sub postcircumfix:<[ ]>(\SELF, Int:D $pos, Mu :$BIND! is raw) is raw {
  128. SELF.BIND-POS($pos, $BIND);
  129. }
  130. multi sub postcircumfix:<[ ]>( \SELF, Int:D $pos, :$delete!, *%other ) is raw {
  131. $delete && nqp::not_i(nqp::elems(nqp::getattr(%other,Map,'$!storage')))
  132. ?? SELF.DELETE-POS($pos)
  133. !! SLICE_ONE_LIST( SELF, $pos, 'delete', $delete, %other );
  134. }
  135. multi sub postcircumfix:<[ ]>( \SELF, Int:D $pos, :$exists!, *%other ) is raw {
  136. $exists && nqp::not_i(nqp::elems(nqp::getattr(%other,Map,'$!storage')))
  137. ?? SELF.EXISTS-POS($pos)
  138. !! SLICE_ONE_LIST( SELF, $pos, 'exists', $exists, %other );
  139. }
  140. multi sub postcircumfix:<[ ]>( \SELF, Int:D $pos, :$kv!, *%other ) is raw {
  141. $kv && nqp::not_i(nqp::elems(nqp::getattr(%other,Map,'$!storage')))
  142. ?? (SELF.EXISTS-POS($pos) ?? ($pos, SELF.AT-POS($pos)) !! ())
  143. !! SLICE_ONE_LIST( SELF, $pos, 'kv', $kv, %other );
  144. }
  145. multi sub postcircumfix:<[ ]>( \SELF, Int:D $pos, :$p!, *%other ) is raw {
  146. $p && nqp::not_i(nqp::elems(nqp::getattr(%other,Map,'$!storage')))
  147. ?? (SELF.EXISTS-POS($pos) ?? Pair.new($pos,SELF.AT-POS($pos)) !! ())
  148. !! SLICE_ONE_LIST( SELF, $pos, 'p', $p, %other );
  149. }
  150. multi sub postcircumfix:<[ ]>( \SELF, Int:D $pos, :$k!, *%other ) is raw {
  151. $k && nqp::not_i(nqp::elems(nqp::getattr(%other,Map,'$!storage')))
  152. ?? (SELF.EXISTS-POS($pos) ?? $pos !! ())
  153. !! SLICE_ONE_LIST( SELF, $pos, 'k', $k, %other );
  154. }
  155. multi sub postcircumfix:<[ ]>( \SELF, Int:D $pos, :$v!, *%other ) is raw {
  156. $v && nqp::not_i(nqp::elems(nqp::getattr(%other,Map,'$!storage')))
  157. ?? (SELF.EXISTS-POS($pos) ?? nqp::decont(SELF.AT-POS($pos)) !! ())
  158. !! SLICE_ONE_LIST( SELF, $pos, 'v', $v, %other );
  159. }
  160. # @a[$x]
  161. multi sub postcircumfix:<[ ]>( \SELF, Any:D \pos ) is raw {
  162. SELF.AT-POS(pos.Int);
  163. }
  164. multi sub postcircumfix:<[ ]>( \SELF, Any:D \pos, Mu \assignee ) is raw {
  165. SELF.ASSIGN-POS(pos.Int, assignee);
  166. }
  167. multi sub postcircumfix:<[ ]>(\SELF, Any:D \pos, Mu :$BIND! is raw) is raw {
  168. SELF.BIND-POS(pos.Int, $BIND);
  169. }
  170. multi sub postcircumfix:<[ ]>( \SELF, Any:D \pos, :$delete!, *%other ) is raw {
  171. $delete && nqp::not_i(nqp::elems(nqp::getattr(%other,Map,'$!storage')))
  172. ?? SELF.DELETE-POS(pos.Int)
  173. !! SLICE_ONE_LIST( SELF, pos.Int, 'delete', $delete, %other );
  174. }
  175. multi sub postcircumfix:<[ ]>( \SELF, Any:D \pos, :$exists!, *%other ) is raw {
  176. $exists && nqp::not_i(nqp::elems(nqp::getattr(%other,Map,'$!storage')))
  177. ?? SELF.EXISTS-POS(pos.Int)
  178. !! SLICE_ONE_LIST( SELF, pos.Int, 'exists', $exists, %other );
  179. }
  180. multi sub postcircumfix:<[ ]>( \SELF, Any:D \pos, :$kv!, *%other ) is raw {
  181. $kv && nqp::not_i(nqp::elems(nqp::getattr(%other,Map,'$!storage')))
  182. ?? (SELF.EXISTS-POS(pos.Int) ?? (pos, SELF.AT-POS(pos.Int)) !! ())
  183. !! SLICE_ONE_LIST( SELF, pos.Int, 'kv', $kv, %other );
  184. }
  185. multi sub postcircumfix:<[ ]>( \SELF, Any:D \pos, :$p!, *%other ) is raw {
  186. $p && nqp::not_i(nqp::elems(nqp::getattr(%other,Map,'$!storage')))
  187. ?? (SELF.EXISTS-POS(pos.Int) ?? Pair.new(pos, SELF.AT-POS(pos.Int)) !! ())
  188. !! SLICE_ONE_LIST( SELF, pos.Int, 'p', $p, %other );
  189. }
  190. multi sub postcircumfix:<[ ]>( \SELF, Any:D \pos, :$k!, *%other ) is raw {
  191. $k && nqp::not_i(nqp::elems(nqp::getattr(%other,Map,'$!storage')))
  192. ?? (SELF.EXISTS-POS(pos.Int) ?? pos !! ())
  193. !! SLICE_ONE_LIST( SELF, pos.Int, 'k', $k, %other );
  194. }
  195. multi sub postcircumfix:<[ ]>( \SELF, Any:D \pos, :$v!, *%other ) is raw {
  196. $v && nqp::not_i(nqp::elems(nqp::getattr(%other,Map,'$!storage')))
  197. ?? (SELF.EXISTS-POS(pos.Int) ?? nqp::decont(SELF.AT-POS(pos.Int)) !! ())
  198. !! SLICE_ONE_LIST( SELF, pos.Int, 'v', $v, %other );
  199. }
  200. # @a[@i]
  201. multi sub postcircumfix:<[ ]>( \SELF, Iterable:D \pos ) is raw {
  202. nqp::iscont(pos)
  203. ?? SELF.AT-POS(pos.Int)
  204. !! POSITIONS(SELF, pos).map({ SELF[$_] }).eager.list;
  205. }
  206. multi sub postcircumfix:<[ ]>(\SELF, Iterable:D \pos, Mu \val ) is raw {
  207. # MMD is not behaving itself so we do this by hand.
  208. if nqp::iscont(pos) {
  209. return SELF[pos.Int] = val;
  210. }
  211. # Prep an iterator that will assign Nils past end of rval
  212. my \rvlist :=
  213. do if nqp::iscont(val)
  214. or not nqp::istype(val, Iterator)
  215. and not nqp::istype(val, Iterable) {
  216. (nqp::decont(val),).Slip
  217. }
  218. elsif nqp::istype(val, Iterator) {
  219. Slip.from-loop({ nqp::decont(val.pull-one) })
  220. }
  221. elsif nqp::istype(val, Iterable) {
  222. val.map({ nqp::decont($_) }).Slip
  223. }, (Nil xx Inf).Slip;
  224. if nqp::istype(SELF, Positional) {
  225. # For Positionals, preserve established/expected evaluation order.
  226. my $list := List.new;
  227. my $target := nqp::getattr($list,List,'$!reified');
  228. # We try to reify indices eagerly first, in case doing so
  229. # manipulates SELF. If pos is lazy or contains Whatevers/closures,
  230. # the SELF may start to reify as well.
  231. my \indices := POSITIONS(SELF, pos);
  232. indices.iterator.sink-all;
  233. # Extract the values/containers which will be assigned to, in case
  234. # reifying the rhs does crazy things like splicing SELF.
  235. my int $p = -1;
  236. nqp::bindpos($target,++$p,SELF[$_]) for indices;
  237. rvlist.EXISTS-POS($p);
  238. my \rviter := rvlist.iterator;
  239. $p = -1;
  240. my $elems = nqp::elems($target);
  241. nqp::atpos($target,$p) = rviter.pull-one
  242. while nqp::islt_i(++$p,$elems);
  243. $list
  244. }
  245. else { # The assumption for now is this must be Iterable
  246. # Lazy list assignment. This is somewhat experimental and
  247. # semantics may change.
  248. my $target := SELF.iterator;
  249. my sub eagerize ($idx) {
  250. once $target := $target.cache.iterator;
  251. $idx ~~ Whatever ?? $target.elems !! $target.EXISTS-POS($idx);
  252. }
  253. my @poslist := POSITIONS(SELF, pos, :eagerize(&eagerize)).eager;
  254. my %keep;
  255. # TODO: we could also use a quanthash and count occurences of an
  256. # index to let things go to GC sooner.
  257. %keep{@poslist} = ();
  258. my $max = -1;
  259. my \rviter := rvlist.iterator;
  260. @poslist.map: -> $p {
  261. my $lv;
  262. for $max ^.. $p -> $i {
  263. $max = $i;
  264. my $lv := $target.pull-one;
  265. %keep{$i} := $lv
  266. if %keep{$i}:exists and !($lv =:= IterationEnd);
  267. }
  268. $lv := %keep{$p};
  269. $lv = rviter.pull-one;
  270. };
  271. }
  272. }
  273. multi sub postcircumfix:<[ ]>(\SELF, Iterable:D \pos, :$BIND!) is raw {
  274. X::Bind::Slice.new(type => SELF.WHAT).throw;
  275. }
  276. multi sub postcircumfix:<[ ]>(\SELF, Iterable:D \pos,:$delete!,*%other) is raw {
  277. nqp::iscont(pos)
  278. ?? SLICE_ONE_LIST( SELF, pos.Int, 'delete', $delete, %other )
  279. !! SLICE_MORE_LIST(SELF,POSITIONS(SELF,pos),'delete',$delete,%other)
  280. }
  281. multi sub postcircumfix:<[ ]>(\SELF, Iterable:D \pos,:$exists!,*%other) is raw {
  282. nqp::iscont(pos)
  283. ?? SLICE_ONE_LIST( SELF, pos.Int, 'exists', $exists, %other )
  284. !! SLICE_MORE_LIST(SELF,POSITIONS(SELF,pos),'exists',$exists,%other)
  285. }
  286. multi sub postcircumfix:<[ ]>(\SELF, Iterable:D \pos, :$kv!, *%other) is raw {
  287. nqp::iscont(pos)
  288. ?? SLICE_ONE_LIST( SELF, pos.Int, 'kv', $kv, %other )
  289. !! SLICE_MORE_LIST(SELF,POSITIONS(SELF,pos),'kv',$kv,%other)
  290. }
  291. multi sub postcircumfix:<[ ]>(\SELF, Iterable:D \pos, :$p!, *%other) is raw {
  292. nqp::iscont(pos)
  293. ?? SLICE_ONE_LIST( SELF, pos.Int, 'p', $p, %other )
  294. !! SLICE_MORE_LIST(SELF,POSITIONS(SELF,pos),'p',$p,%other)
  295. }
  296. multi sub postcircumfix:<[ ]>(\SELF, Iterable:D \pos, :$k!, *%other) is raw {
  297. nqp::iscont(pos)
  298. ?? SLICE_ONE_LIST( SELF, pos.Int, 'k', $k, %other )
  299. !! SLICE_MORE_LIST(SELF,POSITIONS(SELF,pos),'k',$k,%other)
  300. }
  301. multi sub postcircumfix:<[ ]>(\SELF, Iterable:D \pos, :$v!, *%other) is raw {
  302. nqp::iscont(pos)
  303. ?? SLICE_ONE_LIST( SELF, pos.Int, 'v', $v, %other )
  304. !! SLICE_MORE_LIST(SELF,POSITIONS(SELF,pos),'v',$v,%other)
  305. }
  306. # @a[->{}]
  307. multi sub postcircumfix:<[ ]>(\SELF, Callable:D $block ) is raw {
  308. nqp::stmts(
  309. (my $*INDEX = 'Effective index'),
  310. SELF[$block.pos(SELF)]
  311. )
  312. }
  313. multi sub postcircumfix:<[ ]>(\SELF, Callable:D $block, Mu \assignee ) is raw {
  314. nqp::stmts(
  315. (my $*INDEX = 'Effective index'),
  316. SELF[$block.pos(SELF)] = assignee
  317. )
  318. }
  319. multi sub postcircumfix:<[ ]>(\SELF, Callable:D $block, :$BIND!) is raw {
  320. X::Bind::Slice.new(type => SELF.WHAT).throw;
  321. }
  322. multi sub postcircumfix:<[ ]>(\SELF,Callable:D $block,:$delete!,*%other) is raw {
  323. nqp::stmts(
  324. (my $*INDEX = 'Effective index'),
  325. nqp::if(
  326. nqp::istype((my $pos := $block.pos(SELF)),Int),
  327. SLICE_ONE_LIST( SELF, $pos, 'delete', $delete, %other ),
  328. SLICE_MORE_LIST( SELF, @$pos, 'delete', $delete, %other )
  329. )
  330. )
  331. }
  332. multi sub postcircumfix:<[ ]>(\SELF,Callable:D $block,:$exists!,*%other) is raw {
  333. nqp::stmts(
  334. (my $*INDEX = 'Effective index'),
  335. nqp::if(
  336. nqp::istype((my $pos := $block.pos(SELF)),Int),
  337. SLICE_ONE_LIST( SELF, $pos, 'exists', $exists, %other ),
  338. SLICE_MORE_LIST( SELF, @$pos, 'exists', $exists, %other )
  339. )
  340. )
  341. }
  342. multi sub postcircumfix:<[ ]>(\SELF,Callable:D $block,:$kv!,*%other) is raw {
  343. nqp::stmts(
  344. (my $*INDEX = 'Effective index'),
  345. nqp::if(
  346. nqp::istype((my $pos := $block.pos(SELF)),Int),
  347. SLICE_ONE_LIST( SELF, $pos, 'kv', $kv, %other ),
  348. SLICE_MORE_LIST( SELF, @$pos, 'kv', $kv, %other )
  349. )
  350. )
  351. }
  352. multi sub postcircumfix:<[ ]>(\SELF,Callable:D $block,:$p!,*%other) is raw {
  353. nqp::stmts(
  354. (my $*INDEX = 'Effective index'),
  355. nqp::if(
  356. nqp::istype((my $pos := $block.pos(SELF)),Int),
  357. SLICE_ONE_LIST( SELF, $pos, 'p', $p, %other ),
  358. SLICE_MORE_LIST( SELF, @$pos, 'p', $p, %other )
  359. )
  360. )
  361. }
  362. multi sub postcircumfix:<[ ]>(\SELF,Callable:D $block,:$k!,*%other) is raw {
  363. nqp::stmts(
  364. (my $*INDEX = 'Effective index'),
  365. nqp::if(
  366. nqp::istype((my $pos := $block.pos(SELF)),Int),
  367. SLICE_ONE_LIST( SELF, $pos, 'k', $k, %other ),
  368. SLICE_MORE_LIST( SELF, @$pos, 'k', $k, %other )
  369. )
  370. )
  371. }
  372. multi sub postcircumfix:<[ ]>(\SELF,Callable:D $block,:$v!,*%other) is raw {
  373. nqp::stmts(
  374. (my $*INDEX = 'Effective index'),
  375. nqp::if(
  376. nqp::istype((my $pos := $block.pos(SELF)),Int),
  377. SLICE_ONE_LIST( SELF, $pos, 'v', $v, %other ),
  378. SLICE_MORE_LIST( SELF, @$pos, 'v', $v, %other )
  379. )
  380. )
  381. }
  382. # @a[*]
  383. multi sub postcircumfix:<[ ]>( \SELF, Whatever:D ) is raw {
  384. SELF[^SELF.elems];
  385. }
  386. multi sub postcircumfix:<[ ]>( \SELF, Whatever:D, Mu \assignee ) is raw {
  387. SELF[^SELF.elems] = assignee;
  388. }
  389. multi sub postcircumfix:<[ ]>(\SELF, Whatever:D, :$BIND!) is raw {
  390. X::Bind::Slice.new(type => SELF.WHAT).throw;
  391. }
  392. multi sub postcircumfix:<[ ]>(\SELF, Whatever:D, :$delete!, *%other) is raw {
  393. SLICE_MORE_LIST( SELF, ^SELF.elems, 'delete', $delete, %other );
  394. }
  395. multi sub postcircumfix:<[ ]>(\SELF, Whatever:D, :$exists!, *%other) is raw {
  396. SLICE_MORE_LIST( SELF, ^SELF.elems, 'exists', $exists, %other );
  397. }
  398. multi sub postcircumfix:<[ ]>(\SELF, Whatever:D, :$kv!, *%other) is raw {
  399. SLICE_MORE_LIST( SELF, ^SELF.elems, 'kv', $kv, %other );
  400. }
  401. multi sub postcircumfix:<[ ]>(\SELF, Whatever:D, :$p!, *%other) is raw {
  402. SLICE_MORE_LIST( SELF, ^SELF.elems, 'p', $p, %other );
  403. }
  404. multi sub postcircumfix:<[ ]>(\SELF, Whatever:D, :$k!, *%other) is raw {
  405. SLICE_MORE_LIST( SELF, ^SELF.elems, 'k', $k, %other );
  406. }
  407. multi sub postcircumfix:<[ ]>(\SELF, Whatever:D, :$v!, *%other) is raw {
  408. nqp::elems(nqp::getattr(%other,Map,'$!storage'))
  409. ?? SLICE_MORE_LIST( SELF, ^SELF.elems, 'v', $v, %other )
  410. !! SELF[^SELF.elems];
  411. }
  412. # @a[**]
  413. multi sub postcircumfix:<[ ]>(\SELF, HyperWhatever:D $, *%adv) is raw {
  414. X::NYI.new(feature => 'HyperWhatever in array index').throw;
  415. }
  416. multi sub postcircumfix:<[ ]>(\SELF, HyperWhatever:D $, Mu \assignee) is raw {
  417. X::NYI.new(feature => 'HyperWhatever in array index').throw;
  418. }
  419. # @a[]
  420. multi sub postcircumfix:<[ ]>(\SELF, :$BIND!) is raw {
  421. X::Bind::ZenSlice.new(type => SELF.WHAT).throw;
  422. }
  423. multi sub postcircumfix:<[ ]>(\SELF, :$delete!, *%other) is raw {
  424. SLICE_MORE_LIST( SELF, ^SELF.elems, 'delete', $delete, %other );
  425. }
  426. multi sub postcircumfix:<[ ]>(\SELF, :$exists!, *%other) is raw {
  427. SLICE_MORE_LIST( SELF, ^SELF.elems, 'exists', $exists, %other );
  428. }
  429. multi sub postcircumfix:<[ ]>(\SELF, :$kv!, *%other) is raw {
  430. SLICE_MORE_LIST( SELF, ^SELF.elems, 'kv', $kv, %other );
  431. }
  432. multi sub postcircumfix:<[ ]>(\SELF, :$p!, *%other) is raw {
  433. SLICE_MORE_LIST( SELF, ^SELF.elems, 'p', $p, %other );
  434. }
  435. multi sub postcircumfix:<[ ]>(\SELF, :$k!, *%other) is raw {
  436. SLICE_MORE_LIST( SELF, ^SELF.elems, 'k', $k, %other );
  437. }
  438. multi sub postcircumfix:<[ ]>(\SELF, :$v!, *%other) is raw {
  439. nqp::elems(nqp::getattr(%other,Map,'$!storage'))
  440. ?? SLICE_MORE_LIST( SELF, ^SELF.elems, 'v', $v, %other )
  441. !! SELF[^SELF.elems];
  442. }
  443. multi sub postcircumfix:<[ ]>(\SELF, *%other) is raw {
  444. SELF.ZEN-POS(|%other);
  445. }