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  }