1-- in.cue --
2import "list"
3
4// The following just chains existing fields and should NOT trigger a cycle
5// detection error.
6
7
8chain: t1: {
9 #maxiter: 2
10
11 // Trigger lookup of a.x0 before the "regular" evaluation of a.
12 x: a.x0
13
14 a: {
15 for k, _ in [0, 1] {
16 "x\(k)": (#DepthF & {#in: a["x\(k+1)"]}).#out
17 }
18 }
19
20 a: x2: null
21
22
23 #DepthF: {
24 #in: _
25 #out: {}
26 }
27}
28
29chain: t2: p1: {
30 X: 1
31
32 // Reference X through x.x0 before X is inserted.
33 for v in [0, X] + [] {
34 x: "x\(v)": {}
35 }
36
37 x: _
38
39 x.x0
40}
41
42chain: t2: p2: {
43 // Reference X through x.x0 before X is inserted.
44 for v in [0, X] + [] {
45 x: "x\(v)": {}
46 }
47
48 x: _
49
50 x.x0
51
52 X: 1
53}
54
55chain: t3: p1: {
56 X: 1
57
58 for v in list.Range(0, X, 1) {
59 x: "x\(v)": {}
60 }
61
62 x: _
63
64 x.x0
65}
66
67chain: t3: p1: {
68 for v in list.Range(0, X, 1) {
69 x: "x\(v)": {}
70 }
71
72 x: _
73
74 x.x0
75
76 X: 1
77}
78
79-- issue2052.cue --
80import "list"
81
82issue2052: t1: {
83 #Depth: {
84 #maxiter: 4
85
86 for k, v in list.Range(0, #maxiter, 1) {
87 #funcs: "\(k)": (#DepthF & {#next: #funcs["\(k+1)"]}).#func
88 }
89
90 #funcs: "\(#maxiter)": null
91
92 #funcs["0"]
93 }
94
95 #DepthF: {
96 #next: _
97 #func: {
98 #in: _
99 #basic: string | null
100 out: {
101 if (#in & #basic) != _|_ {1}
102 if (#in & #basic) == _|_ {
103 list.Max([for k, v in #in {(#next & {#in: v}).out}]) + 1
104 }
105 }
106 }
107 }
108
109 tree: "bar"
110
111 d: #Depth & {#in: tree}
112
113}
114
115issue2052: t2: {
116 #Depth: {
117 #maxiter: 4
118
119 for k, v in list.Range(0, #maxiter, 1) {
120 #funcs: "\(k)": (#DepthF & {#next: #funcs["\(k+1)"]}).#func
121 }
122
123 #funcs:{
124 for k, v in list.Range(0, #maxiter, 1) {
125 "\(k)": (#DepthF & {#next: #funcs["\(k+1)"]}).#func
126 }
127 }
128
129 #funcs: "\(#maxiter)": null
130
131 #funcs["0"]
132 }
133
134 #DepthF: {
135 #next: _
136 #func: {
137 #in: _
138 #basic: string | null
139 out: {
140 if (#in & #basic) != _|_ {1}
141 if (#in & #basic) == _|_ {
142 list.Max([for k, v in #in {(#next & {#in: v}).out}]) + 1
143 }
144 }
145 }
146 }
147
148 tree: "bar"
149
150 d: #Depth & {#in: tree}
151}
152
153issue2052: full: {
154 #RecurseN: {
155 // this is the bound on our recursion
156 #maxiter: uint | *4
157
158 // This is the function list element
159 // we generate this to simulate recursion
160 #funcFactory: {
161 #next: _
162 #func: _
163 }
164
165 // this is our "recursion unrolling"
166 for k, v in list.Range(0, #maxiter, 1) {
167 // this is where we build up our indexed functions and the references between them
168 #funcs: "\(k)": (#funcFactory & {#next: #funcs["\(k+1)"]}).#func
169 }
170
171 // our final value needs to be null
172 #funcs: "\(#maxiter)": null
173
174 // we embed the head of the list so that the values
175 // we write this into can be used like other CUE "functions"
176 #funcs["0"]
177 }
178
179 #DepthF: {
180 #next: _
181 #func: {
182 #in: _
183 #basic: int | number | string | bytes | null
184 out: {
185 // if we have a basic type, we are at a leaf, depth is 1
186 if (#in & #basic) != _|_ {1}
187
188 // if we are not a basic type, then we are 1 + the max of children
189 if (#in & #basic) == _|_ {
190 // this is our "recursion" for each child
191 let depths = [for k, v in #in {(#next & {#in: v}).out}]
192 list.Max(depths) + 1
193 }
194 }
195 }
196 }
197
198 #Depth: #RecurseN & {#maxiter: 11, #funcFactory: #DepthF}
199
200 tree: {
201 a: {
202 foo: "bar"
203 a: b: c: "d"
204 }
205 cow: "moo"
206 }
207
208 d: #Depth & {#in: tree}
209}
210-- out/eval/stats --
211Leaks: 70
212Freed: 1815
213Reused: 1801
214Allocs: 84
215Retain: 185
216
217Unifications: 800
218Conjuncts: 3175
219Disjuncts: 1974
220-- out/eval --
221(struct){
222 chain: (struct){
223 t1: (struct){
224 #maxiter: (int){ 2 }
225 x: (#struct){
226 }
227 a: (struct){
228 x2: (null){ null }
229 x0: (#struct){
230 }
231 x1: (#struct){
232 }
233 }
234 #DepthF: (#struct){
235 #in: (_){ _ }
236 #out: (#struct){
237 }
238 }
239 }
240 t2: (struct){
241 p1: (struct){
242 X: (int){ 1 }
243 x: (struct){
244 x0: (struct){
245 }
246 x1: (struct){
247 }
248 }
249 }
250 p2: (struct){
251 x: (struct){
252 x0: (struct){
253 }
254 x1: (struct){
255 }
256 }
257 X: (int){ 1 }
258 }
259 }
260 t3: (struct){
261 p1: (struct){
262 X: (int){ 1 }
263 x: (struct){
264 x0: (struct){
265 }
266 }
267 }
268 }
269 }
270 issue2052: (struct){
271 t1: (struct){
272 #Depth: (#struct){
273 #maxiter: (int){ 4 }
274 #funcs: (#struct){
275 "4": (null){ null }
276 "0": (#struct){
277 #in: (_){ _ }
278 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
279 out: (int){ 1 }
280 }
281 "1": (#struct){
282 #in: (_){ _ }
283 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
284 out: (int){ 1 }
285 }
286 "2": (#struct){
287 #in: (_){ _ }
288 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
289 out: (int){ 1 }
290 }
291 "3": (#struct){
292 #in: (_){ _ }
293 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
294 out: (int){ 1 }
295 }
296 }
297 #in: (_){ _ }
298 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
299 out: (int){ 1 }
300 }
301 #DepthF: (#struct){
302 #next: (_){ _ }
303 #func: (#struct){
304 #in: (_){ _ }
305 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
306 out: (int){ 1 }
307 }
308 }
309 tree: (string){ "bar" }
310 d: (#struct){
311 #maxiter: (int){ 4 }
312 #funcs: (#struct){
313 "4": (null){ null }
314 "0": (#struct){
315 #in: (_){ _ }
316 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
317 out: (int){ 1 }
318 }
319 "1": (#struct){
320 #in: (_){ _ }
321 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
322 out: (int){ 1 }
323 }
324 "2": (#struct){
325 #in: (_){ _ }
326 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
327 out: (int){ 1 }
328 }
329 "3": (#struct){
330 #in: (_){ _ }
331 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
332 out: (int){ 1 }
333 }
334 }
335 #in: (string){ "bar" }
336 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
337 out: (int){ 1 }
338 }
339 }
340 t2: (struct){
341 #Depth: (#struct){
342 #maxiter: (int){ 4 }
343 #funcs: (#struct){
344 "4": (null){ null }
345 "0": (#struct){
346 #in: (_){ _ }
347 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
348 out: (int){ 1 }
349 }
350 "1": (#struct){
351 #in: (_){ _ }
352 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
353 out: (int){ 1 }
354 }
355 "2": (#struct){
356 #in: (_){ _ }
357 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
358 out: (int){ 1 }
359 }
360 "3": (#struct){
361 #in: (_){ _ }
362 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
363 out: (int){ 1 }
364 }
365 }
366 #in: (_){ _ }
367 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
368 out: (int){ 1 }
369 }
370 #DepthF: (#struct){
371 #next: (_){ _ }
372 #func: (#struct){
373 #in: (_){ _ }
374 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
375 out: (int){ 1 }
376 }
377 }
378 tree: (string){ "bar" }
379 d: (#struct){
380 #maxiter: (int){ 4 }
381 #funcs: (#struct){
382 "4": (null){ null }
383 "0": (#struct){
384 #in: (_){ _ }
385 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
386 out: (int){ 1 }
387 }
388 "1": (#struct){
389 #in: (_){ _ }
390 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
391 out: (int){ 1 }
392 }
393 "2": (#struct){
394 #in: (_){ _ }
395 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
396 out: (int){ 1 }
397 }
398 "3": (#struct){
399 #in: (_){ _ }
400 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
401 out: (int){ 1 }
402 }
403 }
404 #in: (string){ "bar" }
405 #basic: ((null|string)){ |((string){ string }, (null){ null }) }
406 out: (int){ 1 }
407 }
408 }
409 full: (struct){
410 #RecurseN: (_){
411 _
412 #maxiter: (int){ |(*(int){ 4 }, (int){ &(>=0, int) }) }
413 #funcFactory: (#struct){
414 #next: (_){ _ }
415 #func: (_){ _ }
416 }
417 #funcs: (#struct){
418 "4": (null){ null }
419 "0": (_){ _ }
420 "1": (_){ _ }
421 "2": (_){ _ }
422 "3": (_){ _ }
423 }
424 }
425 #DepthF: (#struct){
426 #next: (_){ _ }
427 #func: (#struct){
428 #in: (_){ _ }
429 #basic: ((null|string|bytes|number)){ |((int){ int }, (number){ number }, (string){ string }, (bytes){ bytes }, (null){ null }) }
430 out: (int){
431 1
432 let depths#1 = (_){ _ }
433 }
434 }
435 }
436 #Depth: (#struct){
437 #maxiter: (int){ 11 }
438 #funcFactory: (#struct){
439 #next: (_){ _ }
440 #func: (#struct){
441 #in: (_){ _ }
442 #basic: ((null|string|bytes|number)){ |((int){ int }, (number){ number }, (string){ string }, (bytes){ bytes }, (null){ null }) }
443 out: (int){
444 1
445 let depths#1 = (_){ _ }
446 }
447 }
448 }
449 #funcs: (#struct){
450 "11": (null){ null }
451 "0": (#struct){
452 #in: (_){ _ }
453 #basic: ((null|string|bytes|number)){ |((int){ int }, (number){ number }, (string){ string }, (bytes){ bytes }, (null){ null }) }
454 out: (int){
455 1
456 let depths#1 = (_){ _ }
457 }
458 }
459 "1": (#struct){
460 #in: (_){ _ }
461 #basic: ((null|string|bytes|number)){ |((int){ int }, (number){ number }, (string){ string }, (bytes){ bytes }, (null){ null }) }
462 out: (int){
463 1
464 let depths#1 = (_){ _ }
465 }
466 }
467 "2": (#struct){
468 #in: (_){ _ }
469 #basic: ((null|string|bytes|number)){ |((int){ int }, (number){ number }, (string){ string }, (bytes){ bytes }, (null){ null }) }
470 out: (int){
471 1
472 let depths#1 = (_){ _ }
473 }
474 }
475 "3": (#struct){
476 #in: (_){ _ }
477 #basic: ((null|string|bytes|number)){ |((int){ int }, (number){ number }, (string){ string }, (bytes){ bytes }, (null){ null }) }
478 out: (int){
479 1
480 let depths#1 = (_){ _ }
481 }
482 }
483 "4": (#struct){
484 #in: (_){ _ }
485 #basic: ((null|string|bytes|number)){ |((int){ int }, (number){ number }, (string){ string }, (bytes){ bytes }, (null){ null }) }
486 out: (int){
487 1
488 let depths#1 = (_){ _ }
489 }
490 }
491 "5": (#struct){
492 #in: (_){ _ }
493 #basic: ((null|string|bytes|number)){ |((int){ int }, (number){ number }, (string){ string }, (bytes){ bytes }, (null){ null }) }
494 out: (int){
495 1
496 let depths#1 = (_){ _ }
497 }
498 }
499 "6": (#struct){
500 #in: (_){ _ }
501 #basic: ((null|string|bytes|number)){ |((int){ int }, (number){ number }, (string){ string }, (bytes){ bytes }, (null){ null }) }
502 out: (int){
503 1
504 let depths#1 = (_){ _ }
505 }
506 }
507 "7": (#struct){
508 #in: (_){ _ }
509 #basic: ((null|string|bytes|number)){ |((int){ int }, (number){ number }, (string){ string }, (bytes){ bytes }, (null){ null }) }
510 out: (int){
511 1
512 let depths#1 = (_){ _ }
513 }
514 }
515 "8": (#struct){
516 #in: (_){ _ }
517 #basic: ((null|string|bytes|number)){ |((int){ int }, (number){ number }, (string){ string }, (bytes){ bytes }, (null){ null }) }
518 out: (int){
519 1
520 let depths#1 = (_){ _ }
521 }
522 }
523 "9": (#struct){
524 #in: (_){ _ }
525 #basic: ((null|string|bytes|number)){ |((int){ int }, (number){ number }, (string){ string }, (bytes){ bytes }, (null){ null }) }
526 out: (int){
527 1
528 let depths#1 = (_){ _ }
529 }
530 }
531 "10": (#struct){
532 #in: (_){ _ }
533 #basic: ((null|string|bytes|number)){ |((int){ int }, (number){ number }, (string){ string }, (bytes){ bytes }, (null){ null }) }
534 out: (int){
535 1
536 let depths#1 = (_){ _ }
537 }
538 }
539 }
540 #in: (_){ _ }
541 #basic: ((null|string|bytes|number)){ |((int){ int }, (number){ number }, (string){ string }, (bytes){ bytes }, (null){ null }) }
542 out: (int){
543 1
544 let depths#1 = (_){ _ }
545 }
546 }
547 tree: (struct){
548 a: (struct){
549 foo: (string){ "bar" }
550 a: (struct){
551 b: (struct){
552 c: (string){ "d" }
553 }
554 }
555 }
556 cow: (string){ "moo" }
557 }
558 d: (_|_){
559 // [incomplete] issue2052.full.d: cannot add field #maxiter: was already used:
560 // ./issue2052.cue:119:23
561 #maxiter: (int){ |(*(int){ 4 }, (int){ &(>=0, int) }) }
562 #funcFactory: (#struct){
563 #next: (_){ _ }
564 #func: (#struct){
565 #in: (_){ _ }
566 #basic: ((null|string|bytes|number)){ |((int){ int }, (number){ number }, (string){ string }, (bytes){ bytes }, (null){ null }) }
567 out: (int){
568 1
569 let depths#1 = (_){ _ }
570 }
571 }
572 }
573 #funcs: (#struct){
574 "4": (null){ null }
575 "0": (_){ _ }
576 "1": (#struct){
577 #in: (_){ _ }
578 #basic: ((null|string|bytes|number)){ |((int){ int }, (number){ number }, (string){ string }, (bytes){ bytes }, (null){ null }) }
579 out: (int){
580 1
581 let depths#1 = (_){ _ }
582 }
583 }
584 "2": (#struct){
585 #in: (_){ _ }
586 #basic: ((null|string|bytes|number)){ |((int){ int }, (number){ number }, (string){ string }, (bytes){ bytes }, (null){ null }) }
587 out: (int){
588 1
589 let depths#1 = (_){ _ }
590 }
591 }
592 "3": (#struct){
593 #in: (_){ _ }
594 #basic: ((null|string|bytes|number)){ |((int){ int }, (number){ number }, (string){ string }, (bytes){ bytes }, (null){ null }) }
595 out: (int){
596 1
597 let depths#1 = (_){ _ }
598 }
599 }
600 }
601 #in: (#struct){
602 a: (#struct){
603 foo: (string){ "bar" }
604 a: (#struct){
605 b: (#struct){
606 c: (string){ "d" }
607 }
608 }
609 }
610 cow: (string){ "moo" }
611 }
612 }
613 }
614 }
615}
616-- out/compile --
617--- in.cue
618{
619 chain: {
620 t1: {
621 #maxiter: 2
622 x: 〈0;a〉.x0
623 a: {
624 for k, _ in [
625 0,
626 1,
627 ] {
628 "x\(〈1;k〉)": (〈3;#DepthF〉 & {
629 #in: 〈4;a〉["x\((〈2;k〉 + 1))"]
630 }).#out
631 }
632 }
633 a: {
634 x2: null
635 }
636 #DepthF: {
637 #in: _
638 #out: {}
639 }
640 }
641 }
642 chain: {
643 t2: {
644 p1: {
645 X: 1
646 for _, v in ([
647 0,
648 〈1;X〉,
649 ] + []) {
650 x: {
651 "x\(〈2;v〉)": {}
652 }
653 }
654 x: _
655 〈0;x〉.x0
656 }
657 }
658 }
659 chain: {
660 t2: {
661 p2: {
662 for _, v in ([
663 0,
664 〈1;X〉,
665 ] + []) {
666 x: {
667 "x\(〈2;v〉)": {}
668 }
669 }
670 x: _
671 〈0;x〉.x0
672 X: 1
673 }
674 }
675 }
676 chain: {
677 t3: {
678 p1: {
679 X: 1
680 for _, v in 〈import;list〉.Range(0, 〈0;X〉, 1) {
681 x: {
682 "x\(〈2;v〉)": {}
683 }
684 }
685 x: _
686 〈0;x〉.x0
687 }
688 }
689 }
690 chain: {
691 t3: {
692 p1: {
693 for _, v in 〈import;list〉.Range(0, 〈0;X〉, 1) {
694 x: {
695 "x\(〈2;v〉)": {}
696 }
697 }
698 x: _
699 〈0;x〉.x0
700 X: 1
701 }
702 }
703 }
704}
705--- issue2052.cue
706{
707 issue2052: {
708 t1: {
709 #Depth: {
710 #maxiter: 4
711 for k, v in 〈import;list〉.Range(0, 〈0;#maxiter〉, 1) {
712 #funcs: {
713 "\(〈2;k〉)": (〈4;#DepthF〉 & {
714 #next: 〈2;#funcs〉["\((〈3;k〉 + 1))"]
715 }).#func
716 }
717 }
718 #funcs: {
719 "\(〈1;#maxiter〉)": null
720 }
721 〈0;#funcs〉["0"]
722 }
723 #DepthF: {
724 #next: _
725 #func: {
726 #in: _
727 #basic: (string|null)
728 out: {
729 if ((〈1;#in〉 & 〈1;#basic〉) != _|_(explicit error (_|_ literal) in source)) {
730 1
731 }
732 if ((〈1;#in〉 & 〈1;#basic〉) == _|_(explicit error (_|_ literal) in source)) {
733 (〈import;list〉.Max([
734 for k, v in 〈3;#in〉 {
735 (〈6;#next〉 & {
736 #in: 〈2;v〉
737 }).out
738 },
739 ]) + 1)
740 }
741 }
742 }
743 }
744 tree: "bar"
745 d: (〈0;#Depth〉 & {
746 #in: 〈1;tree〉
747 })
748 }
749 }
750 issue2052: {
751 t2: {
752 #Depth: {
753 #maxiter: 4
754 for k, v in 〈import;list〉.Range(0, 〈0;#maxiter〉, 1) {
755 #funcs: {
756 "\(〈2;k〉)": (〈4;#DepthF〉 & {
757 #next: 〈2;#funcs〉["\((〈3;k〉 + 1))"]
758 }).#func
759 }
760 }
761 #funcs: {
762 for k, v in 〈import;list〉.Range(0, 〈1;#maxiter〉, 1) {
763 "\(〈1;k〉)": (〈4;#DepthF〉 & {
764 #next: 〈4;#funcs〉["\((〈2;k〉 + 1))"]
765 }).#func
766 }
767 }
768 #funcs: {
769 "\(〈1;#maxiter〉)": null
770 }
771 〈0;#funcs〉["0"]
772 }
773 #DepthF: {
774 #next: _
775 #func: {
776 #in: _
777 #basic: (string|null)
778 out: {
779 if ((〈1;#in〉 & 〈1;#basic〉) != _|_(explicit error (_|_ literal) in source)) {
780 1
781 }
782 if ((〈1;#in〉 & 〈1;#basic〉) == _|_(explicit error (_|_ literal) in source)) {
783 (〈import;list〉.Max([
784 for k, v in 〈3;#in〉 {
785 (〈6;#next〉 & {
786 #in: 〈2;v〉
787 }).out
788 },
789 ]) + 1)
790 }
791 }
792 }
793 }
794 tree: "bar"
795 d: (〈0;#Depth〉 & {
796 #in: 〈1;tree〉
797 })
798 }
799 }
800 issue2052: {
801 full: {
802 #RecurseN: {
803 #maxiter: (&(int, >=0)|*4)
804 #funcFactory: {
805 #next: _
806 #func: _
807 }
808 for k, v in 〈import;list〉.Range(0, 〈0;#maxiter〉, 1) {
809 #funcs: {
810 "\(〈2;k〉)": (〈3;#funcFactory〉 & {
811 #next: 〈2;#funcs〉["\((〈3;k〉 + 1))"]
812 }).#func
813 }
814 }
815 #funcs: {
816 "\(〈1;#maxiter〉)": null
817 }
818 〈0;#funcs〉["0"]
819 }
820 #DepthF: {
821 #next: _
822 #func: {
823 #in: _
824 #basic: (int|number|string|bytes|null)
825 out: {
826 if ((〈1;#in〉 & 〈1;#basic〉) != _|_(explicit error (_|_ literal) in source)) {
827 1
828 }
829 if ((〈1;#in〉 & 〈1;#basic〉) == _|_(explicit error (_|_ literal) in source)) {
830 let depths#1 = [
831 for k, v in 〈3;#in〉 {
832 (〈6;#next〉 & {
833 #in: 〈2;v〉
834 }).out
835 },
836 ]
837 (〈import;list〉.Max(〈0;let depths#1〉) + 1)
838 }
839 }
840 }
841 }
842 #Depth: (〈0;#RecurseN〉 & {
843 #maxiter: 11
844 #funcFactory: 〈1;#DepthF〉
845 })
846 tree: {
847 a: {
848 foo: "bar"
849 a: {
850 b: {
851 c: "d"
852 }
853 }
854 }
855 cow: "moo"
856 }
857 d: (〈0;#Depth〉 & {
858 #in: 〈1;tree〉
859 })
860 }
861 }
862}
View as plain text