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  }