1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package compile
16
17 import (
18 "strings"
19
20 "cuelang.org/go/cue/ast"
21 "cuelang.org/go/cue/errors"
22 "cuelang.org/go/cue/literal"
23 "cuelang.org/go/cue/token"
24 "cuelang.org/go/internal"
25 "cuelang.org/go/internal/astinternal"
26 "cuelang.org/go/internal/core/adt"
27 )
28
29
30 type Scope interface {
31 Parent() Scope
32 Vertex() *adt.Vertex
33 }
34
35
36 type Config struct {
37
38
39
40 Scope Scope
41
42
43
44
45
46
47 Imports func(x *ast.Ident) (pkgPath string)
48
49
50
51 pkgPath string
52 }
53
54
55
56
57
58
59
60 func Files(cfg *Config, r adt.Runtime, pkgID string, files ...*ast.File) (*adt.Vertex, errors.Error) {
61 c := newCompiler(cfg, pkgID, r)
62
63 v := c.compileFiles(files)
64
65 if c.errs != nil {
66 return v, c.errs
67 }
68 return v, nil
69 }
70
71
72
73
74 func Expr(cfg *Config, r adt.Runtime, pkgPath string, x ast.Expr) (adt.Conjunct, errors.Error) {
75 c := newCompiler(cfg, pkgPath, r)
76
77 v := c.compileExpr(x)
78
79 if c.errs != nil {
80 return v, c.errs
81 }
82 return v, nil
83 }
84
85 func newCompiler(cfg *Config, pkgPath string, r adt.Runtime) *compiler {
86 c := &compiler{
87 index: r,
88 }
89 if cfg != nil {
90 c.Config = *cfg
91 }
92 if pkgPath == "" {
93 pkgPath = "_"
94 }
95 c.Config.pkgPath = pkgPath
96 return c
97 }
98
99 type compiler struct {
100 Config
101 upCountOffset int32
102
103 index adt.StringIndexer
104
105 stack []frame
106 inSelector int
107
108
109
110
111
112
113
114
115
116
117 refersToForVariable bool
118
119 fileScope map[adt.Feature]bool
120
121 num literal.NumInfo
122
123 errs errors.Error
124 }
125
126 func (c *compiler) reset() {
127 c.fileScope = nil
128 c.stack = c.stack[:0]
129 c.errs = nil
130 }
131
132 func (c *compiler) errf(n ast.Node, format string, args ...interface{}) *adt.Bottom {
133 err := &compilerError{
134 n: n,
135 path: c.path(),
136 Message: errors.NewMessagef(format, args...),
137 }
138 c.errs = errors.Append(c.errs, err)
139 return &adt.Bottom{Err: err}
140 }
141
142 func (c *compiler) path() []string {
143 a := []string{}
144 for _, f := range c.stack {
145 if f.label != nil {
146 a = append(a, f.label.labelString())
147 }
148 }
149 return a
150 }
151
152 type frame struct {
153 label labeler
154 scope ast.Node
155 field ast.Decl
156
157 upCount int32
158
159
160
161 isComprehensionVar bool
162
163 aliases map[string]aliasEntry
164 }
165
166 type aliasEntry struct {
167 label labeler
168 srcExpr ast.Expr
169 expr adt.Expr
170 source ast.Node
171 feature adt.Feature
172 used bool
173 }
174
175 func (c *compiler) insertAlias(id *ast.Ident, a aliasEntry) *adt.Bottom {
176 k := len(c.stack) - 1
177 m := c.stack[k].aliases
178 if m == nil {
179 m = map[string]aliasEntry{}
180 c.stack[k].aliases = m
181 }
182
183 if id == nil || !ast.IsValidIdent(id.Name) {
184 return c.errf(a.source, "invalid identifier name")
185 }
186
187 if e, ok := m[id.Name]; ok {
188 return c.errf(a.source,
189 "alias %q already declared; previous declaration at %s",
190 id.Name, e.source.Pos())
191 }
192 if id.Name == "_" {
193 return c.errf(id, "cannot use _ as alias or let clause")
194 }
195
196 m[id.Name] = a
197 return nil
198 }
199
200 func (c *compiler) updateAlias(id *ast.Ident, expr adt.Expr) {
201 k := len(c.stack) - 1
202 m := c.stack[k].aliases
203
204 x := m[id.Name]
205 x.expr = expr
206 x.label = nil
207 x.srcExpr = nil
208 m[id.Name] = x
209 }
210
211
212 func (c *compiler) lookupAlias(k int, id *ast.Ident) aliasEntry {
213 m := c.stack[k].aliases
214 name := id.Name
215 entry, ok := m[name]
216
217 if !ok {
218 err := c.errf(id, "could not find LetClause associated with identifier %q", name)
219 return aliasEntry{expr: err}
220 }
221
222 switch {
223 case entry.label != nil:
224
225
226 if entry.srcExpr == nil {
227 entry.expr = c.errf(id, "cyclic references in let clause or alias")
228 break
229 }
230
231 src := entry.srcExpr
232 entry.srcExpr = nil
233 m[name] = entry
234
235 entry.expr = c.labeledExprAt(k, nil, entry.label, src)
236 entry.label = nil
237 }
238
239 entry.used = true
240 m[name] = entry
241 return entry
242 }
243
244 func (c *compiler) pushScope(n labeler, upCount int32, id ast.Node) *frame {
245 c.stack = append(c.stack, frame{
246 label: n,
247 scope: id,
248 upCount: upCount,
249 })
250 return &c.stack[len(c.stack)-1]
251 }
252
253 func (c *compiler) popScope() {
254 k := len(c.stack) - 1
255 f := c.stack[k]
256 for k, v := range f.aliases {
257 if !v.used {
258 c.errf(v.source, "unreferenced alias or let clause %s", k)
259 }
260 }
261 c.stack = c.stack[:k]
262 }
263
264 func (c *compiler) compileFiles(a []*ast.File) *adt.Vertex {
265 c.fileScope = map[adt.Feature]bool{}
266 c.upCountOffset = 1
267
268
269
270
271
272
273
274
275
276
277 for _, f := range a {
278 if p := internal.GetPackageInfo(f); p.IsAnonymous() {
279 continue
280 }
281 for _, d := range f.Decls {
282 if f, ok := d.(*ast.Field); ok {
283 if id, ok := f.Label.(*ast.Ident); ok {
284 c.fileScope[c.label(id)] = true
285 }
286 }
287 }
288 }
289
290
291 res := &adt.Vertex{}
292
293
294
295 env := &adt.Environment{}
296 top := env
297
298 for p := c.Config.Scope; p != nil; p = p.Parent() {
299 top.Vertex = p.Vertex()
300 top.Up = &adt.Environment{}
301 top = top.Up
302 }
303
304 for _, file := range a {
305 c.pushScope(nil, 0, file)
306 v := &adt.StructLit{Src: file}
307 c.addDecls(v, file.Decls)
308 res.Conjuncts = append(res.Conjuncts, adt.MakeRootConjunct(env, v))
309 c.popScope()
310 }
311
312 return res
313 }
314
315 func (c *compiler) compileExpr(x ast.Expr) adt.Conjunct {
316 expr := c.expr(x)
317
318 env := &adt.Environment{}
319 top := env
320
321 for p := c.Config.Scope; p != nil; p = p.Parent() {
322 top.Vertex = p.Vertex()
323 top.Up = &adt.Environment{}
324 top = top.Up
325 }
326
327 return adt.MakeRootConjunct(env, expr)
328 }
329
330
331
332
333
334
335 func (c *compiler) resolve(n *ast.Ident) adt.Expr {
336
337
338 if imp, ok := n.Node.(*ast.ImportSpec); ok {
339 return &adt.ImportReference{
340 Src: n,
341 ImportPath: c.label(imp.Path),
342 Label: c.label(n),
343 }
344 }
345
346 label := c.label(n)
347
348 if label == adt.InvalidLabel {
349 return &adt.Top{Src: n}
350 }
351
352
353 if n.Node == nil {
354 upCount := int32(0)
355 for _, c := range c.stack {
356 upCount += c.upCount
357 }
358 if c.fileScope[label] {
359 return &adt.FieldReference{
360 Src: n,
361 UpCount: upCount,
362 Label: label,
363 }
364 }
365 upCount += c.upCountOffset
366 for p := c.Scope; p != nil; p = p.Parent() {
367 for _, a := range p.Vertex().Arcs {
368 switch {
369 case a.Label.IsLet() && a.Label.IdentString(c.index) == n.Name:
370 label = a.Label
371 case a.Label == label:
372 return &adt.FieldReference{
373 Src: n,
374 UpCount: upCount,
375 Label: label,
376 }
377 }
378 }
379 upCount++
380 }
381
382 if c.Config.Imports != nil {
383 if pkgPath := c.Config.Imports(n); pkgPath != "" {
384 return &adt.ImportReference{
385 Src: n,
386 ImportPath: adt.MakeStringLabel(c.index, pkgPath),
387 Label: c.label(n),
388 }
389 }
390 }
391
392 if p := predeclared(n); p != nil {
393 return p
394 }
395
396 return c.errf(n, "reference %q not found", n.Name)
397 }
398
399
400
401
402 if f, ok := n.Scope.(*ast.Field); ok {
403 upCount := int32(0)
404
405 k := len(c.stack) - 1
406 for ; k >= 0; k-- {
407 if c.stack[k].field == f {
408 break
409 }
410 upCount += c.stack[k].upCount
411 }
412
413 label := &adt.LabelReference{
414 Src: n,
415 UpCount: upCount,
416 }
417
418 switch f := n.Node.(type) {
419 case *ast.Field:
420 _ = c.lookupAlias(k, f.Label.(*ast.Alias).Ident)
421
422
423
424
425 label.UpCount = 0
426 return &adt.DynamicReference{
427 Src: n,
428 UpCount: upCount,
429 Label: label,
430 }
431
432 case *ast.Alias:
433 _ = c.lookupAlias(k, f.Ident)
434 return &adt.ValueReference{
435 Src: n,
436 UpCount: upCount,
437 Label: c.label(f.Ident),
438 }
439 }
440 return label
441 }
442
443 upCount := int32(0)
444
445 k := len(c.stack) - 1
446 for ; k >= 0; k-- {
447 if f := c.stack[k]; f.scope == n.Scope {
448 if f.isComprehensionVar {
449 c.refersToForVariable = true
450 }
451 break
452 }
453 upCount += c.stack[k].upCount
454 }
455 if k < 0 {
456
457
458
459 c.errf(n, "reference %q set to unknown node in AST; "+
460 "this can result from incorrect API usage or a compiler bug",
461 n.Name)
462 }
463
464 if n.Scope == nil {
465
466
467 return c.errf(n, "unresolved identifier %v", n.Name)
468 }
469
470 switch f := n.Node.(type) {
471
472 case *ast.LetClause:
473 entry := c.lookupAlias(k, n)
474 if entry.expr == nil {
475 panic("unreachable")
476 }
477 label = entry.feature
478
479
480 return &adt.LetReference{
481 Src: n,
482 UpCount: upCount,
483 Label: label,
484 X: entry.expr,
485 }
486
487
488
489 case *ast.Field:
490
491
492
493 a, ok := f.Label.(*ast.Alias)
494 if !ok {
495 return c.errf(n, "illegal reference %s", n.Name)
496 }
497 aliasInfo := c.lookupAlias(k, a.Ident)
498 lab, ok := a.Expr.(ast.Label)
499 if !ok {
500 return c.errf(a.Expr, "invalid label expression")
501 }
502 name, _, err := ast.LabelName(lab)
503 switch {
504 case errors.Is(err, ast.ErrIsExpression):
505 if aliasInfo.expr == nil {
506 panic("unreachable")
507 }
508 return &adt.DynamicReference{
509 Src: n,
510 UpCount: upCount,
511 Label: aliasInfo.expr,
512 }
513
514 case err != nil:
515 return c.errf(n, "invalid label: %v", err)
516
517 case name != "":
518 label = c.label(lab)
519
520 default:
521 return c.errf(n, "unsupported field alias %q", name)
522 }
523 }
524
525 return &adt.FieldReference{
526 Src: n,
527 UpCount: upCount,
528 Label: label,
529 }
530 }
531
532 func (c *compiler) addDecls(st *adt.StructLit, a []ast.Decl) {
533 for _, d := range a {
534 c.markAlias(d)
535 }
536 for _, d := range a {
537 c.addLetDecl(d)
538 }
539 for _, d := range a {
540 if x := c.decl(d); x != nil {
541 st.Decls = append(st.Decls, x)
542 }
543 }
544 }
545
546 func (c *compiler) markAlias(d ast.Decl) {
547 switch x := d.(type) {
548 case *ast.Field:
549 lab := x.Label
550 if a, ok := lab.(*ast.Alias); ok {
551 if _, ok = a.Expr.(ast.Label); !ok {
552 c.errf(a, "alias expression is not a valid label")
553 }
554
555 e := aliasEntry{source: a}
556
557 c.insertAlias(a.Ident, e)
558 }
559
560 case *ast.LetClause:
561 a := aliasEntry{
562 label: (*letScope)(x),
563 srcExpr: x.Expr,
564 source: x,
565 feature: adt.MakeLetLabel(c.index, x.Ident.Name),
566 }
567 c.insertAlias(x.Ident, a)
568
569 case *ast.Alias:
570 c.errf(x, "old-style alias no longer supported: use let clause; use cue fix to update.")
571 }
572 }
573
574 func (c *compiler) decl(d ast.Decl) adt.Decl {
575 switch x := d.(type) {
576 case *ast.BadDecl:
577 return c.errf(d, "")
578
579 case *ast.Field:
580 lab := x.Label
581 if a, ok := lab.(*ast.Alias); ok {
582 if lab, ok = a.Expr.(ast.Label); !ok {
583 return c.errf(a, "alias expression is not a valid label")
584 }
585 }
586
587 v := x.Value
588 var value adt.Expr
589 if a, ok := v.(*ast.Alias); ok {
590 c.pushScope(nil, 0, a)
591 c.insertAlias(a.Ident, aliasEntry{source: a})
592 value = c.labeledExpr(x, (*fieldLabel)(x), a.Expr)
593 c.popScope()
594 } else {
595 value = c.labeledExpr(x, (*fieldLabel)(x), v)
596 }
597
598 switch l := lab.(type) {
599 case *ast.Ident, *ast.BasicLit:
600 label := c.label(lab)
601
602 if label == adt.InvalidLabel {
603 return c.errf(x, "cannot use _ as label")
604 }
605
606 t, _ := internal.ConstraintToken(x)
607
608 return &adt.Field{
609 Src: x,
610 Label: label,
611 ArcType: adt.ConstraintFromToken(t),
612 Value: value,
613 }
614
615 case *ast.ListLit:
616 if len(l.Elts) != 1 {
617
618 return c.errf(x, "list label must have one element")
619 }
620 var label adt.Feature
621 elem := l.Elts[0]
622
623
624 if a, ok := elem.(*ast.Alias); ok {
625 label = c.label(a.Ident)
626 elem = a.Expr
627 }
628
629 return &adt.BulkOptionalField{
630 Src: x,
631 Filter: c.expr(elem),
632 Value: value,
633 Label: label,
634 }
635
636 case *ast.ParenExpr:
637 t, _ := internal.ConstraintToken(x)
638
639 return &adt.DynamicField{
640 Src: x,
641 Key: c.expr(l),
642 ArcType: adt.ConstraintFromToken(t),
643 Value: value,
644 }
645
646 case *ast.Interpolation:
647 t, _ := internal.ConstraintToken(x)
648
649 return &adt.DynamicField{
650 Src: x,
651 Key: c.expr(l),
652 ArcType: adt.ConstraintFromToken(t),
653 Value: value,
654 }
655 }
656
657 case *ast.LetClause:
658 m := c.stack[len(c.stack)-1].aliases
659 entry := m[x.Ident.Name]
660
661
662
663
664
665
666
667
668
669 savedUses := c.refersToForVariable
670 c.refersToForVariable = false
671 value := c.labeledExpr(x, (*letScope)(x), x.Expr)
672 refsCompVar := c.refersToForVariable
673 c.refersToForVariable = savedUses || refsCompVar
674
675 return &adt.LetField{
676 Src: x,
677 Label: entry.feature,
678 IsMulti: refsCompVar,
679 Value: value,
680 }
681
682
683
684 case *ast.CommentGroup:
685
686
687 case *ast.Attribute:
688
689
690 case *ast.Ellipsis:
691 return &adt.Ellipsis{
692 Src: x,
693 Value: c.expr(x.Type),
694 }
695
696 case *ast.Comprehension:
697 return c.comprehension(x, false)
698
699 case *ast.EmbedDecl:
700 return c.expr(x.Expr)
701
702 case ast.Expr:
703 return c.expr(x)
704 }
705 return nil
706 }
707
708 func (c *compiler) addLetDecl(d ast.Decl) {
709 switch x := d.(type) {
710 case *ast.Field:
711 lab := x.Label
712 if a, ok := lab.(*ast.Alias); ok {
713 if lab, ok = a.Expr.(ast.Label); !ok {
714
715 return
716 }
717
718 switch lab.(type) {
719 case *ast.Ident, *ast.BasicLit, *ast.ListLit:
720
721
722 default:
723 c.updateAlias(a.Ident, c.expr(a.Expr))
724 }
725 }
726
727 case *ast.Alias:
728 c.errf(x, "old-style alias no longer supported: use let clause; use cue fix to update.")
729 }
730 }
731
732 func (c *compiler) elem(n ast.Expr) adt.Elem {
733 switch x := n.(type) {
734 case *ast.Ellipsis:
735 return &adt.Ellipsis{
736 Src: x,
737 Value: c.expr(x.Type),
738 }
739
740 case *ast.Comprehension:
741 return c.comprehension(x, true)
742
743 case ast.Expr:
744 return c.expr(x)
745 }
746 return nil
747 }
748
749 func (c *compiler) comprehension(x *ast.Comprehension, inList bool) adt.Elem {
750 var a []adt.Yielder
751 for _, v := range x.Clauses {
752 switch x := v.(type) {
753 case *ast.ForClause:
754 var key adt.Feature
755 if x.Key != nil {
756 key = c.label(x.Key)
757 }
758 y := &adt.ForClause{
759 Syntax: x,
760 Key: key,
761 Value: c.label(x.Value),
762 Src: c.expr(x.Source),
763 }
764 f := c.pushScope((*forScope)(x), 1, v)
765 defer c.popScope()
766 f.isComprehensionVar = !inList
767 a = append(a, y)
768
769 case *ast.IfClause:
770 y := &adt.IfClause{
771 Src: x,
772 Condition: c.expr(x.Condition),
773 }
774 a = append(a, y)
775
776 case *ast.LetClause:
777
778
779 savedUses := c.refersToForVariable
780 c.refersToForVariable = false
781 expr := c.expr(x.Expr)
782 refsCompVar := c.refersToForVariable
783 c.refersToForVariable = savedUses || refsCompVar
784
785 y := &adt.LetClause{
786 Src: x,
787 Label: c.label(x.Ident),
788 Expr: expr,
789 }
790 f := c.pushScope((*letScope)(x), 1, v)
791 defer c.popScope()
792 f.isComprehensionVar = !inList && refsCompVar
793 a = append(a, y)
794 }
795
796 if _, ok := a[0].(*adt.LetClause); ok {
797 return c.errf(x,
798 "first comprehension clause must be 'if' or 'for'")
799 }
800 }
801
802
803 if y, ok := x.Value.(*ast.StructLit); !ok {
804 return c.errf(x.Value,
805 "comprehension value must be struct, found %T", y)
806 }
807
808 y := c.expr(x.Value)
809
810 st, ok := y.(*adt.StructLit)
811 if !ok {
812
813 return y
814 }
815
816 if len(a) == 0 {
817 return c.errf(x, "comprehension value without clauses")
818 }
819
820 return &adt.Comprehension{
821 Syntax: x,
822 Clauses: a,
823 Value: st,
824 }
825 }
826
827 func (c *compiler) labeledExpr(f ast.Decl, lab labeler, expr ast.Expr) adt.Expr {
828 k := len(c.stack) - 1
829 return c.labeledExprAt(k, f, lab, expr)
830 }
831
832 func (c *compiler) labeledExprAt(k int, f ast.Decl, lab labeler, expr ast.Expr) adt.Expr {
833 saved := c.stack[k]
834
835 c.stack[k].label = lab
836 c.stack[k].field = f
837
838 value := c.expr(expr)
839
840 c.stack[k] = saved
841 return value
842 }
843
844 func (c *compiler) expr(expr ast.Expr) adt.Expr {
845 switch n := expr.(type) {
846 case nil:
847 return nil
848 case *ast.Ident:
849 return c.resolve(n)
850
851 case *ast.Func:
852
853
854
855
856
857
858
859 return c.resolve(ast.NewIdent("_"))
860
861 case *ast.StructLit:
862 c.pushScope(nil, 1, n)
863 v := &adt.StructLit{Src: n}
864 c.addDecls(v, n.Elts)
865 c.popScope()
866 return v
867
868 case *ast.ListLit:
869 c.pushScope(nil, 1, n)
870 v := &adt.ListLit{Src: n}
871 elts, ellipsis := internal.ListEllipsis(n)
872 for _, d := range elts {
873 elem := c.elem(d)
874
875 switch x := elem.(type) {
876 case nil:
877 case adt.Elem:
878 v.Elems = append(v.Elems, x)
879 default:
880 c.errf(d, "type %T not allowed in ListLit", d)
881 }
882 }
883 if ellipsis != nil {
884 d := &adt.Ellipsis{
885 Src: ellipsis,
886 Value: c.expr(ellipsis.Type),
887 }
888 v.Elems = append(v.Elems, d)
889 }
890 c.popScope()
891 return v
892
893 case *ast.SelectorExpr:
894 c.inSelector++
895 ret := &adt.SelectorExpr{
896 Src: n,
897 X: c.expr(n.X),
898 Sel: c.label(n.Sel)}
899 c.inSelector--
900 return ret
901
902 case *ast.IndexExpr:
903 return &adt.IndexExpr{
904 Src: n,
905 X: c.expr(n.X),
906 Index: c.expr(n.Index),
907 }
908
909 case *ast.SliceExpr:
910 slice := &adt.SliceExpr{Src: n, X: c.expr(n.X)}
911 if n.Low != nil {
912 slice.Lo = c.expr(n.Low)
913 }
914 if n.High != nil {
915 slice.Hi = c.expr(n.High)
916 }
917 return slice
918
919 case *ast.BottomLit:
920 return &adt.Bottom{
921 Src: n,
922 Code: adt.UserError,
923 Err: errors.Newf(n.Pos(), "explicit error (_|_ literal) in source"),
924 }
925
926 case *ast.BadExpr:
927 return c.errf(n, "invalid expression")
928
929 case *ast.BasicLit:
930 return c.parse(n)
931
932 case *ast.Interpolation:
933 if len(n.Elts) == 0 {
934 return c.errf(n, "invalid interpolation")
935 }
936 first, ok1 := n.Elts[0].(*ast.BasicLit)
937 last, ok2 := n.Elts[len(n.Elts)-1].(*ast.BasicLit)
938 if !ok1 || !ok2 {
939 return c.errf(n, "invalid interpolation")
940 }
941 if len(n.Elts) == 1 {
942 return c.expr(n.Elts[0])
943 }
944 lit := &adt.Interpolation{Src: n}
945 info, prefixLen, _, err := literal.ParseQuotes(first.Value, last.Value)
946 if err != nil {
947 return c.errf(n, "invalid interpolation: %v", err)
948 }
949 if info.IsDouble() {
950 lit.K = adt.StringKind
951 } else {
952 lit.K = adt.BytesKind
953 }
954 prefix := ""
955 for i := 0; i < len(n.Elts); i += 2 {
956 l, ok := n.Elts[i].(*ast.BasicLit)
957 if !ok {
958 return c.errf(n, "invalid interpolation")
959 }
960 s := l.Value
961 if !strings.HasPrefix(s, prefix) {
962 return c.errf(l, "invalid interpolation: unmatched ')'")
963 }
964 s = l.Value[prefixLen:]
965 x := parseString(c, l, info, s)
966 lit.Parts = append(lit.Parts, x)
967 if i+1 < len(n.Elts) {
968 lit.Parts = append(lit.Parts, c.expr(n.Elts[i+1]))
969 }
970 prefix = ")"
971 prefixLen = 1
972 }
973 return lit
974
975 case *ast.ParenExpr:
976 return c.expr(n.X)
977
978 case *ast.CallExpr:
979 call := &adt.CallExpr{Src: n, Fun: c.expr(n.Fun)}
980 for _, a := range n.Args {
981 call.Args = append(call.Args, c.expr(a))
982 }
983 return call
984
985 case *ast.UnaryExpr:
986 switch n.Op {
987 case token.NOT, token.ADD, token.SUB:
988 return &adt.UnaryExpr{
989 Src: n,
990 Op: adt.OpFromToken(n.Op),
991 X: c.expr(n.X),
992 }
993 case token.GEQ, token.GTR, token.LSS, token.LEQ,
994 token.NEQ, token.MAT, token.NMAT:
995 return &adt.BoundExpr{
996 Src: n,
997 Op: adt.OpFromToken(n.Op),
998 Expr: c.expr(n.X),
999 }
1000
1001 case token.MUL:
1002 return c.errf(n, "preference mark not allowed at this position")
1003 default:
1004 return c.errf(n, "unsupported unary operator %q", n.Op)
1005 }
1006
1007 case *ast.BinaryExpr:
1008 switch n.Op {
1009 case token.OR:
1010 d := &adt.DisjunctionExpr{Src: n}
1011 c.addDisjunctionElem(d, n.X, false)
1012 c.addDisjunctionElem(d, n.Y, false)
1013 return d
1014
1015 default:
1016 op := adt.OpFromToken(n.Op)
1017 x := c.expr(n.X)
1018 y := c.expr(n.Y)
1019 if op != adt.AndOp {
1020 c.assertConcreteIsPossible(n.X, op, x)
1021 c.assertConcreteIsPossible(n.Y, op, y)
1022 }
1023
1024 return &adt.BinaryExpr{Src: n, Op: op, X: x, Y: y}
1025 }
1026
1027 default:
1028 return c.errf(n, "%s values not allowed in this position", ast.Name(n))
1029 }
1030 }
1031
1032 func (c *compiler) assertConcreteIsPossible(src ast.Node, op adt.Op, x adt.Expr) bool {
1033 if !adt.AssertConcreteIsPossible(op, x) {
1034 str := astinternal.DebugStr(src)
1035 c.errf(src, "invalid operand %s ('%s' requires concrete value)", str, op)
1036 }
1037 return false
1038 }
1039
1040 func (c *compiler) addDisjunctionElem(d *adt.DisjunctionExpr, n ast.Expr, mark bool) {
1041 switch x := n.(type) {
1042 case *ast.BinaryExpr:
1043 if x.Op == token.OR {
1044 c.addDisjunctionElem(d, x.X, mark)
1045 c.addDisjunctionElem(d, x.Y, mark)
1046 return
1047 }
1048 case *ast.UnaryExpr:
1049 if x.Op == token.MUL {
1050 d.HasDefaults = true
1051 c.addDisjunctionElem(d, x.X, true)
1052 return
1053 }
1054 }
1055 d.Values = append(d.Values, adt.Disjunct{Val: c.expr(n), Default: mark})
1056 }
1057
1058
1059
1060 func (c *compiler) parse(l *ast.BasicLit) (n adt.Expr) {
1061 s := l.Value
1062 if s == "" {
1063 return c.errf(l, "invalid literal %q", s)
1064 }
1065 switch l.Kind {
1066 case token.STRING:
1067 info, nStart, _, err := literal.ParseQuotes(s, s)
1068 if err != nil {
1069 return c.errf(l, err.Error())
1070 }
1071 s := s[nStart:]
1072 return parseString(c, l, info, s)
1073
1074 case token.FLOAT, token.INT:
1075 err := literal.ParseNum(s, &c.num)
1076 if err != nil {
1077 return c.errf(l, "parse error: %v", err)
1078 }
1079 kind := adt.FloatKind
1080 if c.num.IsInt() {
1081 kind = adt.IntKind
1082 }
1083 n := &adt.Num{Src: l, K: kind}
1084 if err = c.num.Decimal(&n.X); err != nil {
1085 return c.errf(l, "error converting number to decimal: %v", err)
1086 }
1087 return n
1088
1089 case token.TRUE:
1090 return &adt.Bool{Src: l, B: true}
1091
1092 case token.FALSE:
1093 return &adt.Bool{Src: l, B: false}
1094
1095 case token.NULL:
1096 return &adt.Null{Src: l}
1097
1098 default:
1099 return c.errf(l, "unknown literal type")
1100 }
1101 }
1102
1103
1104 func parseString(c *compiler, node ast.Expr, q literal.QuoteInfo, s string) (n adt.Expr) {
1105 str, err := q.Unquote(s)
1106 if err != nil {
1107 return c.errf(node, "invalid string: %v", err)
1108 }
1109 if q.IsDouble() {
1110 return &adt.String{Src: node, Str: str, RE: nil}
1111 }
1112 return &adt.Bytes{Src: node, B: []byte(str), RE: nil}
1113 }
1114
View as plain text