1. my class Pair { ... }
  2. my class Range { ... }
  3. my class Seq { ... }
  4. my class X::Adverb { ... }
  5. my class X::Bind { ... }
  6. my class X::Bind::Slice { ... }
  7. my class X::Bind::ZenSlice { ... }
  8. my class X::Item { ... }
  9. my class X::Match::Bool { ... }
  10. my class X::Pairup::OddNumber { ... }
  11. my class X::Subscript::Negative { ... }
  12. my role Numeric { ... }
  13. my class Any { # declared in BOOTSTRAP
  14. # my class Any is Mu
  15. multi method ACCEPTS(Any:D: Mu:D \a) { self === a }
  16. multi method ACCEPTS(Any:D: Mu:U $ --> False) { }
  17. multi method ACCEPTS(Any:U: Any \topic) { # use of Any on topic to force autothreading
  18. nqp::p6bool(nqp::istype(topic, self)) # so that all(@foo) ~~ Type works as expected
  19. }
  20. proto method EXISTS-KEY(|) is nodal {*}
  21. multi method EXISTS-KEY(Any:U: $ --> False) { }
  22. multi method EXISTS-KEY(Any:D: $ --> False) { }
  23. proto method DELETE-KEY(|) is nodal {*}
  24. multi method DELETE-KEY(Any:U: $ --> Nil) { }
  25. multi method DELETE-KEY(Any:D: $) {
  26. Failure.new("Can not remove values from a {self.^name}")
  27. }
  28. proto method DELETE-POS(|) is nodal {*}
  29. multi method DELETE-POS(Any:U: $pos --> Nil) { }
  30. multi method DELETE-POS(Any:D: $pos) {
  31. Failure.new("Can not remove elements from a {self.^name}")
  32. }
  33. multi method DELETE-POS(Any:D: \one, \two) is raw {
  34. self.AT-POS(one).DELETE-POS(two)
  35. }
  36. multi method DELETE-POS(Any:D: \one, \two, \three) is raw {
  37. self.AT-POS(one).AT-POS(two).DELETE-POS(three)
  38. }
  39. multi method DELETE-POS(Any:D: **@indices) {
  40. my $final := @indices.pop;
  41. Rakudo::Internals.WALK-AT-POS(self,@indices).DELETE-POS($final)
  42. }
  43. method cache() { self.list }
  44. proto method list(|) is nodal {*}
  45. multi method list(Any:U:) { infix:<,>(self) }
  46. multi method list(Any:D \SELF:) { infix:<,>(SELF) }
  47. proto method flat(|) is nodal {*}
  48. multi method flat() { self.list.flat }
  49. proto method eager(|) is nodal {*}
  50. multi method eager() { self.list.eager }
  51. proto method serial(|) is nodal {*}
  52. multi method serial() { self }
  53. # derived from .list
  54. proto method List(|) is nodal {*}
  55. multi method List() { self.list }
  56. proto method Slip(|) is nodal {*}
  57. multi method Slip() { self.list.Slip }
  58. proto method Array(|) is nodal {*}
  59. multi method Array() { self.list.Array }
  60. proto method Seq(|) is nodal {*}
  61. multi method Seq() { Seq.new(self.iterator) }
  62. proto method hash(|) is nodal {*}
  63. multi method hash(Any:U:) { my % = () }
  64. multi method hash(Any:D:) { my % = self }
  65. # derived from .hash
  66. proto method Hash(|) is nodal {*}
  67. multi method Hash() { self.hash.Hash }
  68. proto method Map(|) is nodal {*}
  69. multi method Map() { self.hash.Map }
  70. proto method elems(|) is nodal {*}
  71. multi method elems(Any:U: --> 1) { }
  72. multi method elems(Any:D:) { self.list.elems }
  73. proto method end(|) is nodal {*}
  74. multi method end(Any:U: --> 0) { }
  75. multi method end(Any:D:) { self.list.end }
  76. proto method keys(|) is nodal {*}
  77. multi method keys(Any:U:) { () }
  78. multi method keys(Any:D:) { self.list.keys }
  79. proto method kv(|) is nodal {*}
  80. multi method kv(Any:U:) { () }
  81. multi method kv(Any:D:) { self.list.kv }
  82. proto method values(|) is nodal {*}
  83. multi method values(Any:U:) { () }
  84. multi method values(Any:D:) { self.list }
  85. proto method pairs(|) is nodal {*}
  86. multi method pairs(Any:U:) { () }
  87. multi method pairs(Any:D:) { self.list.pairs }
  88. proto method antipairs(|) is nodal {*}
  89. multi method antipairs(Any:U:) { () }
  90. multi method antipairs(Any:D:) { self.list.antipairs }
  91. proto method invert(|) is nodal {*}
  92. multi method invert(Any:U:) { () }
  93. multi method invert(Any:D:) { self.list.invert }
  94. proto method pick(|) is nodal {*}
  95. multi method pick() { self.list.pick }
  96. multi method pick($n) { self.list.pick($n) }
  97. proto method roll(|) is nodal {*}
  98. multi method roll() { self.list.roll }
  99. multi method roll($n) { self.list.roll($n) }
  100. multi method iterator(Any:) { self.list.iterator }
  101. method match(Any:U: |) { self.Str; nqp::getlexcaller('$/') = Nil }
  102. proto method classify(|) is nodal {*}
  103. multi method classify() {
  104. die "Must specify something to classify with, a Callable, Hash or List";
  105. }
  106. multi method classify(Whatever) {
  107. die "Doesn't make sense to classify with itself";
  108. }
  109. multi method classify($test, :$into!, :&as) {
  110. ( $into // $into.new ).classify-list( $test, self, :&as);
  111. }
  112. multi method classify($test, :&as) {
  113. Hash.^parameterize(Any,Any).new.classify-list( $test, self, :&as );
  114. }
  115. proto method categorize(|) is nodal {*}
  116. multi method categorize() {
  117. die "Must specify something to categorize with, a Callable, Hash or List";
  118. }
  119. multi method categorize(Whatever) {
  120. die "Doesn't make sense to categorize with itself";
  121. }
  122. multi method categorize($test, :$into!, :&as) {
  123. ( $into // $into.new ).categorize-list( $test, self.list, :&as );
  124. }
  125. multi method categorize($test, :&as) {
  126. Hash.^parameterize(Any,Any).new.categorize-list($test, self.list, :&as);
  127. }
  128. method reverse() is nodal { self.list.reverse }
  129. method combinations(|c) is nodal { self.list.combinations(|c) }
  130. method permutations(|c) is nodal { self.list.permutations(|c) }
  131. method join($separator = '') is nodal { self.list.join($separator) }
  132. # XXX GLR should move these
  133. method nodemap(&block) is nodal { nodemap(&block, self) }
  134. method duckmap(&block) is nodal { duckmap(&block, self) }
  135. method deepmap(&block) is nodal { deepmap(&block, self) }
  136. # XXX GLR Do we need tree post-GLR?
  137. proto method tree(|) is nodal {*}
  138. multi method tree(Any:U:) { self }
  139. multi method tree(Any:D:) {
  140. nqp::istype(self, Iterable)
  141. ?? self.map({ .tree }).item
  142. !! self
  143. }
  144. multi method tree(Any:D: Whatever ) { self.tree }
  145. multi method tree(Any:D: Int(Cool) $count) {
  146. nqp::istype(self, Iterable) && $count > 0
  147. ?? self.map({ .tree($count - 1) }).item
  148. !! self
  149. }
  150. multi method tree(Any:D: @ [&first, *@rest]) { self.tree(&first, |@rest); }
  151. multi method tree(Any:D: &first, *@rest) {
  152. nqp::istype(self, Iterable)
  153. ?? @rest ?? first(self.map({ .tree(|@rest) }))
  154. !! first(self)
  155. !! self
  156. }
  157. # auto-vivifying
  158. proto method push(|) is nodal {*}
  159. multi method push(Any:U \SELF: |values) {
  160. SELF = nqp::istype(SELF,Positional) ?? SELF.new !! Array.new;
  161. SELF.push(|values);
  162. }
  163. proto method append(|) is nodal {*}
  164. multi method append(Any:U \SELF: |values) {
  165. SELF = nqp::istype(SELF,Positional) ?? SELF.new !! Array.new;
  166. SELF.append(|values);
  167. }
  168. proto method unshift(|) is nodal {*}
  169. multi method unshift(Any:U \SELF: |values) {
  170. SELF = Array.new;
  171. SELF.unshift(|values);
  172. }
  173. proto method prepend(|) is nodal {*}
  174. multi method prepend(Any:U \SELF: |values) {
  175. SELF = Array.new;
  176. SELF.prepend(|values);
  177. }
  178. proto method EXISTS-POS(|) is nodal {*}
  179. multi method EXISTS-POS(Any:U: Any:D $ --> False) { }
  180. multi method EXISTS-POS(Any:U: Any:U $pos) {
  181. die "Cannot use '{$pos.^name}' as an index";
  182. }
  183. multi method EXISTS-POS(Any:D: int \pos) {
  184. nqp::p6bool(nqp::iseq_i(pos,0));
  185. }
  186. multi method EXISTS-POS(Any:D: Int:D \pos) {
  187. pos == 0;
  188. }
  189. multi method EXISTS-POS(Any:D: Num:D \pos) {
  190. X::Item.new(aggregate => self, index => pos).throw
  191. if nqp::isnanorinf(pos);
  192. self.AT-POS(nqp::unbox_i(pos.Int));
  193. pos == 0;
  194. }
  195. multi method EXISTS-POS(Any:D: Any:D \pos) {
  196. pos.Int == 0;
  197. }
  198. multi method EXISTS-POS(Any:D: Any:U \pos) {
  199. die "Cannot use '{pos.^name}' as an index";
  200. }
  201. multi method EXISTS-POS(Any:D: \one, \two) is raw {
  202. self.AT-POS(one).EXISTS-POS(two)
  203. }
  204. multi method EXISTS-POS(Any:D: \one, \two,\three) is raw {
  205. self.AT-POS(one).AT-POS(two).EXISTS-POS(three)
  206. }
  207. multi method EXISTS-POS(Any:D: **@indices) {
  208. my $final := @indices.pop;
  209. Rakudo::Internals.WALK-AT-POS(self,@indices).EXISTS-POS($final)
  210. }
  211. proto method AT-POS(|) is nodal {*}
  212. multi method AT-POS(Any:U \SELF: int \pos) is raw {
  213. nqp::p6bindattrinvres(
  214. my $scalar,
  215. Scalar,
  216. '$!whence',
  217. -> { nqp::if(
  218. nqp::isconcrete(SELF),
  219. SELF,
  220. (SELF = Array.new)
  221. ).BIND-POS(pos, $scalar)
  222. }
  223. )
  224. }
  225. multi method AT-POS(Any:U \SELF: Int:D \pos) is raw {
  226. nqp::p6bindattrinvres(
  227. my $scalar,
  228. Scalar,
  229. '$!whence',
  230. -> { nqp::if(
  231. nqp::isconcrete(SELF),
  232. SELF,
  233. (SELF = Array.new)
  234. ).BIND-POS(pos, $scalar)
  235. }
  236. )
  237. }
  238. multi method AT-POS(Any:U: Num:D \pos) is raw {
  239. nqp::isnanorinf(pos)
  240. ?? Failure.new(X::Item.new(aggregate => self, index => pos))
  241. !! self.AT-POS(nqp::unbox_i(pos.Int))
  242. }
  243. multi method AT-POS(Any:U: Any:D \pos) is raw {
  244. self.AT-POS(nqp::unbox_i(pos.Int));
  245. }
  246. multi method AT-POS(Any:D: int \pos) is raw {
  247. pos
  248. ?? Failure.new(X::OutOfRange.new(
  249. :what($*INDEX // 'Index'), :got(pos), :range<0..0>))
  250. !! self
  251. }
  252. multi method AT-POS(Any:D: Int:D \pos) is raw {
  253. pos
  254. ?? Failure.new(X::OutOfRange.new(
  255. :what($*INDEX // 'Index'), :got(pos), :range<0..0>))
  256. !! self
  257. }
  258. multi method AT-POS(Any:D: Num:D \pos) is raw {
  259. nqp::isnanorinf(pos)
  260. ?? Failure.new(X::Item.new(aggregate => self, index => pos))
  261. !! self.AT-POS(nqp::unbox_i(pos.Int))
  262. }
  263. multi method AT-POS(Any:D: Any:D \pos) is raw {
  264. self.AT-POS(nqp::unbox_i(pos.Int));
  265. }
  266. multi method AT-POS(Any: Any:U \pos) is raw {
  267. die "Cannot use '{pos.^name}' as an index";
  268. }
  269. multi method AT-POS(Any:D: \one, \two) is raw {
  270. self.AT-POS(one).AT-POS(two)
  271. }
  272. multi method AT-POS(Any:D: \one, \two, \three) is raw {
  273. self.AT-POS(one).AT-POS(two).AT-POS(three)
  274. }
  275. multi method AT-POS(Any:D: **@indices) is raw {
  276. my $final := @indices.pop;
  277. Rakudo::Internals.WALK-AT-POS(self,@indices).AT-POS($final)
  278. }
  279. proto method ZEN-POS(|) {*}
  280. multi method ZEN-POS(*%unexpected) {
  281. %unexpected
  282. ?? Failure.new(X::Adverb.new(
  283. :what('[] slice'),
  284. :source(try { self.VAR.name } // self.WHAT.perl),
  285. :unexpected(%unexpected.keys)))
  286. !! self
  287. }
  288. proto method ZEN-KEY(|) {*}
  289. multi method ZEN-KEY(*%unexpected) {
  290. %unexpected
  291. ?? Failure.new(X::Adverb.new(
  292. :what('{} slice'),
  293. :source(try { self.VAR.name } // self.WHAT.perl),
  294. :unexpected(%unexpected.keys)))
  295. !! self
  296. }
  297. proto method ASSIGN-POS(|) is nodal {*}
  298. multi method ASSIGN-POS(Any:U \SELF: \pos, Mu \assignee) {
  299. SELF.AT-POS(pos) = assignee; # defer < 0 check
  300. }
  301. multi method ASSIGN-POS(Any:D: int \pos, Mu \assignee) {
  302. self.AT-POS(pos) = assignee; # defer < 0 check
  303. }
  304. multi method ASSIGN-POS(Any:D: Int:D \pos, Mu \assignee) {
  305. self.AT-POS(pos) = assignee; # defer < 0 check
  306. }
  307. multi method ASSIGN-POS(Any:D: Num:D \pos, Mu \assignee) {
  308. nqp::isnanorinf(pos)
  309. ?? Failure.new(X::Item.new(aggregate => self, index => pos))
  310. !! self.AT-POS(nqp::unbox_i(pos.Int)) = assignee; # defer < 0 check
  311. }
  312. multi method ASSIGN-POS(Any:D: Any:D \pos, Mu \assignee) {
  313. self.AT-POS(nqp::unbox_i(pos.Int)) = assignee; # defer < 0 check
  314. }
  315. multi method ASSIGN-POS(Any:D: Any:U \pos, Mu \assignee) {
  316. die "Cannot use '{pos.^name}' as an index";
  317. }
  318. multi method ASSIGN-POS(Any:D: \one, \two, Mu \assignee) is raw {
  319. self.AT-POS(one).ASSIGN-POS(two, assignee)
  320. }
  321. multi method ASSIGN-POS(Any:D: \one, \two, \three, Mu \assignee) is raw {
  322. self.AT-POS(one).AT-POS(two).ASSIGN-POS(three, assignee)
  323. }
  324. multi method ASSIGN-POS(Any:D: **@indices) {
  325. my \value := @indices.pop;
  326. my $final := @indices.pop;
  327. Rakudo::Internals.WALK-AT-POS(self,@indices).ASSIGN-POS($final,value)
  328. }
  329. proto method BIND-POS(|) {*}
  330. multi method BIND-POS(Any:D: **@indices is raw) is raw {
  331. # looks like Array.pop doesn't really return a bindable container
  332. # my \value := @indices.pop;
  333. # my $final := @indices.pop;
  334. # Rakudo::Internals.WALK-AT-POS(self,@indices).BIND-POS($final,value)
  335. my int $elems = @indices.elems; # reifies
  336. my \value := @indices.AT-POS(--$elems);
  337. my $final := @indices.AT-POS(--$elems);
  338. my $target := self;
  339. my int $i = -1;
  340. $target := $target.AT-POS(@indices.AT-POS($i))
  341. while nqp::islt_i(++$i,$elems);
  342. X::Bind.new.throw if $target =:= self;
  343. $target.BIND-POS($final, value)
  344. }
  345. method all() is nodal { Junction.new("all", self) }
  346. method any() is nodal { Junction.new("any", self) }
  347. method one() is nodal { Junction.new("one", self) }
  348. method none() is nodal { Junction.new("none",self) }
  349. # internals
  350. proto method AT-KEY(|) is nodal {*}
  351. multi method AT-KEY(Any:D: $key) is raw {
  352. Failure.new( self ~~ Associative
  353. ?? "Associative indexing implementation missing from type {self.WHAT.perl}"
  354. !! "Type {self.WHAT.perl} does not support associative indexing."
  355. )
  356. }
  357. multi method AT-KEY(Any:U \SELF: \key) is raw {
  358. nqp::p6bindattrinvres(
  359. my $scalar,
  360. Scalar,
  361. '$!whence',
  362. # NOTE: even though the signature indicates a non-concrete SELF,
  363. # by the time the below code is executed, it *may* have become
  364. # concrete: and then we don't want the execution to reset it to
  365. # an empty Hash.
  366. -> { nqp::if(
  367. nqp::isconcrete(SELF),
  368. SELF,
  369. (SELF = nqp::create(Hash))
  370. ).BIND-KEY(key, $scalar)
  371. }
  372. )
  373. }
  374. proto method BIND-KEY(|) is nodal {*}
  375. multi method BIND-KEY(Any:D: \k, \v) is raw {
  376. X::Bind.new(target => self.^name).throw
  377. }
  378. multi method BIND-KEY(Any:U \SELF: $key, $BIND ) is raw {
  379. SELF = Hash.new;
  380. SELF.BIND-KEY($key, $BIND);
  381. $BIND
  382. }
  383. proto method ASSIGN-KEY(|) is nodal {*}
  384. multi method ASSIGN-KEY(\SELF: \key, Mu \assignee) is raw {
  385. SELF.AT-KEY(key) = assignee;
  386. }
  387. # XXX GLR review these
  388. method FLATTENABLE_LIST() is nodal {
  389. my $list := self.list;
  390. nqp::findmethod($list, 'FLATTENABLE_LIST')($list);
  391. }
  392. method FLATTENABLE_HASH() is nodal { nqp::hash() }
  393. proto method Set(|) is nodal {*}
  394. multi method Set(Any:) { Set.new-from-pairs(self.list) }
  395. proto method SetHash(|) is nodal {*}
  396. multi method SetHash(Any:) { SetHash.new-from-pairs(self.list) }
  397. proto method Bag(|) is nodal {*}
  398. multi method Bag(Any:) { Bag.new-from-pairs(self.list) }
  399. proto method BagHash(|) is nodal {*}
  400. multi method BagHash(Any:) { BagHash.new-from-pairs(self.list) }
  401. proto method Mix(|) is nodal {*}
  402. multi method Mix(Any:) { Mix.new-from-pairs(self.list) }
  403. proto method MixHash(|) is nodal {*}
  404. multi method MixHash() { MixHash.new-from-pairs(self.list) }
  405. # XXX GLR does this really need to force a list?
  406. proto method Supply(|) is nodal {*}
  407. multi method Supply() { self.list.Supply }
  408. method nl-out() { "\n" }
  409. method print-nl() { self.print(self.nl-out) }
  410. method lazy-if($flag) { self } # no-op on non-Iterables
  411. method sum() is nodal {
  412. my \iter = self.iterator;
  413. my $sum = 0;
  414. my Mu $value;
  415. nqp::until(
  416. nqp::eqaddr(($value := iter.pull-one),IterationEnd),
  417. ($sum = $sum + $value)
  418. );
  419. $sum;
  420. }
  421. }
  422. Metamodel::ClassHOW.exclude_parent(Any);
  423. # builtin ops
  424. proto sub infix:<===>(Mu $?, Mu $?) is pure {*}
  425. multi sub infix:<===>($?) { Bool::True }
  426. multi sub infix:<===>(\a, \b) {
  427. nqp::p6bool(
  428. nqp::eqaddr(nqp::decont(a),nqp::decont(b))
  429. || (nqp::eqaddr(a.WHAT,b.WHAT)
  430. && nqp::iseq_s(nqp::unbox_s(a.WHICH), nqp::unbox_s(b.WHICH)))
  431. )
  432. }
  433. proto sub infix:<before>(Mu $?, Mu $?) is pure {*}
  434. multi sub infix:<before>($?) { Bool::True }
  435. multi sub infix:<before>(\a, \b) { (a cmp b) < 0 }
  436. proto sub infix:<after>(Mu $?, Mu $?) is pure {*}
  437. multi sub infix:<after>($x?) { Bool::True }
  438. multi sub infix:<after>(\a, \b) { (a cmp b) > 0 }
  439. proto prefix:<++>(Mu) {*}
  440. multi prefix:<++>(Mu:D $a is rw) { $a = $a.succ }
  441. multi prefix:<++>(Mu:U $a is rw) { $a = 1 }
  442. proto prefix:<-->(Mu) {*}
  443. multi prefix:<-->(Mu:D $a is rw) { $a = $a.pred }
  444. multi prefix:<-->(Mu:U $a is rw) { $a = -1 }
  445. proto postfix:<++>(Mu) {*}
  446. multi postfix:<++>(Mu:D $a is rw) { my $b = $a; $a = $a.succ; $b }
  447. multi postfix:<++>(Mu:U $a is rw) { $a = 1; 0 }
  448. proto postfix:<-->(Mu) {*}
  449. multi postfix:<-->(Mu:D $a is rw) { my $b = $a; $a = $a.pred; $b }
  450. multi postfix:<-->(Mu:U $a is rw) { $a = -1; 0 }
  451. proto sub pick(|) {*}
  452. multi sub pick($n, +values) { values.pick($n) }
  453. proto sub roll(|) {*}
  454. multi sub roll($n, +values) { values.roll($n) }
  455. proto sub keys(|) {*}
  456. multi sub keys($x) { $x.keys }
  457. proto sub values(|) {*}
  458. multi sub values($x) { $x.values }
  459. proto sub pairs(|) {*}
  460. multi sub pairs($x) { $x.pairs }
  461. proto sub kv(|) {*}
  462. multi sub kv($x) { $x.kv }
  463. proto sub elems(|) is nodal {*}
  464. multi sub elems($a) { $a.elems }
  465. proto sub end(|) {*}
  466. multi sub end($a) { $a.end }
  467. proto sub sum(|) {*}
  468. multi sub sum() { 0 }
  469. multi sub sum(\SELF) { SELF.sum }
  470. multi sub sum(+SELF) { SELF.sum }
  471. proto sub classify(|) {*}
  472. multi sub classify($test, +items, :$into!, *%named ) {
  473. ( $into // $into.new).classify-list($test, items, |%named)
  474. }
  475. multi sub classify($test, +items, *%named ) {
  476. Hash.^parameterize(Any,Any).new.classify-list($test, items, |%named);
  477. }
  478. proto sub categorize(|) {*}
  479. multi sub categorize($test, +items, :$into!, *%named ) {
  480. ( $into // $into.new).categorize-list($test, items, |%named)
  481. }
  482. multi sub categorize($test, +items, *%named ) {
  483. Hash.^parameterize(Any,Any).new.categorize-list($test, items, |%named)
  484. }
  485. proto sub item(|) is pure {*}
  486. multi sub item(\x) { my $ = x }
  487. multi sub item(|c) { my $ = c.list }
  488. multi sub item(Mu $a) { $a }
  489. sub SLICE_HUH(\SELF, @nogo, %d, %adv) {
  490. @nogo.unshift('delete') # recover any :delete if necessary
  491. if @nogo && @nogo[0] ne 'delete' && %adv.EXISTS-KEY('delete');
  492. for <delete exists kv p k v> -> $valid { # check all valid params
  493. if nqp::existskey(%d,nqp::unbox_s($valid)) {
  494. nqp::deletekey(%d,nqp::unbox_s($valid));
  495. @nogo.push($valid);
  496. }
  497. }
  498. Failure.new(X::Adverb.new(
  499. :what<slice>,
  500. :source(try { SELF.VAR.name } // SELF.WHAT.perl),
  501. :unexpected(%d.keys),
  502. :nogo(@nogo),
  503. ))
  504. } #SLICE_HUH
  505. sub dd(|) {
  506. my Mu $args := nqp::p6argvmarray();
  507. if nqp::elems($args) {
  508. while $args {
  509. my $var := nqp::shift($args);
  510. my $name := ! nqp::istype($var.VAR, Failure) && try $var.VAR.name;
  511. my $type := $var.WHAT.^name;
  512. my $what := nqp::can($var, 'is-lazy') && $var.is-lazy
  513. ?? $var[^10].perl.chop ~ "... lazy list)"
  514. !! nqp::can($var, 'perl')
  515. ?? $var.perl
  516. !! "($var.^name() without .perl method)";
  517. note $name ?? "$type $name = $what" !! $what;
  518. }
  519. }
  520. else { # tell where we are
  521. note .name
  522. ?? "{lc .^name} {.name}{.signature.gist}"
  523. !! "{lc .^name} {.signature.gist}"
  524. with callframe(1).code;
  525. }
  526. return
  527. }