github.com/solo-io/cue@v0.4.7/internal/core/compile/compile.go (about) 1 // Copyright 2020 CUE Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package compile 16 17 import ( 18 "strings" 19 20 "github.com/solo-io/cue/cue/ast" 21 "github.com/solo-io/cue/cue/errors" 22 "github.com/solo-io/cue/cue/literal" 23 "github.com/solo-io/cue/cue/token" 24 "github.com/solo-io/cue/internal" 25 "github.com/solo-io/cue/internal/astinternal" 26 "github.com/solo-io/cue/internal/core/adt" 27 ) 28 29 // A Scope represents a nested scope of Vertices. 30 type Scope interface { 31 Parent() Scope 32 Vertex() *adt.Vertex 33 } 34 35 // Config configures a compilation. 36 type Config struct { 37 // Scope specifies a node in which to look up unresolved references. This 38 // is useful for evaluating expressions within an already evaluated 39 // configuration. 40 Scope Scope 41 42 // Imports allows unresolved identifiers to resolve to imports. 43 // 44 // Under normal circumstances, identifiers bind to import specifications, 45 // which get resolved to an ImportReference. Use this option to 46 // automatically resolve identifiers to imports. 47 Imports func(x *ast.Ident) (pkgPath string) 48 49 // pkgPath is used to qualify the scope of hidden fields. The default 50 // scope is "_". 51 pkgPath string 52 } 53 54 // Files compiles the given files as a single instance. It disregards 55 // the package names and it is the responsibility of the user to verify that 56 // the packages names are consistent. The pkgID must be a unique identifier 57 // for a package in a module, for instance as obtained from build.Instance.ID. 58 // 59 // Files may return a completed parse even if it has errors. 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 // Expr compiles the given expression into a conjunct. The pkgID must be a 72 // unique identifier for a package in a module, for instance as obtained from 73 // build.Instance.ID. 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 // 1 for files; 0 for expressions 102 103 index adt.StringIndexer 104 105 stack []frame 106 inSelector int 107 108 fileScope map[adt.Feature]bool 109 110 num literal.NumInfo 111 112 errs errors.Error 113 } 114 115 func (c *compiler) reset() { 116 c.fileScope = nil 117 c.stack = c.stack[:0] 118 c.errs = nil 119 } 120 121 func (c *compiler) errf(n ast.Node, format string, args ...interface{}) *adt.Bottom { 122 err := &compilerError{ 123 n: n, 124 path: c.path(), 125 Message: errors.NewMessage(format, args), 126 } 127 c.errs = errors.Append(c.errs, err) 128 return &adt.Bottom{Err: err} 129 } 130 131 func (c *compiler) path() []string { 132 a := []string{} 133 for _, f := range c.stack { 134 if f.label != nil { 135 a = append(a, f.label.labelString()) 136 } 137 } 138 return a 139 } 140 141 type frame struct { 142 label labeler // path name leading to this frame. 143 scope ast.Node // *ast.File or *ast.Struct 144 field *ast.Field 145 // scope map[ast.Node]bool 146 upCount int32 // 1 for field, 0 for embedding. 147 148 aliases map[string]aliasEntry 149 } 150 151 type aliasEntry struct { 152 label labeler 153 srcExpr ast.Expr 154 expr adt.Expr 155 source ast.Node 156 used bool 157 } 158 159 func (c *compiler) insertAlias(id *ast.Ident, a aliasEntry) *adt.Bottom { 160 k := len(c.stack) - 1 161 m := c.stack[k].aliases 162 if m == nil { 163 m = map[string]aliasEntry{} 164 c.stack[k].aliases = m 165 } 166 167 if id == nil || !ast.IsValidIdent(id.Name) { 168 return c.errf(a.source, "invalid identifier name") 169 } 170 171 if e, ok := m[id.Name]; ok { 172 return c.errf(a.source, 173 "alias %q already declared; previous declaration at %s", 174 id.Name, e.source.Pos()) 175 } 176 177 m[id.Name] = a 178 return nil 179 } 180 181 func (c *compiler) updateAlias(id *ast.Ident, expr adt.Expr) { 182 k := len(c.stack) - 1 183 m := c.stack[k].aliases 184 185 x := m[id.Name] 186 x.expr = expr 187 x.label = nil 188 x.srcExpr = nil 189 m[id.Name] = x 190 } 191 192 // lookupAlias looks up an alias with the given name at the k'th stack position. 193 func (c *compiler) lookupAlias(k int, id *ast.Ident) aliasEntry { 194 m := c.stack[k].aliases 195 name := id.Name 196 entry, ok := m[name] 197 198 if !ok { 199 err := c.errf(id, "could not find LetClause associated with identifier %q", name) 200 return aliasEntry{expr: err} 201 } 202 203 switch { 204 case entry.label != nil: 205 if entry.srcExpr == nil { 206 entry.expr = c.errf(id, "cyclic references in let clause or alias") 207 break 208 } 209 210 src := entry.srcExpr 211 entry.srcExpr = nil // mark to allow detecting cycles 212 m[name] = entry 213 214 entry.expr = c.labeledExprAt(k, nil, entry.label, src) 215 entry.label = nil 216 } 217 218 entry.used = true 219 m[name] = entry 220 return entry 221 } 222 223 func (c *compiler) pushScope(n labeler, upCount int32, id ast.Node) *frame { 224 c.stack = append(c.stack, frame{ 225 label: n, 226 scope: id, 227 upCount: upCount, 228 }) 229 return &c.stack[len(c.stack)-1] 230 } 231 232 func (c *compiler) popScope() { 233 k := len(c.stack) - 1 234 f := c.stack[k] 235 for k, v := range f.aliases { 236 if !v.used { 237 c.errf(v.source, "unreferenced alias or let clause %s", k) 238 } 239 } 240 c.stack = c.stack[:k] 241 } 242 243 func (c *compiler) compileFiles(a []*ast.File) *adt.Vertex { // Or value? 244 c.fileScope = map[adt.Feature]bool{} 245 c.upCountOffset = 1 246 247 // TODO(resolve): this is also done in the runtime package, do we need both? 248 249 // Populate file scope to handle unresolved references. 250 // Excluded from cross-file resolution are: 251 // - import specs 252 // - aliases 253 // - anything in an anonymous file 254 // 255 for _, f := range a { 256 if p := internal.GetPackageInfo(f); p.IsAnonymous() { 257 continue 258 } 259 for _, d := range f.Decls { 260 if f, ok := d.(*ast.Field); ok { 261 if id, ok := f.Label.(*ast.Ident); ok { 262 c.fileScope[c.label(id)] = true 263 } 264 } 265 } 266 } 267 268 // TODO: set doc. 269 res := &adt.Vertex{} 270 271 // env := &adt.Environment{Vertex: nil} // runtime: c.runtime 272 273 env := &adt.Environment{} 274 top := env 275 276 for p := c.Config.Scope; p != nil; p = p.Parent() { 277 top.Vertex = p.Vertex() 278 top.Up = &adt.Environment{} 279 top = top.Up 280 } 281 282 for _, file := range a { 283 c.pushScope(nil, 0, file) // File scope 284 v := &adt.StructLit{Src: file} 285 c.addDecls(v, file.Decls) 286 res.Conjuncts = append(res.Conjuncts, adt.MakeRootConjunct(env, v)) 287 c.popScope() 288 } 289 290 return res 291 } 292 293 func (c *compiler) compileExpr(x ast.Expr) adt.Conjunct { 294 expr := c.expr(x) 295 296 env := &adt.Environment{} 297 top := env 298 299 for p := c.Config.Scope; p != nil; p = p.Parent() { 300 top.Vertex = p.Vertex() 301 top.Up = &adt.Environment{} 302 top = top.Up 303 } 304 305 return adt.MakeRootConjunct(env, expr) 306 } 307 308 // resolve assumes that all existing resolutions are legal. Validation should 309 // be done in a separate step if required. 310 // 311 // TODO: collect validation pass to verify that all resolutions are 312 // legal? 313 func (c *compiler) resolve(n *ast.Ident) adt.Expr { 314 // X in import "path/X" 315 // X in import X "path" 316 if imp, ok := n.Node.(*ast.ImportSpec); ok { 317 return &adt.ImportReference{ 318 Src: n, 319 ImportPath: c.label(imp.Path), 320 Label: c.label(n), 321 } 322 } 323 324 label := c.label(n) 325 326 // Unresolved field. 327 if n.Node == nil { 328 upCount := int32(0) 329 for _, c := range c.stack { 330 upCount += c.upCount 331 } 332 if c.fileScope[label] { 333 return &adt.FieldReference{ 334 Src: n, 335 UpCount: upCount, 336 Label: label, 337 } 338 } 339 upCount += c.upCountOffset 340 for p := c.Scope; p != nil; p = p.Parent() { 341 for _, a := range p.Vertex().Arcs { 342 if a.Label == label { 343 return &adt.FieldReference{ 344 Src: n, 345 UpCount: upCount, 346 Label: label, 347 } 348 } 349 } 350 upCount++ 351 } 352 353 if c.Config.Imports != nil { 354 if pkgPath := c.Config.Imports(n); pkgPath != "" { 355 return &adt.ImportReference{ 356 Src: n, 357 ImportPath: adt.MakeStringLabel(c.index, pkgPath), 358 Label: c.label(n), 359 } 360 } 361 } 362 363 if p := predeclared(n); p != nil { 364 return p 365 } 366 367 return c.errf(n, "reference %q not found", n.Name) 368 } 369 370 // X in [X=x]: y Scope: Field Node: Expr (x) 371 // X in X=[x]: y Scope: Field Node: Field 372 // X in x: X=y Scope: Field Node: Alias 373 if f, ok := n.Scope.(*ast.Field); ok { 374 upCount := int32(0) 375 376 k := len(c.stack) - 1 377 for ; k >= 0; k-- { 378 if c.stack[k].field == f { 379 break 380 } 381 upCount += c.stack[k].upCount 382 } 383 384 label := &adt.LabelReference{ 385 Src: n, 386 UpCount: upCount, 387 } 388 389 switch f := n.Node.(type) { 390 case *ast.Field: 391 _ = c.lookupAlias(k, f.Label.(*ast.Alias).Ident) // mark as used 392 return &adt.DynamicReference{ 393 Src: n, 394 UpCount: upCount, 395 Label: label, 396 } 397 398 case *ast.Alias: 399 _ = c.lookupAlias(k, f.Ident) // mark as used 400 return &adt.ValueReference{ 401 Src: n, 402 UpCount: upCount, 403 Label: c.label(f.Ident), 404 } 405 } 406 return label 407 } 408 409 upCount := int32(0) 410 411 k := len(c.stack) - 1 412 for ; k >= 0; k-- { 413 if c.stack[k].scope == n.Scope { 414 break 415 } 416 upCount += c.stack[k].upCount 417 } 418 if k < 0 { 419 // This is a programmatic error and should never happen if the users 420 // just builds with the cue command or if astutil.Resolve is used 421 // correctly. 422 c.errf(n, "reference %q set to unknown node in AST; "+ 423 "this can result from incorrect API usage or a compiler bug", 424 n.Name) 425 } 426 427 if n.Scope == nil { 428 // Package. 429 // Should have been handled above. 430 return c.errf(n, "unresolved identifier %v", n.Name) 431 } 432 433 switch f := n.Node.(type) { 434 // Local expressions 435 case *ast.LetClause: 436 entry := c.lookupAlias(k, n) 437 438 // let x = y 439 return &adt.LetReference{ 440 Src: n, 441 UpCount: upCount, 442 Label: label, 443 X: entry.expr, 444 } 445 446 // TODO: handle new-style aliases 447 448 case *ast.Field: 449 // X=x: y 450 // X=(x): y 451 // X="\(x)": y 452 a, ok := f.Label.(*ast.Alias) 453 if !ok { 454 return c.errf(n, "illegal reference %s", n.Name) 455 } 456 aliasInfo := c.lookupAlias(k, a.Ident) // marks alias as used. 457 lab, ok := a.Expr.(ast.Label) 458 if !ok { 459 return c.errf(a.Expr, "invalid label expression") 460 } 461 name, _, err := ast.LabelName(lab) 462 switch { 463 case errors.Is(err, ast.ErrIsExpression): 464 if aliasInfo.expr == nil { 465 panic("unreachable") 466 } 467 return &adt.DynamicReference{ 468 Src: n, 469 UpCount: upCount, 470 Label: aliasInfo.expr, 471 } 472 473 case err != nil: 474 return c.errf(n, "invalid label: %v", err) 475 476 case name != "": 477 label = c.label(lab) 478 479 default: 480 return c.errf(n, "unsupported field alias %q", name) 481 } 482 } 483 484 return &adt.FieldReference{ 485 Src: n, 486 UpCount: upCount, 487 Label: label, 488 } 489 } 490 491 func (c *compiler) addDecls(st *adt.StructLit, a []ast.Decl) { 492 for _, d := range a { 493 c.markAlias(d) 494 } 495 for _, d := range a { 496 c.addLetDecl(d) 497 } 498 for _, d := range a { 499 if x := c.decl(d); x != nil { 500 st.Decls = append(st.Decls, x) 501 } 502 } 503 } 504 505 func (c *compiler) markAlias(d ast.Decl) { 506 switch x := d.(type) { 507 case *ast.Field: 508 lab := x.Label 509 if a, ok := lab.(*ast.Alias); ok { 510 if _, ok = a.Expr.(ast.Label); !ok { 511 c.errf(a, "alias expression is not a valid label") 512 } 513 514 e := aliasEntry{source: a} 515 516 c.insertAlias(a.Ident, e) 517 } 518 519 case *ast.LetClause: 520 a := aliasEntry{ 521 label: (*letScope)(x), 522 srcExpr: x.Expr, 523 source: x, 524 } 525 c.insertAlias(x.Ident, a) 526 527 case *ast.Alias: 528 c.errf(x, "old-style alias no longer supported: use let clause; use cue fix to update.") 529 } 530 } 531 532 func (c *compiler) decl(d ast.Decl) adt.Decl { 533 switch x := d.(type) { 534 case *ast.BadDecl: 535 return c.errf(d, "") 536 537 case *ast.Field: 538 lab := x.Label 539 if a, ok := lab.(*ast.Alias); ok { 540 if lab, ok = a.Expr.(ast.Label); !ok { 541 return c.errf(a, "alias expression is not a valid label") 542 } 543 544 switch lab.(type) { 545 case *ast.Ident, *ast.BasicLit, *ast.ListLit: 546 // Even though we won't need the alias, we still register it 547 // for duplicate and failed reference detection. 548 default: 549 c.updateAlias(a.Ident, c.expr(a.Expr)) 550 } 551 } 552 553 v := x.Value 554 var value adt.Expr 555 if a, ok := v.(*ast.Alias); ok { 556 c.pushScope(nil, 0, a) 557 c.insertAlias(a.Ident, aliasEntry{source: a}) 558 value = c.labeledExpr(x, (*fieldLabel)(x), a.Expr) 559 c.popScope() 560 } else { 561 value = c.labeledExpr(x, (*fieldLabel)(x), v) 562 } 563 564 switch l := lab.(type) { 565 case *ast.Ident, *ast.BasicLit: 566 label := c.label(lab) 567 568 // TODO(legacy): remove: old-school definitions 569 if x.Token == token.ISA && !label.IsDef() { 570 name, isIdent, err := ast.LabelName(lab) 571 if err == nil && isIdent { 572 idx := c.index.StringToIndex(name) 573 label, _ = adt.MakeLabel(x, idx, adt.DefinitionLabel) 574 } 575 } 576 577 if x.Optional == token.NoPos { 578 return &adt.Field{ 579 Src: x, 580 Label: label, 581 Value: value, 582 } 583 } else { 584 return &adt.OptionalField{ 585 Src: x, 586 Label: label, 587 Value: value, 588 } 589 } 590 591 case *ast.ListLit: 592 if len(l.Elts) != 1 { 593 // error 594 return c.errf(x, "list label must have one element") 595 } 596 var label adt.Feature 597 elem := l.Elts[0] 598 // TODO: record alias for error handling? In principle it is okay 599 // to have duplicates, but we do want it to be used. 600 if a, ok := elem.(*ast.Alias); ok { 601 label = c.label(a.Ident) 602 elem = a.Expr 603 } 604 605 return &adt.BulkOptionalField{ 606 Src: x, 607 Filter: c.expr(elem), 608 Value: value, 609 Label: label, 610 } 611 612 case *ast.ParenExpr: 613 if x.Token == token.ISA { 614 c.errf(x, "definitions not supported for dynamic fields") 615 } 616 return &adt.DynamicField{ 617 Src: x, 618 Key: c.expr(l), 619 Value: value, 620 } 621 622 case *ast.Interpolation: 623 if x.Token == token.ISA { 624 c.errf(x, "definitions not supported for interpolations") 625 } 626 return &adt.DynamicField{ 627 Src: x, 628 Key: c.expr(l), 629 Value: value, 630 } 631 } 632 633 // Handled in addLetDecl. 634 case *ast.LetClause: 635 // case: *ast.Alias: // TODO(value alias) 636 637 case *ast.CommentGroup: 638 // Nothing to do for a free-floating comment group. 639 640 case *ast.Attribute: 641 // Nothing to do for now for an attribute declaration. 642 643 case *ast.Ellipsis: 644 return &adt.Ellipsis{ 645 Src: x, 646 Value: c.expr(x.Type), 647 } 648 649 case *ast.Comprehension: 650 return c.comprehension(x) 651 652 case *ast.EmbedDecl: // Deprecated 653 return c.embed(x.Expr) 654 655 case ast.Expr: 656 return c.embed(x) 657 } 658 return nil 659 } 660 661 func (c *compiler) addLetDecl(d ast.Decl) { 662 switch x := d.(type) { 663 // An alias reference will have an expression that is looked up in the 664 // environment cash. 665 case *ast.LetClause: 666 // Cache the parsed expression. Creating a unique expression for each 667 // reference allows the computation to be shared given that we don't 668 // have fields for expressions. This, in turn, prevents exponential 669 // blowup in x2: x1+x1, x3: x2+x2, ... patterns. 670 expr := c.labeledExpr(nil, (*letScope)(x), x.Expr) 671 c.updateAlias(x.Ident, expr) 672 673 case *ast.Alias: 674 c.errf(x, "old-style alias no longer supported: use let clause; use cue fix to update.") 675 } 676 } 677 678 func (c *compiler) elem(n ast.Expr) adt.Elem { 679 switch x := n.(type) { 680 case *ast.Ellipsis: 681 return &adt.Ellipsis{ 682 Src: x, 683 Value: c.expr(x.Type), 684 } 685 686 case *ast.Comprehension: 687 return c.comprehension(x) 688 689 case ast.Expr: 690 return c.expr(x) 691 } 692 return nil 693 } 694 695 func (c *compiler) comprehension(x *ast.Comprehension) adt.Elem { 696 var cur adt.Yielder 697 var first adt.Elem 698 var prev, next *adt.Yielder 699 for _, v := range x.Clauses { 700 switch x := v.(type) { 701 case *ast.ForClause: 702 var key adt.Feature 703 if x.Key != nil { 704 key = c.label(x.Key) 705 } 706 y := &adt.ForClause{ 707 Syntax: x, 708 Key: key, 709 Value: c.label(x.Value), 710 Src: c.expr(x.Source), 711 } 712 cur = y 713 c.pushScope((*forScope)(x), 1, v) 714 defer c.popScope() 715 next = &y.Dst 716 717 case *ast.IfClause: 718 y := &adt.IfClause{ 719 Src: x, 720 Condition: c.expr(x.Condition), 721 } 722 cur = y 723 next = &y.Dst 724 725 case *ast.LetClause: 726 y := &adt.LetClause{ 727 Src: x, 728 Label: c.label(x.Ident), 729 Expr: c.expr(x.Expr), 730 } 731 cur = y 732 c.pushScope((*letScope)(x), 1, v) 733 defer c.popScope() 734 next = &y.Dst 735 } 736 737 if prev != nil { 738 *prev = cur 739 } else { 740 var ok bool 741 if first, ok = cur.(adt.Elem); !ok { 742 return c.errf(x, 743 "first comprehension clause must be 'if' or 'for'") 744 } 745 } 746 prev = next 747 } 748 749 // TODO: make x.Value an *ast.StructLit and this is redundant. 750 if y, ok := x.Value.(*ast.StructLit); !ok { 751 return c.errf(x.Value, 752 "comprehension value must be struct, found %T", y) 753 } 754 755 y := c.expr(x.Value) 756 757 st, ok := y.(*adt.StructLit) 758 if !ok { 759 // Error must have been generated. 760 return y 761 } 762 763 if prev != nil { 764 *prev = &adt.ValueClause{StructLit: st} 765 } else { 766 return c.errf(x, "comprehension value without clauses") 767 } 768 769 return first 770 } 771 772 func (c *compiler) embed(expr ast.Expr) adt.Expr { 773 switch n := expr.(type) { 774 case *ast.StructLit: 775 c.pushScope(nil, 1, n) 776 v := &adt.StructLit{Src: n} 777 c.addDecls(v, n.Elts) 778 c.popScope() 779 return v 780 } 781 return c.expr(expr) 782 } 783 784 func (c *compiler) labeledExpr(f *ast.Field, lab labeler, expr ast.Expr) adt.Expr { 785 k := len(c.stack) - 1 786 return c.labeledExprAt(k, f, lab, expr) 787 } 788 789 func (c *compiler) labeledExprAt(k int, f *ast.Field, lab labeler, expr ast.Expr) adt.Expr { 790 if c.stack[k].field != nil { 791 panic("expected nil field") 792 } 793 saved := c.stack[k] 794 795 c.stack[k].label = lab 796 c.stack[k].field = f 797 798 value := c.expr(expr) 799 800 c.stack[k] = saved 801 return value 802 } 803 804 func (c *compiler) expr(expr ast.Expr) adt.Expr { 805 switch n := expr.(type) { 806 case nil: 807 return nil 808 case *ast.Ident: 809 return c.resolve(n) 810 811 case *ast.StructLit: 812 c.pushScope(nil, 1, n) 813 v := &adt.StructLit{Src: n} 814 c.addDecls(v, n.Elts) 815 c.popScope() 816 return v 817 818 case *ast.ListLit: 819 v := &adt.ListLit{Src: n} 820 elts, ellipsis := internal.ListEllipsis(n) 821 for _, d := range elts { 822 elem := c.elem(d) 823 824 switch x := elem.(type) { 825 case nil: 826 case adt.Elem: 827 v.Elems = append(v.Elems, x) 828 default: 829 c.errf(d, "type %T not allowed in ListLit", d) 830 } 831 } 832 if ellipsis != nil { 833 d := &adt.Ellipsis{ 834 Src: ellipsis, 835 Value: c.expr(ellipsis.Type), 836 } 837 v.Elems = append(v.Elems, d) 838 } 839 return v 840 841 case *ast.SelectorExpr: 842 c.inSelector++ 843 ret := &adt.SelectorExpr{ 844 Src: n, 845 X: c.expr(n.X), 846 Sel: c.label(n.Sel)} 847 c.inSelector-- 848 return ret 849 850 case *ast.IndexExpr: 851 return &adt.IndexExpr{ 852 Src: n, 853 X: c.expr(n.X), 854 Index: c.expr(n.Index), 855 } 856 857 case *ast.SliceExpr: 858 slice := &adt.SliceExpr{Src: n, X: c.expr(n.X)} 859 if n.Low != nil { 860 slice.Lo = c.expr(n.Low) 861 } 862 if n.High != nil { 863 slice.Hi = c.expr(n.High) 864 } 865 return slice 866 867 case *ast.BottomLit: 868 return &adt.Bottom{ 869 Src: n, 870 Code: adt.UserError, 871 Err: errors.Newf(n.Pos(), "explicit error (_|_ literal) in source"), 872 } 873 874 case *ast.BadExpr: 875 return c.errf(n, "invalid expression") 876 877 case *ast.BasicLit: 878 return c.parse(n) 879 880 case *ast.Interpolation: 881 if len(n.Elts) == 0 { 882 return c.errf(n, "invalid interpolation") 883 } 884 first, ok1 := n.Elts[0].(*ast.BasicLit) 885 last, ok2 := n.Elts[len(n.Elts)-1].(*ast.BasicLit) 886 if !ok1 || !ok2 { 887 return c.errf(n, "invalid interpolation") 888 } 889 if len(n.Elts) == 1 { 890 return c.expr(n.Elts[0]) 891 } 892 lit := &adt.Interpolation{Src: n} 893 info, prefixLen, _, err := literal.ParseQuotes(first.Value, last.Value) 894 if err != nil { 895 return c.errf(n, "invalid interpolation: %v", err) 896 } 897 if info.IsDouble() { 898 lit.K = adt.StringKind 899 } else { 900 lit.K = adt.BytesKind 901 } 902 prefix := "" 903 for i := 0; i < len(n.Elts); i += 2 { 904 l, ok := n.Elts[i].(*ast.BasicLit) 905 if !ok { 906 return c.errf(n, "invalid interpolation") 907 } 908 s := l.Value 909 if !strings.HasPrefix(s, prefix) { 910 return c.errf(l, "invalid interpolation: unmatched ')'") 911 } 912 s = l.Value[prefixLen:] 913 x := parseString(c, l, info, s) 914 lit.Parts = append(lit.Parts, x) 915 if i+1 < len(n.Elts) { 916 lit.Parts = append(lit.Parts, c.expr(n.Elts[i+1])) 917 } 918 prefix = ")" 919 prefixLen = 1 920 } 921 return lit 922 923 case *ast.ParenExpr: 924 return c.expr(n.X) 925 926 case *ast.CallExpr: 927 call := &adt.CallExpr{Src: n, Fun: c.expr(n.Fun)} 928 for _, a := range n.Args { 929 call.Args = append(call.Args, c.expr(a)) 930 } 931 return call 932 933 case *ast.UnaryExpr: 934 switch n.Op { 935 case token.NOT, token.ADD, token.SUB: 936 return &adt.UnaryExpr{ 937 Src: n, 938 Op: adt.OpFromToken(n.Op), 939 X: c.expr(n.X), 940 } 941 case token.GEQ, token.GTR, token.LSS, token.LEQ, 942 token.NEQ, token.MAT, token.NMAT: 943 return &adt.BoundExpr{ 944 Src: n, 945 Op: adt.OpFromToken(n.Op), 946 Expr: c.expr(n.X), 947 } 948 949 case token.MUL: 950 return c.errf(n, "preference mark not allowed at this position") 951 default: 952 return c.errf(n, "unsupported unary operator %q", n.Op) 953 } 954 955 case *ast.BinaryExpr: 956 switch n.Op { 957 case token.OR: 958 d := &adt.DisjunctionExpr{Src: n} 959 c.addDisjunctionElem(d, n.X, false) 960 c.addDisjunctionElem(d, n.Y, false) 961 return d 962 963 default: 964 op := adt.OpFromToken(n.Op) 965 x := c.expr(n.X) 966 y := c.expr(n.Y) 967 if op != adt.AndOp { 968 c.assertConcreteIsPossible(n.X, op, x) 969 c.assertConcreteIsPossible(n.Y, op, y) 970 } 971 // return updateBin(c, 972 return &adt.BinaryExpr{Src: n, Op: op, X: x, Y: y} // ) 973 } 974 975 default: 976 return c.errf(n, "%s values not allowed in this position", ast.Name(n)) 977 } 978 } 979 980 func (c *compiler) assertConcreteIsPossible(src ast.Node, op adt.Op, x adt.Expr) bool { 981 if !adt.AssertConcreteIsPossible(op, x) { 982 str := astinternal.DebugStr(src) 983 c.errf(src, "invalid operand %s ('%s' requires concrete value)", str, op) 984 } 985 return false 986 } 987 988 func (c *compiler) addDisjunctionElem(d *adt.DisjunctionExpr, n ast.Expr, mark bool) { 989 switch x := n.(type) { 990 case *ast.BinaryExpr: 991 if x.Op == token.OR { 992 c.addDisjunctionElem(d, x.X, mark) 993 c.addDisjunctionElem(d, x.Y, mark) 994 return 995 } 996 case *ast.UnaryExpr: 997 if x.Op == token.MUL { 998 d.HasDefaults = true 999 c.addDisjunctionElem(d, x.X, true) 1000 return 1001 } 1002 } 1003 d.Values = append(d.Values, adt.Disjunct{Val: c.expr(n), Default: mark}) 1004 } 1005 1006 // TODO(perf): validate that regexps are cached at the right time. 1007 1008 func (c *compiler) parse(l *ast.BasicLit) (n adt.Expr) { 1009 s := l.Value 1010 if s == "" { 1011 return c.errf(l, "invalid literal %q", s) 1012 } 1013 switch l.Kind { 1014 case token.STRING: 1015 info, nStart, _, err := literal.ParseQuotes(s, s) 1016 if err != nil { 1017 return c.errf(l, err.Error()) 1018 } 1019 s := s[nStart:] 1020 return parseString(c, l, info, s) 1021 1022 case token.FLOAT, token.INT: 1023 err := literal.ParseNum(s, &c.num) 1024 if err != nil { 1025 return c.errf(l, "parse error: %v", err) 1026 } 1027 kind := adt.FloatKind 1028 if c.num.IsInt() { 1029 kind = adt.IntKind 1030 } 1031 n := &adt.Num{Src: l, K: kind} 1032 if err = c.num.Decimal(&n.X); err != nil { 1033 return c.errf(l, "error converting number to decimal: %v", err) 1034 } 1035 return n 1036 1037 case token.TRUE: 1038 return &adt.Bool{Src: l, B: true} 1039 1040 case token.FALSE: 1041 return &adt.Bool{Src: l, B: false} 1042 1043 case token.NULL: 1044 return &adt.Null{Src: l} 1045 1046 default: 1047 return c.errf(l, "unknown literal type") 1048 } 1049 } 1050 1051 // parseString decodes a string without the starting and ending quotes. 1052 func parseString(c *compiler, node ast.Expr, q literal.QuoteInfo, s string) (n adt.Expr) { 1053 str, err := q.Unquote(s) 1054 if err != nil { 1055 return c.errf(node, "invalid string: %v", err) 1056 } 1057 if q.IsDouble() { 1058 return &adt.String{Src: node, Str: str, RE: nil} 1059 } 1060 return &adt.Bytes{Src: node, B: []byte(str), RE: nil} 1061 }