1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package adt
16
17 import (
18 "bytes"
19 "fmt"
20 "io"
21 "regexp"
22
23 "github.com/cockroachdb/apd/v3"
24
25 "cuelang.org/go/cue/ast"
26 "cuelang.org/go/cue/errors"
27 "cuelang.org/go/cue/token"
28 )
29
30 var _ Elem = &ConjunctGroup{}
31
32
33
34 type ConjunctGroup []Conjunct
35
36 func (g *ConjunctGroup) Source() ast.Node {
37 return nil
38 }
39
40
41 type StructLit struct {
42 Src ast.Node
43 Decls []Decl
44
45
46
47
48
49
50
51 Fields []FieldInfo
52
53 Dynamic []*DynamicField
54
55
56 Bulk []*BulkOptionalField
57
58 Additional []*Ellipsis
59 HasEmbed bool
60 IsOpen bool
61 initialized bool
62
63 types OptionalType
64
65
66
67 }
68
69 func (o *StructLit) IsFile() bool {
70 _, ok := o.Src.(*ast.File)
71 return ok
72 }
73
74 type FieldInfo struct {
75 Label Feature
76 }
77
78 func (x *StructLit) HasOptional() bool {
79 return x.types&(HasPattern|HasAdditional) != 0
80 }
81
82 func (x *StructLit) Source() ast.Node { return x.Src }
83
84 func (x *StructLit) evaluate(c *OpContext, state combinedFlags) Value {
85 e := c.Env(0)
86 v := c.newInlineVertex(e.Vertex, nil, Conjunct{e, x, c.ci})
87
88
89
90
91 v.CompleteArcs(c)
92 return v
93 }
94
95
96 func (o *StructLit) MarkField(f Feature) {
97 o.Fields = append(o.Fields, FieldInfo{Label: f})
98 }
99
100 func (o *StructLit) Init() {
101 if o.initialized {
102 return
103 }
104 o.initialized = true
105 for _, d := range o.Decls {
106 switch x := d.(type) {
107 case *Field:
108 if o.fieldIndex(x.Label) < 0 {
109 o.Fields = append(o.Fields, FieldInfo{Label: x.Label})
110 }
111 if x.ArcType > ArcMember {
112 o.types |= HasField
113 }
114
115 case *LetField:
116 if o.fieldIndex(x.Label) >= 0 {
117 panic("duplicate let identifier")
118 }
119 o.Fields = append(o.Fields, FieldInfo{Label: x.Label})
120
121 case *DynamicField:
122 o.Dynamic = append(o.Dynamic, x)
123 o.types |= HasDynamic
124
125 case Expr:
126 o.HasEmbed = true
127
128 case *Comprehension:
129 o.HasEmbed = true
130
131 case *LetClause:
132 o.HasEmbed = true
133
134 case *BulkOptionalField:
135 o.Bulk = append(o.Bulk, x)
136 o.types |= HasPattern
137 switch x.Filter.(type) {
138 case *BasicType, *Top:
139 default:
140 o.types |= HasComplexPattern
141 }
142
143 case *Ellipsis:
144 switch x.Value.(type) {
145 case nil, *Top:
146 o.IsOpen = true
147 o.types |= IsOpen
148
149 default:
150
151 o.types |= HasAdditional
152 }
153 o.Additional = append(o.Additional, x)
154
155 default:
156 panic("unreachable")
157 }
158 }
159 }
160
161 func (o *StructLit) fieldIndex(f Feature) int {
162 for i := range o.Fields {
163 if o.Fields[i].Label == f {
164 return i
165 }
166 }
167 return -1
168 }
169
170 func (o *StructLit) OptionalTypes() OptionalType {
171 return o.types
172 }
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189 type Field struct {
190 Src *ast.Field
191
192 ArcType ArcType
193 Label Feature
194 Value Expr
195 }
196
197 func (x *Field) Source() ast.Node {
198 if x.Src == nil {
199 return nil
200 }
201 return x.Src
202 }
203
204
205
206
207 type LetField struct {
208 Src *ast.LetClause
209 Label Feature
210
211
212
213 IsMulti bool
214 Value Expr
215 }
216
217 func (x *LetField) Source() ast.Node {
218 if x.Src == nil {
219 return nil
220 }
221 return x.Src
222 }
223
224
225
226
227 type BulkOptionalField struct {
228 Src *ast.Field
229 Filter Expr
230 Value Expr
231 Label Feature
232 }
233
234 func (x *BulkOptionalField) Source() ast.Node {
235 if x.Src == nil {
236 return nil
237 }
238 return x.Src
239 }
240
241
242
243
244 type Ellipsis struct {
245 Src *ast.Ellipsis
246 Value Expr
247 }
248
249 func (x *Ellipsis) Source() ast.Node {
250 if x.Src == nil {
251 return nil
252 }
253 return x.Src
254 }
255
256
257
258
259
260 type DynamicField struct {
261 Src *ast.Field
262
263 ArcType ArcType
264 Key Expr
265 Value Expr
266 }
267
268 func (x *DynamicField) Source() ast.Node {
269 if x.Src == nil {
270 return nil
271 }
272 return x.Src
273 }
274
275
276
277
278 type ListLit struct {
279 Src *ast.ListLit
280
281
282 Elems []Elem
283
284 info *StructLit
285 }
286
287 func (x *ListLit) Source() ast.Node {
288 if x.Src == nil {
289 return nil
290 }
291 return x.Src
292 }
293
294 func (x *ListLit) evaluate(c *OpContext, state combinedFlags) Value {
295 e := c.Env(0)
296 v := c.newInlineVertex(e.Vertex, nil, Conjunct{e, x, c.ci})
297 v.CompleteArcs(c)
298 return v
299 }
300
301
302 type Null struct {
303 Src ast.Node
304 }
305
306 func (x *Null) Source() ast.Node { return x.Src }
307 func (x *Null) Kind() Kind { return NullKind }
308
309
310 type Bool struct {
311 Src ast.Node
312 B bool
313 }
314
315 func (x *Bool) Source() ast.Node { return x.Src }
316 func (x *Bool) Kind() Kind { return BoolKind }
317
318
319 type Num struct {
320 Src ast.Node
321 K Kind
322 X apd.Decimal
323 }
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342 func (x *Num) Source() ast.Node { return x.Src }
343 func (x *Num) Kind() Kind { return x.K }
344
345
346
347
348
349
350
351
352
353
354
355
356
357 type String struct {
358 Src ast.Node
359 Str string
360 RE *regexp.Regexp
361 }
362
363 func (x *String) Source() ast.Node { return x.Src }
364 func (x *String) Kind() Kind { return StringKind }
365
366
367 type Bytes struct {
368 Src ast.Node
369 B []byte
370 RE *regexp.Regexp
371 }
372
373 func (x *Bytes) Source() ast.Node { return x.Src }
374 func (x *Bytes) Kind() Kind { return BytesKind }
375
376
377
378
379 type ListMarker struct {
380 Src ast.Expr
381 IsOpen bool
382 }
383
384 func (x *ListMarker) Source() ast.Node { return x.Src }
385 func (x *ListMarker) Kind() Kind { return ListKind }
386 func (x *ListMarker) node() {}
387
388 type StructMarker struct {
389
390
391 NeedClose bool
392 }
393
394 func (x *StructMarker) Source() ast.Node { return nil }
395 func (x *StructMarker) Kind() Kind { return StructKind }
396 func (x *StructMarker) node() {}
397
398
399 type Top struct{ Src *ast.Ident }
400
401 func (x *Top) Source() ast.Node {
402 if x.Src == nil {
403 return nil
404 }
405 return x.Src
406 }
407 func (x *Top) Kind() Kind { return TopKind }
408
409
410
411
412
413
414
415
416 type BasicType struct {
417 Src ast.Node
418 K Kind
419 }
420
421 func (x *BasicType) Source() ast.Node {
422 if x.Src == nil {
423 return nil
424 }
425 return x.Src
426 }
427 func (x *BasicType) Kind() Kind { return x.K }
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446 type BoundExpr struct {
447 Src *ast.UnaryExpr
448 Op Op
449 Expr Expr
450 }
451
452 func (x *BoundExpr) Source() ast.Node {
453 if x.Src == nil {
454 return nil
455 }
456 return x.Src
457 }
458
459 func (x *BoundExpr) evaluate(ctx *OpContext, state combinedFlags) Value {
460
461
462 v := ctx.value(x.Expr, require(partial, scalarKnown))
463 if isError(v) {
464 return v
465 }
466
467 switch k := v.Kind(); k {
468 case IntKind, FloatKind, NumKind, StringKind, BytesKind:
469 case NullKind:
470 if x.Op != NotEqualOp {
471 err := ctx.NewPosf(pos(x.Expr),
472 "cannot use null for bound %s", x.Op)
473 return &Bottom{Err: err}
474 }
475 default:
476 mask := IntKind | FloatKind | NumKind | StringKind | BytesKind
477 if x.Op == NotEqualOp {
478 mask |= NullKind
479 }
480 if k&mask != 0 {
481 ctx.addErrf(IncompleteError, token.NoPos,
482 "non-concrete value %s for bound %s", x.Expr, x.Op)
483 return nil
484 }
485 err := ctx.NewPosf(pos(x.Expr),
486 "invalid value %s (type %s) for bound %s", v, k, x.Op)
487 return &Bottom{Err: err}
488 }
489
490 if v, ok := x.Expr.(Value); ok {
491 if v == nil || v.Concreteness() > Concrete {
492 return ctx.NewErrf("bound has fixed non-concrete value")
493 }
494 return &BoundValue{x.Src, x.Op, v}
495 }
496
497
498
499
500
501
502
503
504 switch y := v.(type) {
505 case *BoundValue:
506 switch {
507 case y.Op == NotEqualOp:
508 switch x.Op {
509 case LessEqualOp, LessThanOp, GreaterEqualOp, GreaterThanOp:
510
511
512 return &BasicType{K: y.Kind()}
513 case NotEqualOp:
514
515
516
517 return y.Value
518 }
519
520 case x.Op == NotEqualOp:
521
522 switch y.Op {
523 case LessEqualOp:
524 return &BoundValue{x.Src, GreaterThanOp, y.Value}
525 case LessThanOp:
526 return &BoundValue{x.Src, GreaterEqualOp, y.Value}
527 case GreaterEqualOp:
528 return &BoundValue{x.Src, LessThanOp, y.Value}
529 case GreaterThanOp:
530 return &BoundValue{x.Src, LessEqualOp, y.Value}
531 }
532
533 case (x.Op == LessThanOp || x.Op == LessEqualOp) &&
534 (y.Op == GreaterThanOp || y.Op == GreaterEqualOp),
535 (x.Op == GreaterThanOp || x.Op == GreaterEqualOp) &&
536 (y.Op == LessThanOp || y.Op == LessEqualOp):
537
538
539 return &BasicType{K: y.Kind()}
540
541 case x.Op == LessThanOp &&
542 (y.Op == LessEqualOp || y.Op == LessThanOp),
543 x.Op == GreaterThanOp &&
544 (y.Op == GreaterEqualOp || y.Op == GreaterThanOp):
545
546
547
548 return &BoundValue{x.Src, x.Op, y.Value}
549
550 case x.Op == LessEqualOp &&
551 (y.Op == LessEqualOp || y.Op == LessThanOp),
552 x.Op == GreaterEqualOp &&
553 (y.Op == GreaterEqualOp || y.Op == GreaterThanOp):
554
555
556
557 return y
558 }
559
560 case *BasicType:
561 switch x.Op {
562 case LessEqualOp, LessThanOp, GreaterEqualOp, GreaterThanOp:
563
564
565 ctx.addErrf(IncompleteError, token.NoPos,
566 "non-concrete value %s for bound %s", x.Expr, x.Op)
567 return nil
568 }
569 }
570 if v.Concreteness() > Concrete {
571
572 ctx.addErrf(IncompleteError, token.NoPos,
573 "non-concrete value %s for bound %s", x.Expr, x.Op)
574 return nil
575 }
576 return &BoundValue{x.Src, x.Op, v}
577 }
578
579
580
581
582
583
584 type BoundValue struct {
585 Src ast.Expr
586 Op Op
587 Value Value
588 }
589
590 func (x *BoundValue) Source() ast.Node { return x.Src }
591 func (x *BoundValue) Kind() Kind {
592 k := x.Value.Kind()
593 switch k {
594 case IntKind, FloatKind, NumKind:
595 return NumKind
596
597 case NullKind:
598 if x.Op == NotEqualOp {
599 return TopKind &^ NullKind
600 }
601 }
602 return k
603 }
604
605 func (x *BoundValue) validate(c *OpContext, y Value) *Bottom {
606 a := y
607 b := c.scalar(x.Value)
608 if c.HasErr() {
609 return c.Err()
610 }
611
612 switch v := BinOp(c, x.Op, a, b).(type) {
613 case *Bottom:
614 return v
615
616 case *Bool:
617 if v.B {
618 return nil
619 }
620
621
622 err := c.Newf("invalid value %v (out of bound %s)", y, x)
623 err.AddPosition(y)
624 return &Bottom{Src: c.src, Err: err, Code: EvalError}
625
626 default:
627 panic(fmt.Sprintf("unsupported type %T", v))
628 }
629 }
630
631 func (x *BoundValue) validateStr(c *OpContext, a string) bool {
632 if str, ok := x.Value.(*String); ok {
633 b := str.Str
634 switch x.Op {
635 case LessEqualOp:
636 return a <= b
637 case LessThanOp:
638 return a < b
639 case GreaterEqualOp:
640 return a >= b
641 case GreaterThanOp:
642 return a > b
643 case EqualOp:
644 return a == b
645 case NotEqualOp:
646 return a != b
647 case MatchOp:
648 return c.regexp(x.Value).MatchString(a)
649 case NotMatchOp:
650 return !c.regexp(x.Value).MatchString(a)
651 }
652 }
653 return x.validate(c, &String{Str: a}) == nil
654 }
655
656 func (x *BoundValue) validateInt(c *OpContext, a int64) bool {
657 switch n := x.Value.(type) {
658 case *Num:
659 b, err := n.X.Int64()
660 if err != nil {
661 break
662 }
663 switch x.Op {
664 case LessEqualOp:
665 return a <= b
666 case LessThanOp:
667 return a < b
668 case GreaterEqualOp:
669 return a >= b
670 case GreaterThanOp:
671 return a > b
672 case EqualOp:
673 return a == b
674 case NotEqualOp:
675 return a != b
676 }
677 }
678 return x.validate(c, c.NewInt64(a)) == nil
679 }
680
681
682
683
684
685 type NodeLink struct {
686 Node *Vertex
687 }
688
689 func (x *NodeLink) Kind() Kind {
690 return x.Node.Kind()
691 }
692 func (x *NodeLink) Source() ast.Node { return x.Node.Source() }
693
694 func (x *NodeLink) resolve(c *OpContext, state combinedFlags) *Vertex {
695 return x.Node
696 }
697
698
699
700
701 type FieldReference struct {
702 Src *ast.Ident
703 UpCount int32
704 Label Feature
705 }
706
707 func (x *FieldReference) Source() ast.Node {
708 if x.Src == nil {
709 return nil
710 }
711 return x.Src
712 }
713
714 func (x *FieldReference) resolve(c *OpContext, state combinedFlags) *Vertex {
715 n := c.relNode(x.UpCount)
716 pos := pos(x)
717 return c.lookup(n, pos, x.Label, state)
718 }
719
720
721
722
723
724
725 type ValueReference struct {
726 Src *ast.Ident
727 UpCount int32
728 Label Feature
729 }
730
731 func (x *ValueReference) Source() ast.Node {
732 if x.Src == nil {
733 return nil
734 }
735 return x.Src
736 }
737
738 func (x *ValueReference) resolve(c *OpContext, state combinedFlags) *Vertex {
739 if x.UpCount == 0 {
740 return c.vertex
741 }
742 n := c.relNode(x.UpCount - 1)
743 return n
744 }
745
746
747
748
749
750
751 type LabelReference struct {
752 Src *ast.Ident
753 UpCount int32
754 }
755
756
757
758 func (x *LabelReference) Source() ast.Node {
759 if x.Src == nil {
760 return nil
761 }
762 return x.Src
763 }
764
765 func (x *LabelReference) evaluate(ctx *OpContext, state combinedFlags) Value {
766 label := ctx.relLabel(x.UpCount)
767 if label == 0 {
768
769
770
771
772
773 return &BasicType{K: StringKind}
774 }
775 return label.ToValue(ctx)
776 }
777
778
779
780
781
782
783
784
785 type DynamicReference struct {
786 Src *ast.Ident
787 UpCount int32
788 Label Expr
789
790
791
792
793
794
795
796 Alias Feature
797 }
798
799 func (x *DynamicReference) Source() ast.Node {
800 if x.Src == nil {
801 return nil
802 }
803 return x.Src
804 }
805
806 func (x *DynamicReference) EvaluateLabel(ctx *OpContext, env *Environment) Feature {
807 env = env.up(ctx, x.UpCount)
808 frame := ctx.PushState(env, x.Src)
809 v := ctx.value(x.Label, require(partial, scalarKnown))
810 ctx.PopState(frame)
811 return ctx.Label(x, v)
812 }
813
814 func (x *DynamicReference) resolve(ctx *OpContext, state combinedFlags) *Vertex {
815 e := ctx.Env(x.UpCount)
816 frame := ctx.PushState(e, x.Src)
817 v := ctx.value(x.Label, require(partial, scalarKnown))
818 ctx.PopState(frame)
819 f := ctx.Label(x.Label, v)
820 return ctx.lookup(e.Vertex, pos(x), f, state)
821 }
822
823
824
825
826
827
828
829
830 type ImportReference struct {
831 Src *ast.Ident
832 ImportPath Feature
833 Label Feature
834 }
835
836 func (x *ImportReference) Source() ast.Node {
837 if x.Src == nil {
838 return nil
839 }
840 return x.Src
841 }
842
843 func (x *ImportReference) resolve(ctx *OpContext, state combinedFlags) *Vertex {
844 path := x.ImportPath.StringValue(ctx)
845 v := ctx.Runtime.LoadImport(path)
846 if v == nil {
847 ctx.addErrf(EvalError, x.Src.Pos(), "cannot find package %q", path)
848 }
849 return v
850 }
851
852
853
854
855
856
857 type LetReference struct {
858 Src *ast.Ident
859 UpCount int32
860 Label Feature
861 X Expr
862 }
863
864 func (x *LetReference) Source() ast.Node {
865 if x.Src == nil {
866 return nil
867 }
868 return x.Src
869 }
870
871 func (x *LetReference) resolve(ctx *OpContext, state combinedFlags) *Vertex {
872 e := ctx.Env(x.UpCount)
873 n := e.Vertex
874
875
876
877
878 if n.status < evaluating && !ctx.isDevVersion() {
879 panic("unexpected node state < Evaluating")
880 }
881
882 arc := ctx.lookup(n, pos(x), x.Label, state)
883 if arc == nil {
884 return nil
885 }
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911 arc.Finalize(ctx)
912 b, ok := arc.BaseValue.(*Bottom)
913 if !arc.MultiLet && !ok {
914 return arc
915 }
916
917
918
919
920 c := arc.Conjuncts[0]
921 expr := c.Expr()
922 key := cacheKey{expr, arc}
923 v, ok := e.cache[key]
924 if !ok {
925
926
927 c.Env = e
928 c.x = expr
929
930 if e.cache == nil {
931 e.cache = map[cacheKey]Value{}
932 }
933 n := &Vertex{
934 Parent: arc.Parent,
935 Label: x.Label,
936 IsDynamic: b != nil && b.Code == StructuralCycleError,
937 Conjuncts: []Conjunct{c},
938 }
939 v = n
940 e.cache[key] = n
941 if ctx.isDevVersion() {
942 nc := n.getState(ctx)
943 nc.hasNonCycle = true
944 nc.free()
945 } else {
946 nc := n.getNodeContext(ctx, 0)
947 nc.hasNonCycle = true
948 }
949
950
951
952
953
954
955
956
957
958
959 n.setParentDone()
960 }
961 return v.(*Vertex)
962 }
963
964
965
966
967 type SelectorExpr struct {
968 Src *ast.SelectorExpr
969 X Expr
970 Sel Feature
971 }
972
973 func (x *SelectorExpr) Source() ast.Node {
974 if x.Src == nil {
975 return nil
976 }
977 return x.Src
978 }
979
980 func (x *SelectorExpr) resolve(c *OpContext, state combinedFlags) *Vertex {
981
982
983
984
985
986 n := c.node(x, x.X, x.Sel.IsRegular(), attempt(partial, needFieldSetKnown))
987 if n == emptyNode {
988 return n
989 }
990 if n.status == partial && !c.isDevVersion() {
991 if b := n.state.incompleteErrors(false); b != nil && b.Code < CycleError {
992 c.AddBottom(b)
993 return n
994 }
995 }
996
997
998
999
1000 pos := x.Src.Sel.Pos()
1001 return c.lookup(n, pos, x.Sel, state)
1002 }
1003
1004
1005
1006
1007 type IndexExpr struct {
1008 Src *ast.IndexExpr
1009 X Expr
1010 Index Expr
1011 }
1012
1013 func (x *IndexExpr) Source() ast.Node {
1014 if x.Src == nil {
1015 return nil
1016 }
1017 return x.Src
1018 }
1019
1020 func (x *IndexExpr) resolve(ctx *OpContext, state combinedFlags) *Vertex {
1021
1022
1023
1024
1025
1026 n := ctx.node(x, x.X, true, attempt(partial, needFieldSetKnown))
1027 i := ctx.value(x.Index, require(partial, scalarKnown))
1028 if n == emptyNode {
1029 return n
1030 }
1031 if n.status == partial && !ctx.isDevVersion() {
1032 if b := n.state.incompleteErrors(false); b != nil && b.Code < CycleError {
1033 ctx.AddBottom(b)
1034 return n
1035 }
1036 }
1037
1038
1039
1040
1041 f := ctx.Label(x.Index, i)
1042
1043
1044
1045
1046
1047
1048 if ctx.errs != nil {
1049 return nil
1050 }
1051 pos := x.Src.Index.Pos()
1052 return ctx.lookup(n, pos, f, state)
1053 }
1054
1055
1056
1057
1058 type SliceExpr struct {
1059 Src *ast.SliceExpr
1060 X Expr
1061 Lo Expr
1062 Hi Expr
1063 Stride Expr
1064 }
1065
1066 func (x *SliceExpr) Source() ast.Node {
1067 if x.Src == nil {
1068 return nil
1069 }
1070 return x.Src
1071 }
1072
1073 func (x *SliceExpr) evaluate(c *OpContext, state combinedFlags) Value {
1074
1075
1076 v := c.value(x.X, require(partial, fieldSetKnown))
1077 const as = "slice index"
1078
1079 switch v := v.(type) {
1080 case nil:
1081 c.addErrf(IncompleteError, c.pos(), "non-concrete slice subject %s", x.X)
1082 return nil
1083 case *Vertex:
1084 if !v.IsList() {
1085 break
1086 }
1087
1088 var (
1089 lo = uint64(0)
1090 hi = uint64(len(v.Arcs))
1091 )
1092 if x.Lo != nil {
1093 lo = c.uint64(c.value(x.Lo, require(partial, scalarKnown)), as)
1094 }
1095 if x.Hi != nil {
1096 hi = c.uint64(c.value(x.Hi, require(partial, scalarKnown)), as)
1097 if hi > uint64(len(v.Arcs)) {
1098 return c.NewErrf("index %d out of range", hi)
1099 }
1100 }
1101 if lo > hi {
1102 return c.NewErrf("invalid slice index: %d > %d", lo, hi)
1103 }
1104
1105 n := c.newList(c.src, v.Parent)
1106 for i, a := range v.Arcs[lo:hi] {
1107 label, err := MakeLabel(a.Source(), int64(i), IntLabel)
1108 if err != nil {
1109 c.AddBottom(&Bottom{Src: a.Source(), Err: err})
1110 return nil
1111 }
1112 arc := *a
1113 arc.Parent = n
1114 arc.Label = label
1115 n.Arcs = append(n.Arcs, &arc)
1116 }
1117 n.status = finalized
1118 return n
1119
1120 case *Bytes:
1121 var (
1122 lo = uint64(0)
1123 hi = uint64(len(v.B))
1124 )
1125 if x.Lo != nil {
1126 lo = c.uint64(c.value(x.Lo, require(partial, scalarKnown)), as)
1127 }
1128 if x.Hi != nil {
1129 hi = c.uint64(c.value(x.Hi, require(partial, scalarKnown)), as)
1130 if hi > uint64(len(v.B)) {
1131 return c.NewErrf("index %d out of range", hi)
1132 }
1133 }
1134 if lo > hi {
1135 return c.NewErrf("invalid slice index: %d > %d", lo, hi)
1136 }
1137 return c.newBytes(v.B[lo:hi])
1138 }
1139
1140 if isError(v) {
1141 return v
1142 }
1143 return c.NewErrf("cannot slice %v (type %s)", v, v.Kind())
1144 }
1145
1146
1147
1148
1149 type Interpolation struct {
1150 Src *ast.Interpolation
1151 K Kind
1152 Parts []Expr
1153 }
1154
1155 func (x *Interpolation) Source() ast.Node {
1156 if x.Src == nil {
1157 return nil
1158 }
1159 return x.Src
1160 }
1161
1162 func (x *Interpolation) evaluate(c *OpContext, state combinedFlags) Value {
1163 buf := bytes.Buffer{}
1164 for _, e := range x.Parts {
1165 v := c.value(e, require(partial, scalarKnown))
1166 if x.K == BytesKind {
1167 buf.Write(c.ToBytes(v))
1168 } else {
1169 buf.WriteString(c.ToString(v))
1170 }
1171 }
1172 if err := c.Err(); err != nil {
1173 err = &Bottom{
1174 Code: err.Code,
1175 Err: errors.Wrapf(err.Err, pos(x), "invalid interpolation"),
1176 }
1177
1178
1179 return err
1180 }
1181 if x.K == BytesKind {
1182 return &Bytes{x.Src, buf.Bytes(), nil}
1183 }
1184 return &String{x.Src, buf.String(), nil}
1185 }
1186
1187
1188
1189
1190
1191 type UnaryExpr struct {
1192 Src *ast.UnaryExpr
1193 Op Op
1194 X Expr
1195 }
1196
1197 func (x *UnaryExpr) Source() ast.Node {
1198 if x.Src == nil {
1199 return nil
1200 }
1201 return x.Src
1202 }
1203
1204 func (x *UnaryExpr) evaluate(c *OpContext, state combinedFlags) Value {
1205 if !c.concreteIsPossible(x.Op, x.X) {
1206 return nil
1207 }
1208 v := c.value(x.X, require(partial, scalarKnown))
1209 if isError(v) {
1210 return v
1211 }
1212
1213 op := x.Op
1214 k := kind(v)
1215 expectedKind := k
1216 switch op {
1217 case SubtractOp:
1218 if v, ok := v.(*Num); ok {
1219 f := *v
1220 f.X.Neg(&v.X)
1221 f.Src = x.Src
1222 return &f
1223 }
1224 expectedKind = NumKind
1225
1226 case AddOp:
1227 if v, ok := v.(*Num); ok {
1228
1229 return v
1230 }
1231 expectedKind = NumKind
1232
1233 case NotOp:
1234 if v, ok := v.(*Bool); ok {
1235 return &Bool{x.Src, !v.B}
1236 }
1237 expectedKind = BoolKind
1238 }
1239 if k&expectedKind != BottomKind {
1240 c.addErrf(IncompleteError, pos(x.X),
1241 "operand %s of '%s' not concrete (was %s)", x.X, op, k)
1242 return nil
1243 }
1244 return c.NewErrf("invalid operation %v (%s %s)", x, op, k)
1245 }
1246
1247
1248
1249
1250
1251 type BinaryExpr struct {
1252 Src *ast.BinaryExpr
1253 Op Op
1254 X Expr
1255 Y Expr
1256 }
1257
1258 func (x *BinaryExpr) Source() ast.Node {
1259 if x.Src == nil {
1260 return nil
1261 }
1262 return x.Src
1263 }
1264
1265 func (x *BinaryExpr) evaluate(c *OpContext, state combinedFlags) Value {
1266 env := c.Env(0)
1267 if x.Op == AndOp {
1268 v := c.newInlineVertex(nil, nil, makeAnonymousConjunct(env, x, c.ci.Refs))
1269
1270
1271
1272
1273
1274
1275
1276
1277 if env.Vertex.IsDynamic || c.inValidator > 0 {
1278 v.Finalize(c)
1279 } else {
1280 v.CompleteArcs(c)
1281 }
1282
1283 return v
1284 }
1285
1286 if !c.concreteIsPossible(x.Op, x.X) || !c.concreteIsPossible(x.Op, x.Y) {
1287 return nil
1288 }
1289
1290
1291
1292
1293
1294 if x.Op == EqualOp || x.Op == NotEqualOp {
1295 if isLiteralBottom(x.X) {
1296 return c.validate(env, x.Src, x.Y, x.Op, state)
1297 }
1298 if isLiteralBottom(x.Y) {
1299 return c.validate(env, x.Src, x.X, x.Op, state)
1300 }
1301 }
1302
1303 left, _ := c.concrete(env, x.X, x.Op)
1304 right, _ := c.concrete(env, x.Y, x.Op)
1305
1306 if err := CombineErrors(x.Src, left, right); err != nil {
1307 return err
1308 }
1309
1310 if err := c.Err(); err != nil {
1311 return err
1312 }
1313
1314 return BinOp(c, x.Op, left, right)
1315 }
1316
1317 func (c *OpContext) validate(env *Environment, src ast.Node, x Expr, op Op, flags combinedFlags) (r Value) {
1318 state := flags.vertexStatus()
1319
1320 s := c.PushState(env, src)
1321
1322 match := op != EqualOp
1323
1324
1325 c.inValidator++
1326 req := flags
1327 req = final(state, needTasksDone)
1328 v := c.evalState(x, req)
1329 c.inValidator--
1330 u, _ := c.getDefault(v)
1331 u = Unwrap(u)
1332
1333
1334
1335
1336
1337 if u != nil && u.Kind().IsAnyOf(StructKind|ListKind) {
1338 u = v
1339 }
1340
1341 switch v := u.(type) {
1342 case nil:
1343 case *Bottom:
1344 switch v.Code {
1345 case CycleError:
1346 c.PopState(s)
1347 c.AddBottom(v)
1348
1349
1350 return nil
1351
1352 case IncompleteError:
1353 c.evalState(x, oldOnly(finalized))
1354
1355
1356
1357 c.verifyNonMonotonicResult(env, x, true)
1358 }
1359
1360 match = op == EqualOp
1361
1362 case *Vertex:
1363
1364
1365
1366
1367
1368
1369
1370 v.Finalize(c)
1371
1372 if v.status == evaluatingArcs {
1373
1374
1375
1376
1377
1378
1379
1380 c.verifyNonMonotonicResult(env, x, true)
1381 match = op == EqualOp
1382 break
1383 }
1384
1385 switch {
1386 case !v.IsDefined(c):
1387 c.verifyNonMonotonicResult(env, x, true)
1388
1389
1390
1391
1392
1393 match = op == EqualOp
1394
1395 case isFinalError(v):
1396
1397
1398 match = op == EqualOp
1399 }
1400
1401 default:
1402 if v.Kind().IsAnyOf(CompositKind) && v.Concreteness() > Concrete && state < conjuncts {
1403 c.PopState(s)
1404 c.AddBottom(cycle)
1405 return nil
1406 }
1407
1408 c.verifyNonMonotonicResult(env, x, false)
1409
1410 if v.Concreteness() > Concrete {
1411
1412
1413
1414
1415 match = op == EqualOp
1416 }
1417
1418 c.evalState(x, require(state, needTasksDone))
1419 }
1420
1421 c.PopState(s)
1422 return &Bool{src, match}
1423 }
1424
1425 func isFinalError(n *Vertex) bool {
1426 n = n.Indirect()
1427 if b, ok := Unwrap(n).(*Bottom); ok && b.Code < IncompleteError {
1428 return true
1429 }
1430 return false
1431 }
1432
1433
1434
1435
1436
1437
1438 func (c *OpContext) verifyNonMonotonicResult(env *Environment, x Expr, expectError bool) {
1439 if n := env.Vertex.state; n != nil {
1440 n.postChecks = append(n.postChecks, envCheck{
1441 env: env,
1442 expr: x,
1443 expectError: expectError,
1444 })
1445 }
1446 }
1447
1448
1449
1450
1451
1452 type CallExpr struct {
1453 Src *ast.CallExpr
1454 Fun Expr
1455 Args []Expr
1456 }
1457
1458 func (x *CallExpr) Source() ast.Node {
1459 if x.Src == nil {
1460 return nil
1461 }
1462 return x.Src
1463 }
1464
1465 func (x *CallExpr) evaluate(c *OpContext, state combinedFlags) Value {
1466 fun := c.value(x.Fun, require(partial, concreteKnown))
1467 var b *Builtin
1468 switch f := fun.(type) {
1469 case *Builtin:
1470 b = f
1471
1472 case *BuiltinValidator:
1473
1474
1475 switch {
1476 case f.Src != nil:
1477 c.AddErrf("cannot call previously called validator %s", x.Fun)
1478
1479 case f.Builtin.IsValidator(len(x.Args)):
1480 v := *f
1481 v.Src = x
1482 return &v
1483
1484 default:
1485 b = f.Builtin
1486 }
1487
1488 default:
1489 c.AddErrf("cannot call non-function %s (type %s)", x.Fun, kind(fun))
1490 return nil
1491 }
1492 args := []Value{}
1493 for i, a := range x.Args {
1494 saved := c.errs
1495 c.errs = nil
1496
1497
1498 runMode := state.runMode()
1499 cond := state.conditions() | allAncestorsProcessed | concreteKnown
1500 state = combineMode(cond, runMode).withVertexStatus(state.vertexStatus())
1501
1502 expr := c.value(a, state)
1503
1504 switch v := expr.(type) {
1505 case nil:
1506 if c.errs == nil {
1507
1508
1509 c.Assertf(pos(x.Fun), c.HasErr(),
1510 "argument %d to function %s is incomplete", i, x.Fun)
1511 }
1512
1513 case *Bottom:
1514
1515 c.errs = CombineErrors(a.Source(), c.errs, v)
1516
1517 default:
1518 args = append(args, expr)
1519 }
1520 c.errs = CombineErrors(a.Source(), saved, c.errs)
1521 }
1522 if c.HasErr() {
1523 return nil
1524 }
1525 if b.IsValidator(len(args)) {
1526 return &BuiltinValidator{x, b, args}
1527 }
1528 result := b.call(c, pos(x), false, args)
1529 if result == nil {
1530 return nil
1531 }
1532 return c.evalState(result, state.withVertexStatus(partial))
1533 }
1534
1535
1536 type Builtin struct {
1537
1538 Params []Param
1539 Result Kind
1540 Func func(c *OpContext, args []Value) Expr
1541
1542 Package Feature
1543 Name string
1544 }
1545
1546 type Param struct {
1547 Name Feature
1548 Value Value
1549 }
1550
1551
1552 func (p Param) Kind() Kind {
1553 return p.Value.Kind()
1554 }
1555
1556
1557 func (p Param) Default() Value {
1558 d, ok := p.Value.(*Disjunction)
1559 if !ok || d.NumDefaults != 1 {
1560 return nil
1561 }
1562 return d.Values[0]
1563 }
1564
1565 func (x *Builtin) WriteName(w io.Writer, c *OpContext) {
1566 _, _ = fmt.Fprintf(w, "%s.%s", x.Package.StringValue(c), x.Name)
1567 }
1568
1569
1570 func (x *Builtin) Kind() Kind {
1571 return FuncKind
1572 }
1573
1574 func (x *Builtin) BareValidator() *BuiltinValidator {
1575 if len(x.Params) != 1 ||
1576 (x.Result != BoolKind && x.Result != BottomKind) {
1577 return nil
1578 }
1579 return &BuiltinValidator{Builtin: x}
1580 }
1581
1582
1583
1584 func (b *Builtin) IsValidator(numArgs int) bool {
1585 return numArgs == len(b.Params)-1 &&
1586 b.Result&^BoolKind == 0 &&
1587 b.Params[numArgs].Default() == nil
1588 }
1589
1590 func bottom(v Value) *Bottom {
1591 if x, ok := v.(*Vertex); ok {
1592 v = x.Value()
1593 }
1594 b, _ := v.(*Bottom)
1595 return b
1596 }
1597
1598 func (x *Builtin) call(c *OpContext, p token.Pos, validate bool, args []Value) Expr {
1599 fun := x
1600 if len(args) > len(x.Params) {
1601 c.addErrf(0, p,
1602 "too many arguments in call to %v (have %d, want %d)",
1603 fun, len(args), len(x.Params))
1604 return nil
1605 }
1606 for i := len(args); i < len(x.Params); i++ {
1607 v := x.Params[i].Default()
1608 if v == nil {
1609 c.addErrf(0, p,
1610 "not enough arguments in call to %v (have %d, want %d)",
1611 fun, len(args), len(x.Params))
1612 return nil
1613 }
1614 args = append(args, v)
1615 }
1616 for i, a := range args {
1617 if x.Params[i].Kind() == BottomKind {
1618 continue
1619 }
1620 if b := bottom(a); b != nil {
1621 return b
1622 }
1623 if k := kind(a); x.Params[i].Kind()&k == BottomKind {
1624 code := EvalError
1625 b, _ := args[i].(*Bottom)
1626 if b != nil {
1627 code = b.Code
1628 }
1629 c.addErrf(code, pos(a),
1630 "cannot use %s (type %s) as %s in argument %d to %v",
1631 a, k, x.Params[i].Kind(), i+1, fun)
1632 return nil
1633 }
1634 v := x.Params[i].Value
1635 if _, ok := v.(*BasicType); !ok {
1636 env := c.Env(0)
1637 x := &BinaryExpr{Op: AndOp, X: v, Y: a}
1638 n := c.newInlineVertex(nil, nil, Conjunct{env, x, c.ci})
1639 n.Finalize(c)
1640 if _, ok := n.BaseValue.(*Bottom); ok {
1641 c.addErrf(0, pos(a),
1642 "cannot use %s as %s in argument %d to %v",
1643 a, v, i+1, fun)
1644 return nil
1645 }
1646 args[i] = n
1647 }
1648 }
1649 saved := c.IsValidator
1650 c.IsValidator = validate
1651 ret := x.Func(c, args)
1652 c.IsValidator = saved
1653
1654 return ret
1655 }
1656
1657 func (x *Builtin) Source() ast.Node { return nil }
1658
1659
1660
1661
1662
1663 type BuiltinValidator struct {
1664 Src *CallExpr
1665 Builtin *Builtin
1666 Args []Value
1667 }
1668
1669 func (x *BuiltinValidator) Source() ast.Node {
1670 if x.Src == nil {
1671 return x.Builtin.Source()
1672 }
1673 return x.Src.Source()
1674 }
1675
1676 func (x *BuiltinValidator) Pos() token.Pos {
1677 if src := x.Source(); src != nil {
1678 return src.Pos()
1679 }
1680 return token.NoPos
1681 }
1682
1683 func (x *BuiltinValidator) Kind() Kind {
1684 return x.Builtin.Params[0].Kind()
1685 }
1686
1687 func (x *BuiltinValidator) validate(c *OpContext, v Value) *Bottom {
1688 args := make([]Value, len(x.Args)+1)
1689 args[0] = v
1690 copy(args[1:], x.Args)
1691
1692 return validateWithBuiltin(c, x.Pos(), x.Builtin, args)
1693 }
1694
1695 func validateWithBuiltin(c *OpContext, src token.Pos, b *Builtin, args []Value) *Bottom {
1696 var severeness ErrorCode
1697 var err errors.Error
1698
1699 res := b.call(c, src, true, args)
1700 switch v := res.(type) {
1701 case nil:
1702 return nil
1703
1704 case *Bottom:
1705 if v == nil {
1706 return nil
1707 }
1708 severeness = v.Code
1709 err = v.Err
1710
1711 case *Bool:
1712 if v.B {
1713 return nil
1714 }
1715
1716 default:
1717 return c.NewErrf("invalid validator %s.%s", b.Package.StringValue(c), b.Name)
1718 }
1719
1720
1721 var buf bytes.Buffer
1722 b.WriteName(&buf, c)
1723 if len(args) > 1 {
1724 buf.WriteString("(")
1725 for i, a := range args[1:] {
1726 if i > 0 {
1727 _, _ = buf.WriteString(", ")
1728 }
1729 buf.WriteString(c.Str(a))
1730 }
1731 buf.WriteString(")")
1732 }
1733
1734
1735
1736 if b, ok := Unwrap(args[0]).(*Bottom); ok {
1737 return b
1738 }
1739
1740 vErr := c.NewPosf(src, "invalid value %s (does not satisfy %s)", args[0], buf.String())
1741
1742 for _, v := range args {
1743 vErr.AddPosition(v)
1744 }
1745
1746 return &Bottom{Code: severeness, Err: errors.Wrap(vErr, err)}
1747 }
1748
1749
1750
1751 type DisjunctionExpr struct {
1752 Src *ast.BinaryExpr
1753 Values []Disjunct
1754
1755 HasDefaults bool
1756 }
1757
1758
1759 type Disjunct struct {
1760 Val Expr
1761 Default bool
1762 }
1763
1764 func (x *DisjunctionExpr) Source() ast.Node {
1765 if x.Src == nil {
1766 return nil
1767 }
1768 return x.Src
1769 }
1770
1771 func (x *DisjunctionExpr) evaluate(c *OpContext, state combinedFlags) Value {
1772 e := c.Env(0)
1773 v := c.newInlineVertex(nil, nil, Conjunct{e, x, c.ci})
1774 v.Finalize(c)
1775
1776
1777 return v
1778 }
1779
1780
1781
1782 type Conjunction struct {
1783 Src ast.Expr
1784 Values []Value
1785 }
1786
1787 func (x *Conjunction) Source() ast.Node { return x.Src }
1788 func (x *Conjunction) Kind() Kind {
1789 k := TopKind
1790 for _, v := range x.Values {
1791 k &= v.Kind()
1792 }
1793 return k
1794 }
1795
1796
1797
1798 type Disjunction struct {
1799 Src ast.Expr
1800
1801
1802
1803 Values []Value
1804
1805 Errors *Bottom
1806
1807
1808 NumDefaults int
1809 HasDefaults bool
1810 }
1811
1812 func (x *Disjunction) Source() ast.Node { return x.Src }
1813 func (x *Disjunction) Kind() Kind {
1814 k := BottomKind
1815 for _, v := range x.Values {
1816 k |= v.Kind()
1817 }
1818 return k
1819 }
1820
1821 type Comprehension struct {
1822 Syntax ast.Node
1823
1824
1825
1826 Clauses []Yielder
1827
1828
1829
1830
1831
1832 Value Node
1833
1834
1835 arcType ArcType
1836
1837
1838 comp *envComprehension
1839 parent *Comprehension
1840 arc *Vertex
1841 }
1842
1843
1844 func (c *Comprehension) Nest() int {
1845 count := 0
1846 for ; c.parent != nil; c = c.parent {
1847 count++
1848 }
1849 return count
1850 }
1851
1852
1853
1854
1855 func (c *Comprehension) Envs() []*Environment {
1856 if c.comp == nil {
1857 return nil
1858 }
1859 return c.comp.envs
1860 }
1861
1862
1863
1864 func (x *Comprehension) DidResolve() bool {
1865 return x.comp.done && len(x.comp.envs) > 0
1866 }
1867
1868 func (x *Comprehension) Source() ast.Node {
1869 if x.Syntax == nil {
1870 return nil
1871 }
1872 return x.Syntax
1873 }
1874
1875
1876
1877
1878
1879 type ForClause struct {
1880 Syntax *ast.ForClause
1881 Key Feature
1882 Value Feature
1883 Src Expr
1884 }
1885
1886 func (x *ForClause) Source() ast.Node {
1887 if x.Syntax == nil {
1888 return nil
1889 }
1890 return x.Syntax
1891 }
1892
1893 func (c *OpContext) forSource(x Expr) *Vertex {
1894 state := require(conjuncts, needFieldSetKnown)
1895
1896
1897
1898 v := c.unifyNode(x, state)
1899
1900 node, ok := v.(*Vertex)
1901 if ok && c.isDevVersion() {
1902 node.unify(c, state.conditions(), yield)
1903 }
1904
1905 v, ok = c.getDefault(v)
1906
1907 if !ok {
1908
1909 return emptyNode
1910 }
1911
1912
1913 if w := Unwrap(v); !isCyclePlaceholder(w) {
1914 v = w
1915 }
1916 node, ok = v.(*Vertex)
1917 if ok && !isCyclePlaceholder(node.BaseValue) {
1918 v = node.Value()
1919 }
1920
1921 switch nv := v.(type) {
1922 case nil:
1923 c.addErrf(IncompleteError, pos(x),
1924 "cannot range over %s (incomplete)", x)
1925 return emptyNode
1926
1927 case *Bottom:
1928
1929
1930
1931 c.AddBottom(nv)
1932 return emptyNode
1933
1934 case *Vertex:
1935 if node == nil {
1936 panic("unexpected markers with nil node")
1937 }
1938
1939 default:
1940 if kind := v.Kind(); kind&StructKind != 0 {
1941 c.addErrf(IncompleteError, pos(x),
1942 "cannot range over %s (incomplete type %s)", x, kind)
1943 return emptyNode
1944
1945 } else if !ok {
1946 c.addErrf(0, pos(x),
1947 "cannot range over %s (found %s, want list or struct)",
1948 x.Source(), v.Kind())
1949 return emptyNode
1950 }
1951 }
1952
1953 return node
1954 }
1955
1956 func (x *ForClause) yield(s *compState) {
1957 c := s.ctx
1958 n := c.forSource(x.Src)
1959
1960 if c.isDevVersion() {
1961 if s := n.getState(c); s != nil {
1962 s.freeze(fieldSetKnown)
1963 }
1964 } else {
1965 if n.status == evaluating && !n.LockArcs {
1966 c.AddBottom(&Bottom{
1967 Code: CycleError,
1968 ForCycle: true,
1969 Value: n,
1970 Err: errors.Newf(pos(x.Src), "comprehension source references itself"),
1971 })
1972 return
1973 }
1974 if c.HasErr() {
1975 return
1976 }
1977 n.LockArcs = true
1978 }
1979
1980 for _, a := range n.Arcs {
1981 if !a.Label.IsRegular() {
1982 continue
1983 }
1984
1985 if c.isDevVersion() {
1986 c.require(a, arcTypeKnown)
1987 } else {
1988 if !a.isDefined() {
1989 a.Finalize(c)
1990 }
1991 if !a.definitelyExists() {
1992 continue
1993 }
1994 }
1995
1996 switch a.ArcType {
1997 case ArcMember:
1998 case ArcRequired:
1999 c.AddBottom(newRequiredFieldInComprehensionError(c, x, a))
2000 continue
2001 default:
2002 continue
2003 }
2004
2005 n := &Vertex{
2006 Parent: c.Env(0).Vertex,
2007
2008
2009
2010
2011 status: finalized,
2012 IsDynamic: true,
2013 ArcType: ArcMember,
2014 }
2015
2016 if x.Value != InvalidLabel {
2017 b := &Vertex{
2018 Label: x.Value,
2019 BaseValue: a,
2020 IsDynamic: true,
2021 ArcType: ArcPending,
2022 }
2023 n.Arcs = append(n.Arcs, b)
2024 }
2025
2026 if x.Key != InvalidLabel {
2027 v := &Vertex{
2028 Label: x.Key,
2029 IsDynamic: true,
2030 }
2031 key := a.Label.ToValue(c)
2032 v.AddConjunct(MakeRootConjunct(c.Env(0), key))
2033 v.SetValue(c, key)
2034 n.Arcs = append(n.Arcs, v)
2035 }
2036
2037 sub := c.spawn(n)
2038 if !s.yield(sub) {
2039 break
2040 }
2041 }
2042 }
2043
2044
2045
2046
2047
2048 type IfClause struct {
2049 Src *ast.IfClause
2050 Condition Expr
2051 }
2052
2053 func (x *IfClause) Source() ast.Node {
2054 if x.Src == nil {
2055 return nil
2056 }
2057 return x.Src
2058 }
2059
2060 func (x *IfClause) yield(s *compState) {
2061 ctx := s.ctx
2062 if ctx.BoolValue(ctx.value(x.Condition, require(s.state, scalarKnown))) {
2063 s.yield(ctx.e)
2064 }
2065 }
2066
2067
2068
2069
2070 type LetClause struct {
2071 Src *ast.LetClause
2072 Label Feature
2073 Expr Expr
2074 }
2075
2076 func (x *LetClause) Source() ast.Node {
2077 if x.Src == nil {
2078 return nil
2079 }
2080 return x.Src
2081 }
2082
2083 func (x *LetClause) yield(s *compState) {
2084 c := s.ctx
2085 n := &Vertex{Arcs: []*Vertex{
2086 {
2087 Label: x.Label,
2088 IsDynamic: true,
2089 Conjuncts: []Conjunct{{c.Env(0), x.Expr, c.ci}},
2090 },
2091 }}
2092
2093 s.yield(c.spawn(n))
2094 }
2095
View as plain text