1. # all sub postcircumfix [;] candidates here please
  2. proto sub postcircumfix:<[; ]>(|) is nodal { * }
  3. sub MD-ARRAY-SLICE-ONE-POSITION(\SELF, \indices, \idx, int $dim, \target) is raw {
  4. my int $next-dim = $dim + 1;
  5. if $next-dim < indices.elems {
  6. if nqp::istype(idx, Iterable) && !nqp::iscont(idx) {
  7. for idx {
  8. MD-ARRAY-SLICE-ONE-POSITION(SELF, indices, $_, $dim, target)
  9. }
  10. }
  11. elsif nqp::istype(idx, Int) {
  12. MD-ARRAY-SLICE-ONE-POSITION(SELF.AT-POS(idx), indices, indices.AT-POS($next-dim), $next-dim, target)
  13. }
  14. elsif nqp::istype(idx, Whatever) {
  15. for ^SELF.elems {
  16. MD-ARRAY-SLICE-ONE-POSITION(SELF.AT-POS($_), indices, indices.AT-POS($next-dim), $next-dim, target)
  17. }
  18. }
  19. elsif nqp::istype(idx, Callable) {
  20. MD-ARRAY-SLICE-ONE-POSITION(SELF, indices, idx.(|(SELF.elems xx (idx.count == Inf ?? 1 !! idx.count))), $dim, target);
  21. }
  22. else {
  23. MD-ARRAY-SLICE-ONE-POSITION(SELF.AT-POS(idx.Int), indices, indices.AT-POS($next-dim), $next-dim, target)
  24. }
  25. }
  26. else {
  27. if nqp::istype(idx, Iterable) && !nqp::iscont(idx) {
  28. for idx {
  29. MD-ARRAY-SLICE-ONE-POSITION(SELF, indices, $_, $dim, target)
  30. }
  31. }
  32. elsif nqp::istype(idx, Int) {
  33. nqp::push(target, SELF.AT-POS(idx))
  34. }
  35. elsif nqp::istype(idx, Whatever) {
  36. for ^SELF.elems {
  37. nqp::push(target, SELF.AT-POS($_))
  38. }
  39. }
  40. elsif nqp::istype(idx, Callable) {
  41. nqp::push(target, SELF.AT-POS(idx.(|(SELF.elems xx (idx.count == Inf ?? 1 !! idx.count)))))
  42. }
  43. else {
  44. nqp::push(target, SELF.AT-POS(idx.Int))
  45. }
  46. }
  47. }
  48. sub MD-ARRAY-SLICE(\SELF, @indices) is raw {
  49. my \target = IterationBuffer.new;
  50. MD-ARRAY-SLICE-ONE-POSITION(SELF, @indices, @indices.AT-POS(0), 0, target);
  51. nqp::p6bindattrinvres(nqp::create(List), List, '$!reified', target)
  52. }
  53. multi sub postcircumfix:<[; ]>(\SELF, @indices) is raw {
  54. nqp::stmts(
  55. (my $indices := nqp::getattr(@indices,List,'$!reified')),
  56. (my int $elems = nqp::elems($indices)),
  57. (my int $i = -1),
  58. nqp::while(
  59. nqp::islt_i(($i = nqp::add_i($i,1)),$elems)
  60. && nqp::istype(nqp::atpos($indices,$i),Int),
  61. nqp::null
  62. ),
  63. nqp::if(
  64. nqp::islt_i($i,$elems),
  65. MD-ARRAY-SLICE(SELF,@indices),
  66. nqp::if(
  67. nqp::iseq_i($elems,2),
  68. SELF.AT-POS(
  69. nqp::atpos($indices,0),
  70. nqp::atpos($indices,1)
  71. ),
  72. nqp::if(
  73. nqp::iseq_i($elems,3),
  74. SELF.AT-POS(
  75. nqp::atpos($indices,0),
  76. nqp::atpos($indices,1),
  77. nqp::atpos($indices,2)
  78. ),
  79. SELF.AT-POS(|@indices)
  80. )
  81. )
  82. )
  83. )
  84. }
  85. multi sub postcircumfix:<[; ]>(\SELF, @indices, Mu \assignee) is raw {
  86. nqp::stmts(
  87. (my int $elems = @indices.elems), # reifies
  88. (my $indices := nqp::getattr(@indices,List,'$!reified')),
  89. (my int $i = -1),
  90. nqp::while(
  91. nqp::islt_i(($i = nqp::add_i($i,1)),$elems)
  92. && nqp::istype(nqp::atpos($indices,$i),Int),
  93. nqp::null
  94. ),
  95. nqp::if(
  96. nqp::islt_i($i,$elems),
  97. (MD-ARRAY-SLICE(SELF,@indices) = assignee),
  98. nqp::if(
  99. nqp::iseq_i($elems,2),
  100. SELF.ASSIGN-POS(
  101. nqp::atpos($indices,0),
  102. nqp::atpos($indices,1),
  103. assignee
  104. ),
  105. nqp::if(
  106. nqp::iseq_i($elems,3),
  107. SELF.ASSIGN-POS(
  108. nqp::atpos($indices,0),
  109. nqp::atpos($indices,1),
  110. nqp::atpos($indices,2),
  111. assignee
  112. ),
  113. SELF.ASSIGN-POS(|@indices,assignee)
  114. )
  115. )
  116. )
  117. )
  118. }
  119. multi sub postcircumfix:<[; ]>(\SELF, @indices, :$BIND!) is raw {
  120. nqp::stmts(
  121. (my int $elems = @indices.elems), # reifies
  122. (my $indices := nqp::getattr(@indices,List,'$!reified')),
  123. (my int $i = -1),
  124. nqp::while(
  125. nqp::islt_i(($i = nqp::add_i($i,1)),$elems)
  126. && nqp::istype(nqp::atpos($indices,$i),Int),
  127. nqp::null
  128. ),
  129. nqp::if(
  130. nqp::islt_i($i,$elems),
  131. X::Bind::Slice.new(type => SELF.WHAT).throw,
  132. nqp::if(
  133. nqp::iseq_i($elems,2),
  134. SELF.BIND-POS(
  135. nqp::atpos($indices,0),
  136. nqp::atpos($indices,1),
  137. $BIND
  138. ),
  139. nqp::if(
  140. nqp::iseq_i($elems,3),
  141. SELF.BIND-POS(
  142. nqp::atpos($indices,0),
  143. nqp::atpos($indices,1),
  144. nqp::atpos($indices,2),
  145. $BIND
  146. ),
  147. SELF.BIND-POS(|@indices, $BIND)
  148. )
  149. )
  150. )
  151. )
  152. }
  153. multi sub postcircumfix:<[; ]>(\SELF, @indices, :$delete!) is raw {
  154. nqp::if(
  155. $delete,
  156. nqp::stmts(
  157. (my int $elems = @indices.elems), # reifies
  158. (my $indices := nqp::getattr(@indices,List,'$!reified')),
  159. (my int $i = -1),
  160. nqp::while(
  161. nqp::islt_i(($i = nqp::add_i($i,1)),$elems)
  162. && nqp::istype(nqp::atpos($indices,$i),Int),
  163. nqp::null
  164. ),
  165. nqp::if(
  166. nqp::islt_i($i,$elems),
  167. Failure.new(X::NYI.new(
  168. feature => ':delete on multi-dimensional slices')),
  169. nqp::if(
  170. nqp::iseq_i($elems,2),
  171. SELF.DELETE-POS(
  172. nqp::atpos($indices,0),
  173. nqp::atpos($indices,1)
  174. ),
  175. nqp::if(
  176. nqp::iseq_i($elems,3),
  177. SELF.DELETE-POS(
  178. nqp::atpos($indices,0),
  179. nqp::atpos($indices,1),
  180. nqp::atpos($indices,2)
  181. ),
  182. SELF.DELETE-POS(|@indices)
  183. )
  184. )
  185. )
  186. ),
  187. postcircumfix:<[; ]>(SELF, @indices)
  188. )
  189. }
  190. multi sub postcircumfix:<[; ]>(\SELF, @indices, :$exists!) is raw {
  191. nqp::if(
  192. $exists,
  193. nqp::stmts(
  194. (my int $elems = @indices.elems), # reifies
  195. (my $indices := nqp::getattr(@indices,List,'$!reified')),
  196. (my int $i = -1),
  197. nqp::while(
  198. nqp::islt_i(($i = nqp::add_i($i,1)),$elems)
  199. && nqp::istype(nqp::atpos($indices,$i),Int),
  200. nqp::null
  201. ),
  202. nqp::if(
  203. nqp::islt_i($i,$elems),
  204. Failure.new(X::NYI.new(
  205. feature => ':exists on multi-dimensional slices')),
  206. nqp::if(
  207. nqp::iseq_i($elems,2),
  208. SELF.EXISTS-POS(
  209. nqp::atpos($indices,0),
  210. nqp::atpos($indices,1)
  211. ),
  212. nqp::if(
  213. nqp::iseq_i($elems,3),
  214. SELF.EXISTS-POS(
  215. nqp::atpos($indices,0),
  216. nqp::atpos($indices,1),
  217. nqp::atpos($indices,2)
  218. ),
  219. SELF.EXISTS-POS(|@indices)
  220. )
  221. )
  222. )
  223. ),
  224. postcircumfix:<[; ]>(SELF, @indices)
  225. )
  226. }
  227. multi sub postcircumfix:<[; ]>(\SELF, @indices, :$kv!) is raw {
  228. nqp::if(
  229. $kv,
  230. nqp::stmts(
  231. (my int $elems = @indices.elems), # reifies
  232. (my $indices := nqp::getattr(@indices,List,'$!reified')),
  233. (my int $i = -1),
  234. nqp::while(
  235. nqp::islt_i(($i = nqp::add_i($i,1)),$elems)
  236. && nqp::istype(nqp::atpos($indices,$i),Int),
  237. nqp::null
  238. ),
  239. nqp::if(
  240. nqp::islt_i($i,$elems),
  241. Failure.new(X::NYI.new(
  242. feature => ':kv on multi-dimensional slices')),
  243. nqp::if(
  244. nqp::iseq_i($elems,2),
  245. nqp::if(
  246. SELF.EXISTS-POS(
  247. nqp::atpos($indices,0),
  248. nqp::atpos($indices,1)
  249. ),
  250. (@indices, SELF.AT-POS(
  251. nqp::atpos($indices,0),
  252. nqp::atpos($indices,1)
  253. )),
  254. ()
  255. ),
  256. nqp::if(
  257. nqp::iseq_i($elems,3),
  258. nqp::if(
  259. SELF.EXISTS-POS(
  260. nqp::atpos($indices,0),
  261. nqp::atpos($indices,1),
  262. nqp::atpos($indices,2)
  263. ),
  264. (@indices, SELF.AT-POS(
  265. nqp::atpos($indices,0),
  266. nqp::atpos($indices,1),
  267. nqp::atpos($indices,2)
  268. )),
  269. ()
  270. ),
  271. nqp::if(
  272. SELF.EXISTS-POS(|@indices),
  273. (@indices, SELF.AT-POS(|@indices)),
  274. ()
  275. )
  276. )
  277. )
  278. )
  279. ),
  280. postcircumfix:<[; ]>(SELF, @indices)
  281. )
  282. }
  283. multi sub postcircumfix:<[; ]>(\SELF, @indices, :$p!) is raw {
  284. nqp::if(
  285. $p,
  286. nqp::stmts(
  287. (my int $elems = @indices.elems), # reifies
  288. (my $indices := nqp::getattr(@indices,List,'$!reified')),
  289. (my int $i = -1),
  290. nqp::while(
  291. nqp::islt_i(($i = nqp::add_i($i,1)),$elems)
  292. && nqp::istype(nqp::atpos($indices,$i),Int),
  293. nqp::null
  294. ),
  295. nqp::if(
  296. nqp::islt_i($i,$elems),
  297. Failure.new(X::NYI.new(
  298. feature => ':p on multi-dimensional slices')),
  299. nqp::if(
  300. nqp::iseq_i($elems,2),
  301. nqp::if(
  302. SELF.EXISTS-POS(
  303. nqp::atpos($indices,0),
  304. nqp::atpos($indices,1)
  305. ),
  306. Pair.new(@indices, SELF.AT-POS(
  307. nqp::atpos($indices,0),
  308. nqp::atpos($indices,1)
  309. )),
  310. ()
  311. ),
  312. nqp::if(
  313. nqp::iseq_i($elems,3),
  314. nqp::if(
  315. SELF.EXISTS-POS(
  316. nqp::atpos($indices,0),
  317. nqp::atpos($indices,1),
  318. nqp::atpos($indices,2)
  319. ),
  320. Pair.new(@indices, SELF.AT-POS(
  321. nqp::atpos($indices,0),
  322. nqp::atpos($indices,1),
  323. nqp::atpos($indices,2)
  324. )),
  325. ()
  326. ),
  327. nqp::if(
  328. SELF.EXISTS-POS(|@indices),
  329. Pair.new(@indices, SELF.AT-POS(|@indices)),
  330. ()
  331. )
  332. )
  333. )
  334. )
  335. ),
  336. postcircumfix:<[; ]>(SELF, @indices)
  337. )
  338. }
  339. multi sub postcircumfix:<[; ]>(\SELF, @indices, :$k!) is raw {
  340. nqp::if(
  341. $k,
  342. nqp::stmts(
  343. (my int $elems = @indices.elems), # reifies
  344. (my $indices := nqp::getattr(@indices,List,'$!reified')),
  345. (my int $i = -1),
  346. nqp::while(
  347. nqp::islt_i(($i = nqp::add_i($i,1)),$elems)
  348. && nqp::istype(nqp::atpos($indices,$i),Int),
  349. nqp::null
  350. ),
  351. nqp::if(
  352. nqp::islt_i($i,$elems),
  353. Failure.new(X::NYI.new(
  354. feature => ':k on multi-dimensional slices')),
  355. nqp::if(
  356. nqp::iseq_i($elems,2),
  357. nqp::if(
  358. SELF.EXISTS-POS(
  359. nqp::atpos($indices,0),
  360. nqp::atpos($indices,1)
  361. ),
  362. @indices,
  363. ()
  364. ),
  365. nqp::if(
  366. nqp::iseq_i($elems,3),
  367. nqp::if(
  368. SELF.EXISTS-POS(
  369. nqp::atpos($indices,0),
  370. nqp::atpos($indices,1),
  371. nqp::atpos($indices,2)
  372. ),
  373. @indices,
  374. ()
  375. ),
  376. nqp::if(
  377. SELF.EXISTS-POS(|@indices),
  378. @indices,
  379. ()
  380. )
  381. )
  382. )
  383. )
  384. ),
  385. postcircumfix:<[; ]>(SELF, @indices)
  386. )
  387. }
  388. multi sub postcircumfix:<[; ]>(\SELF, @indices, :$v!) is raw {
  389. nqp::if(
  390. $v,
  391. nqp::stmts(
  392. (my int $elems = @indices.elems), # reifies
  393. (my $indices := nqp::getattr(@indices,List,'$!reified')),
  394. (my int $i = -1),
  395. nqp::while(
  396. nqp::islt_i(($i = nqp::add_i($i,1)),$elems)
  397. && nqp::istype(nqp::atpos($indices,$i),Int),
  398. nqp::null
  399. ),
  400. nqp::if(
  401. nqp::islt_i($i,$elems),
  402. Failure.new(X::NYI.new(
  403. feature => ':v on multi-dimensional slices')),
  404. nqp::if(
  405. nqp::iseq_i($elems,2),
  406. nqp::if(
  407. SELF.EXISTS-POS(
  408. nqp::atpos($indices,0),
  409. nqp::atpos($indices,1)
  410. ),
  411. nqp::decont(SELF.AT-POS(
  412. nqp::atpos($indices,0),
  413. nqp::atpos($indices,1)
  414. )),
  415. ()
  416. ),
  417. nqp::if(
  418. nqp::iseq_i($elems,3),
  419. nqp::if(
  420. SELF.EXISTS-POS(
  421. nqp::atpos($indices,0),
  422. nqp::atpos($indices,1),
  423. nqp::atpos($indices,2)
  424. ),
  425. nqp::decont(SELF.AT-POS(
  426. nqp::atpos($indices,0),
  427. nqp::atpos($indices,1),
  428. nqp::atpos($indices,2)
  429. )),
  430. ()
  431. ),
  432. nqp::if(
  433. SELF.EXISTS-POS(|@indices),
  434. nqp::decont(SELF.AT-POS(|@indices)),
  435. ()
  436. )
  437. )
  438. )
  439. )
  440. ),
  441. postcircumfix:<[; ]>(SELF, @indices)
  442. )
  443. }