github.com/joomcode/cue@v0.4.4-0.20221111115225-539fe3512047/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/joomcode/cue/cue/ast" 21 "github.com/joomcode/cue/cue/errors" 22 "github.com/joomcode/cue/cue/literal" 23 "github.com/joomcode/cue/cue/token" 24 "github.com/joomcode/cue/internal" 25 "github.com/joomcode/cue/internal/astinternal" 26 "github.com/joomcode/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 if label == adt.InvalidLabel { // `_` 327 return &adt.Top{Src: n} 328 } 329 330 // Unresolved field. 331 if n.Node == nil { 332 upCount := int32(0) 333 for _, c := range c.stack { 334 upCount += c.upCount 335 } 336 if c.fileScope[label] { 337 return &adt.FieldReference{ 338 Src: n, 339 UpCount: upCount, 340 Label: label, 341 } 342 } 343 upCount += c.upCountOffset 344 for p := c.Scope; p != nil; p = p.Parent() { 345 for _, a := range p.Vertex().Arcs { 346 if a.Label == label { 347 return &adt.FieldReference{ 348 Src: n, 349 UpCount: upCount, 350 Label: label, 351 } 352 } 353 } 354 upCount++ 355 } 356 357 if c.Config.Imports != nil { 358 if pkgPath := c.Config.Imports(n); pkgPath != "" { 359 return &adt.ImportReference{ 360 Src: n, 361 ImportPath: adt.MakeStringLabel(c.index, pkgPath), 362 Label: c.label(n), 363 } 364 } 365 } 366 367 if p := predeclared(n); p != nil { 368 return p 369 } 370 371 return c.errf(n, "reference %q not found", n.Name) 372 } 373 374 // X in [X=x]: y Scope: Field Node: Expr (x) 375 // X in X=[x]: y Scope: Field Node: Field 376 // X in x: X=y Scope: Field Node: Alias 377 if f, ok := n.Scope.(*ast.Field); ok { 378 upCount := int32(0) 379 380 k := len(c.stack) - 1 381 for ; k >= 0; k-- { 382 if c.stack[k].field == f { 383 break 384 } 385 upCount += c.stack[k].upCount 386 } 387 388 label := &adt.LabelReference{ 389 Src: n, 390 UpCount: upCount, 391 } 392 393 switch f := n.Node.(type) { 394 case *ast.Field: 395 _ = c.lookupAlias(k, f.Label.(*ast.Alias).Ident) // mark as used 396 return &adt.DynamicReference{ 397 Src: n, 398 UpCount: upCount, 399 Label: label, 400 } 401 402 case *ast.Alias: 403 _ = c.lookupAlias(k, f.Ident) // mark as used 404 return &adt.ValueReference{ 405 Src: n, 406 UpCount: upCount, 407 Label: c.label(f.Ident), 408 } 409 } 410 return label 411 } 412 413 upCount := int32(0) 414 415 k := len(c.stack) - 1 416 for ; k >= 0; k-- { 417 if c.stack[k].scope == n.Scope { 418 break 419 } 420 upCount += c.stack[k].upCount 421 } 422 if k < 0 { 423 // This is a programmatic error and should never happen if the users 424 // just builds with the cue command or if astutil.Resolve is used 425 // correctly. 426 c.errf(n, "reference %q set to unknown node in AST; "+ 427 "this can result from incorrect API usage or a compiler bug", 428 n.Name) 429 } 430 431 if n.Scope == nil { 432 // Package. 433 // Should have been handled above. 434 return c.errf(n, "unresolved identifier %v", n.Name) 435 } 436 437 switch f := n.Node.(type) { 438 // Local expressions 439 case *ast.LetClause: 440 entry := c.lookupAlias(k, n) 441 442 // let x = y 443 return &adt.LetReference{ 444 Src: n, 445 UpCount: upCount, 446 Label: label, 447 X: entry.expr, 448 } 449 450 // TODO: handle new-style aliases 451 452 case *ast.Field: 453 // X=x: y 454 // X=(x): y 455 // X="\(x)": y 456 a, ok := f.Label.(*ast.Alias) 457 if !ok { 458 return c.errf(n, "illegal reference %s", n.Name) 459 } 460 aliasInfo := c.lookupAlias(k, a.Ident) // marks alias as used. 461 lab, ok := a.Expr.(ast.Label) 462 if !ok { 463 return c.errf(a.Expr, "invalid label expression") 464 } 465 name, _, err := ast.LabelName(lab) 466 switch { 467 case errors.Is(err, ast.ErrIsExpression): 468 if aliasInfo.expr == nil { 469 panic("unreachable") 470 } 471 return &adt.DynamicReference{ 472 Src: n, 473 UpCount: upCount, 474 Label: aliasInfo.expr, 475 } 476 477 case err != nil: 478 return c.errf(n, "invalid label: %v", err) 479 480 case name != "": 481 label = c.label(lab) 482 483 default: 484 return c.errf(n, "unsupported field alias %q", name) 485 } 486 } 487 488 return &adt.FieldReference{ 489 Src: n, 490 UpCount: upCount, 491 Label: label, 492 } 493 } 494 495 func (c *compiler) addDecls(st *adt.StructLit, a []ast.Decl) { 496 for _, d := range a { 497 c.markAlias(d) 498 } 499 for _, d := range a { 500 c.addLetDecl(d) 501 } 502 for _, d := range a { 503 if x := c.decl(d); x != nil { 504 st.Decls = append(st.Decls, x) 505 } 506 } 507 } 508 509 func (c *compiler) markAlias(d ast.Decl) { 510 switch x := d.(type) { 511 case *ast.Field: 512 lab := x.Label 513 if a, ok := lab.(*ast.Alias); ok { 514 if _, ok = a.Expr.(ast.Label); !ok { 515 c.errf(a, "alias expression is not a valid label") 516 } 517 518 e := aliasEntry{source: a} 519 520 c.insertAlias(a.Ident, e) 521 } 522 523 case *ast.LetClause: 524 a := aliasEntry{ 525 label: (*letScope)(x), 526 srcExpr: x.Expr, 527 source: x, 528 } 529 c.insertAlias(x.Ident, a) 530 531 case *ast.Alias: 532 c.errf(x, "old-style alias no longer supported: use let clause; use cue fix to update.") 533 } 534 } 535 536 func (c *compiler) decl(d ast.Decl) adt.Decl { 537 switch x := d.(type) { 538 case *ast.BadDecl: 539 return c.errf(d, "") 540 541 case *ast.Field: 542 lab := x.Label 543 if a, ok := lab.(*ast.Alias); ok { 544 if lab, ok = a.Expr.(ast.Label); !ok { 545 return c.errf(a, "alias expression is not a valid label") 546 } 547 548 switch lab.(type) { 549 case *ast.Ident, *ast.BasicLit, *ast.ListLit: 550 // Even though we won't need the alias, we still register it 551 // for duplicate and failed reference detection. 552 default: 553 c.updateAlias(a.Ident, c.expr(a.Expr)) 554 } 555 } 556 557 v := x.Value 558 var value adt.Expr 559 if a, ok := v.(*ast.Alias); ok { 560 c.pushScope(nil, 0, a) 561 c.insertAlias(a.Ident, aliasEntry{source: a}) 562 value = c.labeledExpr(x, (*fieldLabel)(x), a.Expr) 563 c.popScope() 564 } else { 565 value = c.labeledExpr(x, (*fieldLabel)(x), v) 566 } 567 568 switch l := lab.(type) { 569 case *ast.Ident, *ast.BasicLit: 570 label := c.label(lab) 571 572 if label == adt.InvalidLabel { 573 return c.errf(x, "cannot use _ as label") 574 } 575 576 // TODO(legacy): remove: old-school definitions 577 if x.Token == token.ISA && !label.IsDef() { 578 name, isIdent, err := ast.LabelName(lab) 579 if err == nil && isIdent { 580 idx := c.index.StringToIndex(name) 581 label, _ = adt.MakeLabel(x, idx, adt.DefinitionLabel) 582 } 583 } 584 585 if x.Optional == token.NoPos { 586 return &adt.Field{ 587 Src: x, 588 Label: label, 589 Value: value, 590 } 591 } else { 592 return &adt.OptionalField{ 593 Src: x, 594 Label: label, 595 Value: value, 596 } 597 } 598 599 case *ast.ListLit: 600 if len(l.Elts) != 1 { 601 // error 602 return c.errf(x, "list label must have one element") 603 } 604 var label adt.Feature 605 elem := l.Elts[0] 606 // TODO: record alias for error handling? In principle it is okay 607 // to have duplicates, but we do want it to be used. 608 if a, ok := elem.(*ast.Alias); ok { 609 label = c.label(a.Ident) 610 elem = a.Expr 611 } 612 613 return &adt.BulkOptionalField{ 614 Src: x, 615 Filter: c.expr(elem), 616 Value: value, 617 Label: label, 618 } 619 620 case *ast.ParenExpr: 621 if x.Token == token.ISA { 622 c.errf(x, "definitions not supported for dynamic fields") 623 } 624 return &adt.DynamicField{ 625 Src: x, 626 Key: c.expr(l), 627 Value: value, 628 } 629 630 case *ast.Interpolation: 631 if x.Token == token.ISA { 632 c.errf(x, "definitions not supported for interpolations") 633 } 634 return &adt.DynamicField{ 635 Src: x, 636 Key: c.expr(l), 637 Value: value, 638 } 639 } 640 641 // Handled in addLetDecl. 642 case *ast.LetClause: 643 // case: *ast.Alias: // TODO(value alias) 644 645 case *ast.CommentGroup: 646 // Nothing to do for a free-floating comment group. 647 648 case *ast.Attribute: 649 // Nothing to do for now for an attribute declaration. 650 651 case *ast.Ellipsis: 652 return &adt.Ellipsis{ 653 Src: x, 654 Value: c.expr(x.Type), 655 } 656 657 case *ast.Comprehension: 658 return c.comprehension(x) 659 660 case *ast.EmbedDecl: // Deprecated 661 return c.expr(x.Expr) 662 663 case ast.Expr: 664 return c.expr(x) 665 } 666 return nil 667 } 668 669 func (c *compiler) addLetDecl(d ast.Decl) { 670 switch x := d.(type) { 671 // An alias reference will have an expression that is looked up in the 672 // environment cash. 673 case *ast.LetClause: 674 // Cache the parsed expression. Creating a unique expression for each 675 // reference allows the computation to be shared given that we don't 676 // have fields for expressions. This, in turn, prevents exponential 677 // blowup in x2: x1+x1, x3: x2+x2, ... patterns. 678 expr := c.labeledExpr(nil, (*letScope)(x), x.Expr) 679 c.updateAlias(x.Ident, expr) 680 681 case *ast.Alias: 682 c.errf(x, "old-style alias no longer supported: use let clause; use cue fix to update.") 683 } 684 } 685 686 func (c *compiler) elem(n ast.Expr) adt.Elem { 687 switch x := n.(type) { 688 case *ast.Ellipsis: 689 return &adt.Ellipsis{ 690 Src: x, 691 Value: c.expr(x.Type), 692 } 693 694 case *ast.Comprehension: 695 return c.comprehension(x) 696 697 case ast.Expr: 698 return c.expr(x) 699 } 700 return nil 701 } 702 703 func (c *compiler) comprehension(x *ast.Comprehension) adt.Elem { 704 var cur adt.Yielder 705 var first adt.Yielder 706 var prev, next *adt.Yielder 707 for _, v := range x.Clauses { 708 switch x := v.(type) { 709 case *ast.ForClause: 710 var key adt.Feature 711 if x.Key != nil { 712 key = c.label(x.Key) 713 } 714 y := &adt.ForClause{ 715 Syntax: x, 716 Key: key, 717 Value: c.label(x.Value), 718 Src: c.expr(x.Source), 719 } 720 cur = y 721 c.pushScope((*forScope)(x), 1, v) 722 defer c.popScope() 723 next = &y.Dst 724 725 case *ast.IfClause: 726 y := &adt.IfClause{ 727 Src: x, 728 Condition: c.expr(x.Condition), 729 } 730 cur = y 731 next = &y.Dst 732 733 case *ast.LetClause: 734 y := &adt.LetClause{ 735 Src: x, 736 Label: c.label(x.Ident), 737 Expr: c.expr(x.Expr), 738 } 739 cur = y 740 c.pushScope((*letScope)(x), 1, v) 741 defer c.popScope() 742 next = &y.Dst 743 } 744 745 if prev != nil { 746 *prev = cur 747 } else { 748 first = cur 749 if _, ok := cur.(*adt.LetClause); ok { 750 return c.errf(x, 751 "first comprehension clause must be 'if' or 'for'") 752 } 753 } 754 prev = next 755 } 756 757 // TODO: make x.Value an *ast.StructLit and this is redundant. 758 if y, ok := x.Value.(*ast.StructLit); !ok { 759 return c.errf(x.Value, 760 "comprehension value must be struct, found %T", y) 761 } 762 763 y := c.expr(x.Value) 764 765 st, ok := y.(*adt.StructLit) 766 if !ok { 767 // Error must have been generated. 768 return y 769 } 770 771 if prev != nil { 772 *prev = &adt.ValueClause{StructLit: st} 773 } else { 774 return c.errf(x, "comprehension value without clauses") 775 } 776 777 return &adt.Comprehension{ 778 Clauses: first, 779 Value: st, 780 } 781 } 782 783 func (c *compiler) labeledExpr(f *ast.Field, lab labeler, expr ast.Expr) adt.Expr { 784 k := len(c.stack) - 1 785 return c.labeledExprAt(k, f, lab, expr) 786 } 787 788 func (c *compiler) labeledExprAt(k int, f *ast.Field, lab labeler, expr ast.Expr) adt.Expr { 789 if c.stack[k].field != nil { 790 panic("expected nil field") 791 } 792 saved := c.stack[k] 793 794 c.stack[k].label = lab 795 c.stack[k].field = f 796 797 value := c.expr(expr) 798 799 c.stack[k] = saved 800 return value 801 } 802 803 func (c *compiler) expr(expr ast.Expr) adt.Expr { 804 switch n := expr.(type) { 805 case nil: 806 return nil 807 case *ast.Ident: 808 return c.resolve(n) 809 810 case *ast.StructLit: 811 c.pushScope(nil, 1, n) 812 v := &adt.StructLit{Src: n} 813 c.addDecls(v, n.Elts) 814 c.popScope() 815 return v 816 817 case *ast.ListLit: 818 c.pushScope(nil, 1, n) 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 c.popScope() 840 return v 841 842 case *ast.SelectorExpr: 843 c.inSelector++ 844 ret := &adt.SelectorExpr{ 845 Src: n, 846 X: c.expr(n.X), 847 Sel: c.label(n.Sel)} 848 c.inSelector-- 849 return ret 850 851 case *ast.IndexExpr: 852 return &adt.IndexExpr{ 853 Src: n, 854 X: c.expr(n.X), 855 Index: c.expr(n.Index), 856 } 857 858 case *ast.SliceExpr: 859 slice := &adt.SliceExpr{Src: n, X: c.expr(n.X)} 860 if n.Low != nil { 861 slice.Lo = c.expr(n.Low) 862 } 863 if n.High != nil { 864 slice.Hi = c.expr(n.High) 865 } 866 return slice 867 868 case *ast.BottomLit: 869 return &adt.Bottom{ 870 Src: n, 871 Code: adt.UserError, 872 Err: errors.Newf(n.Pos(), "explicit error (_|_ literal) in source"), 873 } 874 875 case *ast.BadExpr: 876 return c.errf(n, "invalid expression") 877 878 case *ast.BasicLit: 879 return c.parse(n) 880 881 case *ast.Interpolation: 882 if len(n.Elts) == 0 { 883 return c.errf(n, "invalid interpolation") 884 } 885 first, ok1 := n.Elts[0].(*ast.BasicLit) 886 last, ok2 := n.Elts[len(n.Elts)-1].(*ast.BasicLit) 887 if !ok1 || !ok2 { 888 return c.errf(n, "invalid interpolation") 889 } 890 if len(n.Elts) == 1 { 891 return c.expr(n.Elts[0]) 892 } 893 lit := &adt.Interpolation{Src: n} 894 info, prefixLen, _, err := literal.ParseQuotes(first.Value, last.Value) 895 if err != nil { 896 return c.errf(n, "invalid interpolation: %v", err) 897 } 898 if info.IsDouble() { 899 lit.K = adt.StringKind 900 } else { 901 lit.K = adt.BytesKind 902 } 903 prefix := "" 904 for i := 0; i < len(n.Elts); i += 2 { 905 l, ok := n.Elts[i].(*ast.BasicLit) 906 if !ok { 907 return c.errf(n, "invalid interpolation") 908 } 909 s := l.Value 910 if !strings.HasPrefix(s, prefix) { 911 return c.errf(l, "invalid interpolation: unmatched ')'") 912 } 913 s = l.Value[prefixLen:] 914 x := parseString(c, l, info, s) 915 lit.Parts = append(lit.Parts, x) 916 if i+1 < len(n.Elts) { 917 lit.Parts = append(lit.Parts, c.expr(n.Elts[i+1])) 918 } 919 prefix = ")" 920 prefixLen = 1 921 } 922 return lit 923 924 case *ast.ParenExpr: 925 return c.expr(n.X) 926 927 case *ast.CallExpr: 928 call := &adt.CallExpr{Src: n, Fun: c.expr(n.Fun)} 929 for _, a := range n.Args { 930 call.Args = append(call.Args, c.expr(a)) 931 } 932 return call 933 934 case *ast.UnaryExpr: 935 switch n.Op { 936 case token.NOT, token.ADD, token.SUB: 937 return &adt.UnaryExpr{ 938 Src: n, 939 Op: adt.OpFromToken(n.Op), 940 X: c.expr(n.X), 941 } 942 case token.GEQ, token.GTR, token.LSS, token.LEQ, 943 token.NEQ, token.MAT, token.NMAT: 944 return &adt.BoundExpr{ 945 Src: n, 946 Op: adt.OpFromToken(n.Op), 947 Expr: c.expr(n.X), 948 } 949 950 case token.MUL: 951 return c.errf(n, "preference mark not allowed at this position") 952 default: 953 return c.errf(n, "unsupported unary operator %q", n.Op) 954 } 955 956 case *ast.BinaryExpr: 957 switch n.Op { 958 case token.OR: 959 d := &adt.DisjunctionExpr{Src: n} 960 c.addDisjunctionElem(d, n.X, false) 961 c.addDisjunctionElem(d, n.Y, false) 962 return d 963 964 default: 965 op := adt.OpFromToken(n.Op) 966 x := c.expr(n.X) 967 y := c.expr(n.Y) 968 if op != adt.AndOp { 969 c.assertConcreteIsPossible(n.X, op, x) 970 c.assertConcreteIsPossible(n.Y, op, y) 971 } 972 // return updateBin(c, 973 return &adt.BinaryExpr{Src: n, Op: op, X: x, Y: y} // ) 974 } 975 976 default: 977 return c.errf(n, "%s values not allowed in this position", ast.Name(n)) 978 } 979 } 980 981 func (c *compiler) assertConcreteIsPossible(src ast.Node, op adt.Op, x adt.Expr) bool { 982 if !adt.AssertConcreteIsPossible(op, x) { 983 str := astinternal.DebugStr(src) 984 c.errf(src, "invalid operand %s ('%s' requires concrete value)", str, op) 985 } 986 return false 987 } 988 989 func (c *compiler) addDisjunctionElem(d *adt.DisjunctionExpr, n ast.Expr, mark bool) { 990 switch x := n.(type) { 991 case *ast.BinaryExpr: 992 if x.Op == token.OR { 993 c.addDisjunctionElem(d, x.X, mark) 994 c.addDisjunctionElem(d, x.Y, mark) 995 return 996 } 997 case *ast.UnaryExpr: 998 if x.Op == token.MUL { 999 d.HasDefaults = true 1000 c.addDisjunctionElem(d, x.X, true) 1001 return 1002 } 1003 } 1004 d.Values = append(d.Values, adt.Disjunct{Val: c.expr(n), Default: mark}) 1005 } 1006 1007 // TODO(perf): validate that regexps are cached at the right time. 1008 1009 func (c *compiler) parse(l *ast.BasicLit) (n adt.Expr) { 1010 s := l.Value 1011 if s == "" { 1012 return c.errf(l, "invalid literal %q", s) 1013 } 1014 switch l.Kind { 1015 case token.STRING: 1016 info, nStart, _, err := literal.ParseQuotes(s, s) 1017 if err != nil { 1018 return c.errf(l, err.Error()) 1019 } 1020 s := s[nStart:] 1021 return parseString(c, l, info, s) 1022 1023 case token.FLOAT, token.INT: 1024 err := literal.ParseNum(s, &c.num) 1025 if err != nil { 1026 return c.errf(l, "parse error: %v", err) 1027 } 1028 kind := adt.FloatKind 1029 if c.num.IsInt() { 1030 kind = adt.IntKind 1031 } 1032 n := &adt.Num{Src: l, K: kind} 1033 if err = c.num.Decimal(&n.X); err != nil { 1034 return c.errf(l, "error converting number to decimal: %v", err) 1035 } 1036 return n 1037 1038 case token.TRUE: 1039 return &adt.Bool{Src: l, B: true} 1040 1041 case token.FALSE: 1042 return &adt.Bool{Src: l, B: false} 1043 1044 case token.NULL: 1045 return &adt.Null{Src: l} 1046 1047 default: 1048 return c.errf(l, "unknown literal type") 1049 } 1050 } 1051 1052 // parseString decodes a string without the starting and ending quotes. 1053 func parseString(c *compiler, node ast.Expr, q literal.QuoteInfo, s string) (n adt.Expr) { 1054 str, err := q.Unquote(s) 1055 if err != nil { 1056 return c.errf(node, "invalid string: %v", err) 1057 } 1058 if q.IsDouble() { 1059 return &adt.String{Src: node, Str: str, RE: nil} 1060 } 1061 return &adt.Bytes{Src: node, B: []byte(str), RE: nil} 1062 }