github.com/solo-io/cue@v0.4.7/internal/core/adt/expr.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 adt
    16  
    17  import (
    18  	"bytes"
    19  	"fmt"
    20  	"io"
    21  	"regexp"
    22  
    23  	"github.com/cockroachdb/apd/v2"
    24  
    25  	"github.com/solo-io/cue/cue/ast"
    26  	"github.com/solo-io/cue/cue/errors"
    27  	"github.com/solo-io/cue/cue/token"
    28  )
    29  
    30  // A StructLit represents an unevaluated struct literal or file body.
    31  type StructLit struct {
    32  	Src   ast.Node // ast.File or ast.StructLit
    33  	Decls []Decl
    34  
    35  	// TODO: record the merge order somewhere.
    36  
    37  	// The below fields are redundant to Decls and are computed with Init.
    38  
    39  	// field marks the optional conjuncts of all explicit Fields.
    40  	// Required Fields are marked as empty
    41  	Fields []FieldInfo
    42  
    43  	Dynamic []*DynamicField
    44  
    45  	// excluded are all literal fields that already exist.
    46  	Bulk []*BulkOptionalField
    47  
    48  	Additional  []Expr
    49  	HasEmbed    bool
    50  	IsOpen      bool // has a ...
    51  	initialized bool
    52  
    53  	types OptionalType
    54  
    55  	// administrative fields like hasreferences.
    56  	// hasReferences bool
    57  }
    58  
    59  func (o *StructLit) IsFile() bool {
    60  	_, ok := o.Src.(*ast.File)
    61  	return ok
    62  }
    63  
    64  type FieldInfo struct {
    65  	Label    Feature
    66  	Optional []Node
    67  }
    68  
    69  func (x *StructLit) HasOptional() bool {
    70  	return x.types&(HasField|HasPattern|HasAdditional) != 0
    71  }
    72  
    73  func (x *StructLit) Source() ast.Node { return x.Src }
    74  
    75  func (x *StructLit) evaluate(c *OpContext) Value {
    76  	e := c.Env(0)
    77  	v := &Vertex{Conjuncts: []Conjunct{{e, x, CloseInfo{}}}}
    78  	// evaluate may not finalize a field, as the resulting value may be
    79  	// used in a context where more conjuncts are added. It may also lead
    80  	// to disjuncts being in a partially expanded state, leading to
    81  	// misaligned nodeContexts.
    82  	c.Unify(v, AllArcs)
    83  	return v
    84  }
    85  
    86  // TODO: remove this method
    87  func (o *StructLit) MarkField(f Feature) {
    88  	o.Fields = append(o.Fields, FieldInfo{Label: f})
    89  }
    90  
    91  func (o *StructLit) Init() {
    92  	if o.initialized {
    93  		return
    94  	}
    95  	o.initialized = true
    96  	for _, d := range o.Decls {
    97  		switch x := d.(type) {
    98  		case *Field:
    99  			if o.fieldIndex(x.Label) < 0 {
   100  				o.Fields = append(o.Fields, FieldInfo{Label: x.Label})
   101  			}
   102  
   103  		case *OptionalField:
   104  			p := o.fieldIndex(x.Label)
   105  			if p < 0 {
   106  				p = len(o.Fields)
   107  				o.Fields = append(o.Fields, FieldInfo{Label: x.Label})
   108  			}
   109  			o.Fields[p].Optional = append(o.Fields[p].Optional, x)
   110  			o.types |= HasField
   111  
   112  		case *DynamicField:
   113  			o.Dynamic = append(o.Dynamic, x)
   114  			o.types |= HasDynamic
   115  
   116  		case Expr:
   117  			o.HasEmbed = true
   118  
   119  		case *ForClause, Yielder:
   120  			o.HasEmbed = true
   121  
   122  		case *BulkOptionalField:
   123  			o.Bulk = append(o.Bulk, x)
   124  			o.types |= HasPattern
   125  			switch x.Filter.(type) {
   126  			case *BasicType, *Top:
   127  			default:
   128  				o.types |= HasComplexPattern
   129  			}
   130  
   131  		case *Ellipsis:
   132  			expr := x.Value
   133  			if x.Value == nil {
   134  				o.IsOpen = true
   135  				o.types |= IsOpen
   136  				// TODO(perf): encode more efficiently.
   137  				expr = &Top{}
   138  			} else {
   139  				o.types |= HasAdditional
   140  			}
   141  			o.Additional = append(o.Additional, expr)
   142  
   143  		default:
   144  			panic("unreachable")
   145  		}
   146  	}
   147  }
   148  
   149  func (o *StructLit) fieldIndex(f Feature) int {
   150  	for i := range o.Fields {
   151  		if o.Fields[i].Label == f {
   152  			return i
   153  		}
   154  	}
   155  	return -1
   156  }
   157  
   158  func (o *StructLit) OptionalTypes() OptionalType {
   159  	return o.types
   160  }
   161  
   162  func (o *StructLit) IsOptional(label Feature) bool {
   163  	for _, f := range o.Fields {
   164  		if f.Label == label && len(f.Optional) > 0 {
   165  			return true
   166  		}
   167  	}
   168  	return false
   169  }
   170  
   171  // FIELDS
   172  //
   173  // Fields can also be used as expressions whereby the value field is the
   174  // expression this allows retaining more context.
   175  
   176  // Field represents a field with a fixed label. It can be a regular field,
   177  // definition or hidden field.
   178  //
   179  //   foo: bar
   180  //   #foo: bar
   181  //   _foo: bar
   182  //
   183  // Legacy:
   184  //
   185  //   Foo :: bar
   186  //
   187  type Field struct {
   188  	Src *ast.Field
   189  
   190  	Label Feature
   191  	Value Expr
   192  }
   193  
   194  func (x *Field) Source() ast.Node {
   195  	if x.Src == nil {
   196  		return nil
   197  	}
   198  	return x.Src
   199  }
   200  
   201  // An OptionalField represents an optional regular field.
   202  //
   203  //   foo?: expr
   204  //
   205  type OptionalField struct {
   206  	Src   *ast.Field
   207  	Label Feature
   208  	Value Expr
   209  }
   210  
   211  func (x *OptionalField) Source() ast.Node {
   212  	if x.Src == nil {
   213  		return nil
   214  	}
   215  	return x.Src
   216  }
   217  
   218  // A BulkOptionalField represents a set of optional field.
   219  //
   220  //   [expr]: expr
   221  //
   222  type BulkOptionalField struct {
   223  	Src    *ast.Field // Elipsis or Field
   224  	Filter Expr
   225  	Value  Expr
   226  	Label  Feature // for reference and formatting
   227  }
   228  
   229  func (x *BulkOptionalField) Source() ast.Node {
   230  	if x.Src == nil {
   231  		return nil
   232  	}
   233  	return x.Src
   234  }
   235  
   236  // A Ellipsis represents a set of optional fields of a given type.
   237  //
   238  //   ...T
   239  //
   240  type Ellipsis struct {
   241  	Src   *ast.Ellipsis
   242  	Value Expr
   243  }
   244  
   245  func (x *Ellipsis) Source() ast.Node {
   246  	if x.Src == nil {
   247  		return nil
   248  	}
   249  	return x.Src
   250  }
   251  
   252  // A DynamicField represents a regular field for which the key is computed.
   253  //
   254  //    "\(expr)": expr
   255  //    (expr): expr
   256  //
   257  type DynamicField struct {
   258  	Src   *ast.Field
   259  	Key   Expr
   260  	Value Expr
   261  }
   262  
   263  func (x *DynamicField) IsOptional() bool {
   264  	return x.Src.Optional != token.NoPos
   265  }
   266  
   267  func (x *DynamicField) Source() ast.Node {
   268  	if x.Src == nil {
   269  		return nil
   270  	}
   271  	return x.Src
   272  }
   273  
   274  // A ListLit represents an unevaluated list literal.
   275  //
   276  //    [a, for x in src { ... }, b, ...T]
   277  //
   278  type ListLit struct {
   279  	Src *ast.ListLit
   280  
   281  	// scalars, comprehensions, ...T
   282  	Elems []Elem
   283  }
   284  
   285  func (x *ListLit) Source() ast.Node {
   286  	if x.Src == nil {
   287  		return nil
   288  	}
   289  	return x.Src
   290  }
   291  
   292  func (x *ListLit) evaluate(c *OpContext) Value {
   293  	e := c.Env(0)
   294  	v := &Vertex{Conjuncts: []Conjunct{{e, x, CloseInfo{}}}}
   295  	// TODO: should be AllArcs and then use Finalize for builtins?
   296  	c.Unify(v, Finalized) // TODO: also partial okay?
   297  	return v
   298  }
   299  
   300  // Null represents null. It can be used as a Value and Expr.
   301  type Null struct {
   302  	Src ast.Node
   303  }
   304  
   305  func (x *Null) Source() ast.Node { return x.Src }
   306  func (x *Null) Kind() Kind       { return NullKind }
   307  
   308  // Bool is a boolean value. It can be used as a Value and Expr.
   309  type Bool struct {
   310  	Src ast.Node
   311  	B   bool
   312  }
   313  
   314  func (x *Bool) Source() ast.Node { return x.Src }
   315  func (x *Bool) Kind() Kind       { return BoolKind }
   316  
   317  // Num is a numeric value. It can be used as a Value and Expr.
   318  type Num struct {
   319  	Src ast.Node
   320  	K   Kind        // needed?
   321  	X   apd.Decimal // Is integer if the apd.Decimal is an integer.
   322  }
   323  
   324  // TODO: do we need this?
   325  // func NewNumFromString(src ast.Node, s string) Value {
   326  // 	n := &Num{Src: src, K: IntKind}
   327  // 	if strings.ContainsAny(s, "eE.") {
   328  // 		n.K = FloatKind
   329  // 	}
   330  // 	_, _, err := n.X.SetString(s)
   331  // 	if err != nil {
   332  // 		pos := token.NoPos
   333  // 		if src != nil {
   334  // 			pos = src.Pos()
   335  // 		}
   336  // 		return &Bottom{Err: errors.Newf(pos, "invalid number: %v", err)}
   337  // 	}
   338  // 	return n
   339  // }
   340  
   341  func (x *Num) Source() ast.Node { return x.Src }
   342  func (x *Num) Kind() Kind       { return x.K }
   343  
   344  // TODO: do we still need this?
   345  // func (x *Num) Specialize(k Kind) Value {
   346  // 	k = k & x.K
   347  // 	if k == x.K {
   348  // 		return x
   349  // 	}
   350  // 	y := *x
   351  // 	y.K = k
   352  // 	return &y
   353  // }
   354  
   355  // String is a string value. It can be used as a Value and Expr.
   356  type String struct {
   357  	Src ast.Node
   358  	Str string
   359  	RE  *regexp.Regexp // only set if needed
   360  }
   361  
   362  func (x *String) Source() ast.Node { return x.Src }
   363  func (x *String) Kind() Kind       { return StringKind }
   364  
   365  // Bytes is a bytes value. It can be used as a Value and Expr.
   366  type Bytes struct {
   367  	Src ast.Node
   368  	B   []byte
   369  	RE  *regexp.Regexp // only set if needed
   370  }
   371  
   372  func (x *Bytes) Source() ast.Node { return x.Src }
   373  func (x *Bytes) Kind() Kind       { return BytesKind }
   374  
   375  // Composites: the evaluated fields of a composite are recorded in the arc
   376  // vertices.
   377  
   378  type ListMarker struct {
   379  	Src    ast.Node
   380  	IsOpen bool
   381  }
   382  
   383  func (x *ListMarker) Source() ast.Node { return x.Src }
   384  func (x *ListMarker) Kind() Kind       { return ListKind }
   385  func (x *ListMarker) node()            {}
   386  
   387  type StructMarker struct {
   388  	// NeedClose is used to signal that the evaluator should close this struct.
   389  	// It is only set by the close builtin.
   390  	NeedClose bool
   391  }
   392  
   393  func (x *StructMarker) Source() ast.Node { return nil }
   394  func (x *StructMarker) Kind() Kind       { return StructKind }
   395  func (x *StructMarker) node()            {}
   396  
   397  // Top represents all possible values. It can be used as a Value and Expr.
   398  type Top struct{ Src *ast.Ident }
   399  
   400  func (x *Top) Source() ast.Node {
   401  	if x.Src == nil {
   402  		return nil
   403  	}
   404  	return x.Src
   405  }
   406  func (x *Top) Kind() Kind { return TopKind }
   407  
   408  // BasicType represents all values of a certain Kind. It can be used as a Value
   409  // and Expr.
   410  //
   411  //   string
   412  //   int
   413  //   num
   414  //   bool
   415  //
   416  type BasicType struct {
   417  	Src *ast.Ident
   418  	K   Kind
   419  }
   420  
   421  func (x *BasicType) Source() ast.Node {
   422  	if x.Src == nil {
   423  		return nil
   424  	}
   425  	return x.Src
   426  }
   427  func (x *BasicType) Kind() Kind { return x.K }
   428  
   429  // TODO: do we still need this?
   430  // func (x *BasicType) Specialize(k Kind) Value {
   431  // 	k = x.K & k
   432  // 	if k == x.K {
   433  // 		return x
   434  // 	}
   435  // 	y := *x
   436  // 	y.K = k
   437  // 	return &y
   438  // }
   439  
   440  // TODO: should we use UnaryExpr for Bound now we have BoundValue?
   441  
   442  // BoundExpr represents an unresolved unary comparator.
   443  //
   444  //    <a
   445  //    =~MyPattern
   446  //
   447  type BoundExpr struct {
   448  	Src  *ast.UnaryExpr
   449  	Op   Op
   450  	Expr Expr
   451  }
   452  
   453  func (x *BoundExpr) Source() ast.Node {
   454  	if x.Src == nil {
   455  		return nil
   456  	}
   457  	return x.Src
   458  }
   459  
   460  func (x *BoundExpr) evaluate(ctx *OpContext) Value {
   461  	v := ctx.value(x.Expr)
   462  	if isError(v) {
   463  		return v
   464  	}
   465  
   466  	switch k := v.Kind(); k {
   467  	case IntKind, FloatKind, NumKind, StringKind, BytesKind:
   468  	case NullKind:
   469  		if x.Op != NotEqualOp {
   470  			err := ctx.NewPosf(pos(x.Expr),
   471  				"cannot use null for bound %s", x.Op)
   472  			return &Bottom{Err: err}
   473  		}
   474  	default:
   475  		mask := IntKind | FloatKind | NumKind | StringKind | BytesKind
   476  		if x.Op == NotEqualOp {
   477  			mask |= NullKind
   478  		}
   479  		if k&mask != 0 {
   480  			ctx.addErrf(IncompleteError, token.NoPos, // TODO(errors): use ctx.pos()?
   481  				"non-concrete value %s for bound %s", x.Expr, x.Op)
   482  			return nil
   483  		}
   484  		err := ctx.NewPosf(pos(x.Expr),
   485  			"invalid value %s (type %s) for bound %s", v, k, x.Op)
   486  		return &Bottom{Err: err}
   487  	}
   488  
   489  	if v, ok := x.Expr.(Value); ok {
   490  		if v == nil || v.Concreteness() > Concrete {
   491  			return ctx.NewErrf("bound has fixed non-concrete value")
   492  		}
   493  		return &BoundValue{x.Src, x.Op, v}
   494  	}
   495  
   496  	// This simplifies boundary expressions. It is an alternative to an
   497  	// evaluation strategy that makes nodes increasingly more specific.
   498  	//
   499  	// For instance, a completely different implementation would be to allow
   500  	// the precense of a concrete value to ignore incomplete errors.
   501  	//
   502  	// TODO: consider an alternative approach.
   503  	switch y := v.(type) {
   504  	case *BoundValue:
   505  		switch {
   506  		case y.Op == NotEqualOp:
   507  			switch x.Op {
   508  			case LessEqualOp, LessThanOp, GreaterEqualOp, GreaterThanOp:
   509  				// <(!=3)  =>  number
   510  				// Smaller than an arbitrarily large number is any number.
   511  				return &BasicType{K: y.Kind()}
   512  			case NotEqualOp:
   513  				// !=(!=3) ==> 3
   514  				// Not a value that is anything but a given value is that
   515  				// given value.
   516  				return y.Value
   517  			}
   518  
   519  		case x.Op == NotEqualOp:
   520  			// Invert if applicable.
   521  			switch y.Op {
   522  			case LessEqualOp:
   523  				return &BoundValue{x.Src, GreaterThanOp, y.Value}
   524  			case LessThanOp:
   525  				return &BoundValue{x.Src, GreaterEqualOp, y.Value}
   526  			case GreaterEqualOp:
   527  				return &BoundValue{x.Src, LessThanOp, y.Value}
   528  			case GreaterThanOp:
   529  				return &BoundValue{x.Src, LessEqualOp, y.Value}
   530  			}
   531  
   532  		case (x.Op == LessThanOp || x.Op == LessEqualOp) &&
   533  			(y.Op == GreaterThanOp || y.Op == GreaterEqualOp),
   534  			(x.Op == GreaterThanOp || x.Op == GreaterEqualOp) &&
   535  				(y.Op == LessThanOp || y.Op == LessEqualOp):
   536  			// <(>=3)
   537  			// Something smaller than an arbitrarily large number is any number.
   538  			return &BasicType{K: y.Kind()}
   539  
   540  		case x.Op == LessThanOp &&
   541  			(y.Op == LessEqualOp || y.Op == LessThanOp),
   542  			x.Op == GreaterThanOp &&
   543  				(y.Op == GreaterEqualOp || y.Op == GreaterThanOp):
   544  			// <(<=x)  => <x
   545  			// <(<x)   => <x
   546  			// Less than something that is less or equal to x is less than x.
   547  			return &BoundValue{x.Src, x.Op, y.Value}
   548  
   549  		case x.Op == LessEqualOp &&
   550  			(y.Op == LessEqualOp || y.Op == LessThanOp),
   551  			x.Op == GreaterEqualOp &&
   552  				(y.Op == GreaterEqualOp || y.Op == GreaterThanOp):
   553  			// <=(<x)   => <x
   554  			// <=(<=x)  => <=x
   555  			// Less or equal than something that is less than x is less than x.
   556  			return y
   557  		}
   558  
   559  	case *BasicType:
   560  		switch x.Op {
   561  		case LessEqualOp, LessThanOp, GreaterEqualOp, GreaterThanOp:
   562  			return y
   563  		}
   564  	}
   565  	if v.Concreteness() > Concrete {
   566  		// TODO(errors): analyze dependencies of x.Expr to get positions.
   567  		ctx.addErrf(IncompleteError, token.NoPos, // TODO(errors): use ctx.pos()?
   568  			"non-concrete value %s for bound %s", x.Expr, x.Op)
   569  		return nil
   570  	}
   571  	return &BoundValue{x.Src, x.Op, v}
   572  }
   573  
   574  // A BoundValue is a fully evaluated unary comparator that can be used to
   575  // validate other values.
   576  //
   577  //    <5
   578  //    =~"Name$"
   579  //
   580  type BoundValue struct {
   581  	Src   ast.Expr
   582  	Op    Op
   583  	Value Value
   584  }
   585  
   586  func (x *BoundValue) Source() ast.Node { return x.Src }
   587  func (x *BoundValue) Kind() Kind {
   588  	k := x.Value.Kind()
   589  	switch k {
   590  	case IntKind, FloatKind, NumKind:
   591  		return NumKind
   592  
   593  	case NullKind:
   594  		if x.Op == NotEqualOp {
   595  			return TopKind &^ NullKind
   596  		}
   597  	}
   598  	return k
   599  }
   600  
   601  func (x *BoundValue) validate(c *OpContext, y Value) *Bottom {
   602  	a := y // Can be list or struct.
   603  	b := c.scalar(x.Value)
   604  	if c.HasErr() {
   605  		return c.Err()
   606  	}
   607  
   608  	switch v := BinOp(c, x.Op, a, b).(type) {
   609  	case *Bottom:
   610  		return v
   611  
   612  	case *Bool:
   613  		if v.B {
   614  			return nil
   615  		}
   616  		// TODO(errors): use "invalid value %v (not an %s)" if x is a
   617  		// predeclared identifier such as `int`.
   618  		err := c.Newf("invalid value %v (out of bound %s)", y, x)
   619  		err.AddPosition(y)
   620  		return &Bottom{Src: c.src, Err: err, Code: EvalError}
   621  
   622  	default:
   623  		panic(fmt.Sprintf("unsupported type %T", v))
   624  	}
   625  }
   626  
   627  func (x *BoundValue) validateStr(c *OpContext, a string) bool {
   628  	if str, ok := x.Value.(*String); ok {
   629  		b := str.Str
   630  		switch x.Op {
   631  		case LessEqualOp:
   632  			return a <= b
   633  		case LessThanOp:
   634  			return a < b
   635  		case GreaterEqualOp:
   636  			return a >= b
   637  		case GreaterThanOp:
   638  			return a > b
   639  		case EqualOp:
   640  			return a == b
   641  		case NotEqualOp:
   642  			return a != b
   643  		case MatchOp:
   644  			return c.regexp(x.Value).MatchString(a)
   645  		case NotMatchOp:
   646  			return !c.regexp(x.Value).MatchString(a)
   647  		}
   648  	}
   649  	return x.validate(c, &String{Str: a}) == nil
   650  }
   651  
   652  func (x *BoundValue) validateInt(c *OpContext, a int64) bool {
   653  	switch n := x.Value.(type) {
   654  	case *Num:
   655  		b, err := n.X.Int64()
   656  		if err != nil {
   657  			break
   658  		}
   659  		switch x.Op {
   660  		case LessEqualOp:
   661  			return a <= b
   662  		case LessThanOp:
   663  			return a < b
   664  		case GreaterEqualOp:
   665  			return a >= b
   666  		case GreaterThanOp:
   667  			return a > b
   668  		case EqualOp:
   669  			return a == b
   670  		case NotEqualOp:
   671  			return a != b
   672  		}
   673  	}
   674  	return x.validate(c, c.NewInt64(a)) == nil
   675  }
   676  
   677  // A NodeLink is used during computation to refer to an existing Vertex.
   678  // It is used to signal a potential cycle or reference.
   679  // Note that a NodeLink may be used as a value. This should be taken into
   680  // account.
   681  type NodeLink struct {
   682  	Node *Vertex
   683  }
   684  
   685  func (x *NodeLink) Kind() Kind {
   686  	return x.Node.Kind()
   687  }
   688  func (x *NodeLink) Source() ast.Node { return x.Node.Source() }
   689  
   690  func (x *NodeLink) resolve(c *OpContext, state VertexStatus) *Vertex {
   691  	return x.Node
   692  }
   693  
   694  // A FieldReference represents a lexical reference to a field.
   695  //
   696  //    a
   697  //
   698  type FieldReference struct {
   699  	Src     *ast.Ident
   700  	UpCount int32
   701  	Label   Feature
   702  }
   703  
   704  func (x *FieldReference) Source() ast.Node {
   705  	if x.Src == nil {
   706  		return nil
   707  	}
   708  	return x.Src
   709  }
   710  
   711  func (x *FieldReference) resolve(c *OpContext, state VertexStatus) *Vertex {
   712  	n := c.relNode(x.UpCount)
   713  	pos := pos(x)
   714  	return c.lookup(n, pos, x.Label, state)
   715  }
   716  
   717  // A ValueReference represents a lexical reference to a value.
   718  //
   719  //    a: X=b
   720  //
   721  type ValueReference struct {
   722  	Src     *ast.Ident
   723  	UpCount int32
   724  	Label   Feature // for informative purposes
   725  }
   726  
   727  func (x *ValueReference) Source() ast.Node {
   728  	if x.Src == nil {
   729  		return nil
   730  	}
   731  	return x.Src
   732  }
   733  
   734  func (x *ValueReference) resolve(c *OpContext, state VertexStatus) *Vertex {
   735  	if x.UpCount == 0 {
   736  		return c.vertex
   737  	}
   738  	n := c.relNode(x.UpCount - 1)
   739  	return n
   740  }
   741  
   742  // A LabelReference refers to the string or integer value of a label.
   743  //
   744  //    [X=Pattern]: b: X
   745  //
   746  type LabelReference struct {
   747  	Src     *ast.Ident
   748  	UpCount int32
   749  }
   750  
   751  // TODO: should this implement resolver at all?
   752  
   753  func (x *LabelReference) Source() ast.Node {
   754  	if x.Src == nil {
   755  		return nil
   756  	}
   757  	return x.Src
   758  }
   759  
   760  func (x *LabelReference) evaluate(ctx *OpContext) Value {
   761  	label := ctx.relLabel(x.UpCount)
   762  	if label == 0 {
   763  		// There is no label. This may happen if a LabelReference is evaluated
   764  		// outside of the context of a parent node, for instance if an
   765  		// "additional" items or properties is evaluated in isolation.
   766  		//
   767  		// TODO: this should return the pattern of the label.
   768  		return &BasicType{K: StringKind}
   769  	}
   770  	return label.ToValue(ctx)
   771  }
   772  
   773  // A DynamicReference is like a LabelReference, but with a computed label.
   774  //
   775  //    X=(x): X
   776  //    X="\(x)": X
   777  //
   778  type DynamicReference struct {
   779  	Src     *ast.Ident
   780  	UpCount int32
   781  	Label   Expr
   782  
   783  	// TODO: only use aliases and store the actual expression only in the scope.
   784  	// The feature is unique for every instance. This will also allow dynamic
   785  	// fields to be ordered among normal fields.
   786  	//
   787  	// This could also be used to assign labels to embedded values, if they
   788  	// don't match a label.
   789  	Alias Feature
   790  }
   791  
   792  func (x *DynamicReference) Source() ast.Node {
   793  	if x.Src == nil {
   794  		return nil
   795  	}
   796  	return x.Src
   797  }
   798  
   799  func (x *DynamicReference) resolve(ctx *OpContext, state VertexStatus) *Vertex {
   800  	e := ctx.Env(x.UpCount)
   801  	frame := ctx.PushState(e, x.Src)
   802  	v := ctx.value(x.Label)
   803  	ctx.PopState(frame)
   804  	f := ctx.Label(x.Label, v)
   805  	return ctx.lookup(e.Vertex, pos(x), f, state)
   806  }
   807  
   808  // An ImportReference refers to an imported package.
   809  //
   810  //    import "strings"
   811  //
   812  //    strings.ToLower("Upper")
   813  //
   814  type ImportReference struct {
   815  	Src        *ast.Ident
   816  	ImportPath Feature
   817  	Label      Feature // for informative purposes
   818  }
   819  
   820  func (x *ImportReference) Source() ast.Node {
   821  	if x.Src == nil {
   822  		return nil
   823  	}
   824  	return x.Src
   825  }
   826  
   827  func (x *ImportReference) resolve(ctx *OpContext, state VertexStatus) *Vertex {
   828  	path := x.ImportPath.StringValue(ctx)
   829  	v, _ := ctx.Runtime.LoadImport(path)
   830  	return v
   831  }
   832  
   833  // A LetReference evaluates a let expression in its original environment.
   834  //
   835  //   let X = x
   836  //
   837  type LetReference struct {
   838  	Src     *ast.Ident
   839  	UpCount int32
   840  	Label   Feature // for informative purposes
   841  	X       Expr
   842  }
   843  
   844  func (x *LetReference) Source() ast.Node {
   845  	if x.Src == nil {
   846  		return nil
   847  	}
   848  	return x.Src
   849  }
   850  
   851  func (x *LetReference) resolve(c *OpContext, state VertexStatus) *Vertex {
   852  	e := c.Env(x.UpCount)
   853  	label := e.Vertex.Label
   854  	if x.X == nil {
   855  		panic("nil expression")
   856  	}
   857  	// Anonymous arc.
   858  	return &Vertex{Parent: nil, Label: label, Conjuncts: []Conjunct{{e, x.X, CloseInfo{}}}}
   859  }
   860  
   861  func (x *LetReference) evaluate(c *OpContext) Value {
   862  	e := c.Env(x.UpCount)
   863  
   864  	// Not caching let expressions may lead to exponential behavior.
   865  	return e.evalCached(c, x.X)
   866  }
   867  
   868  // A SelectorExpr looks up a fixed field in an expression.
   869  //
   870  //     X.Sel
   871  //
   872  type SelectorExpr struct {
   873  	Src *ast.SelectorExpr
   874  	X   Expr
   875  	Sel Feature
   876  }
   877  
   878  func (x *SelectorExpr) Source() ast.Node {
   879  	if x.Src == nil {
   880  		return nil
   881  	}
   882  	return x.Src
   883  }
   884  
   885  func (x *SelectorExpr) resolve(c *OpContext, state VertexStatus) *Vertex {
   886  	n := c.node(x, x.X, x.Sel.IsRegular(), state)
   887  	if n == emptyNode {
   888  		return n
   889  	}
   890  	if n.status == Partial {
   891  		if b := n.state.incompleteErrors(); b != nil && b.Code < CycleError {
   892  			n.BaseValue = b
   893  			return n
   894  		}
   895  	}
   896  	return c.lookup(n, x.Src.Sel.Pos(), x.Sel, state)
   897  }
   898  
   899  // IndexExpr is like a selector, but selects an index.
   900  //
   901  //    X[Index]
   902  //
   903  type IndexExpr struct {
   904  	Src   *ast.IndexExpr
   905  	X     Expr
   906  	Index Expr
   907  }
   908  
   909  func (x *IndexExpr) Source() ast.Node {
   910  	if x.Src == nil {
   911  		return nil
   912  	}
   913  	return x.Src
   914  }
   915  
   916  func (x *IndexExpr) resolve(ctx *OpContext, state VertexStatus) *Vertex {
   917  	// TODO: support byte index.
   918  	n := ctx.node(x, x.X, true, state)
   919  	i := ctx.value(x.Index)
   920  	if n == emptyNode {
   921  		return n
   922  	}
   923  	if n.status == Partial {
   924  		if b := n.state.incompleteErrors(); b != nil && b.Code < CycleError {
   925  			n.BaseValue = b
   926  			return n
   927  		}
   928  	}
   929  	f := ctx.Label(x.Index, i)
   930  	return ctx.lookup(n, x.Src.Index.Pos(), f, state)
   931  }
   932  
   933  // A SliceExpr represents a slice operation. (Not currently in spec.)
   934  //
   935  //    X[Lo:Hi:Stride]
   936  //
   937  type SliceExpr struct {
   938  	Src    *ast.SliceExpr
   939  	X      Expr
   940  	Lo     Expr
   941  	Hi     Expr
   942  	Stride Expr
   943  }
   944  
   945  func (x *SliceExpr) Source() ast.Node {
   946  	if x.Src == nil {
   947  		return nil
   948  	}
   949  	return x.Src
   950  }
   951  
   952  func (x *SliceExpr) evaluate(c *OpContext) Value {
   953  	// TODO: strides
   954  
   955  	v := c.value(x.X)
   956  	const as = "slice index"
   957  
   958  	switch v := v.(type) {
   959  	case nil:
   960  		c.addErrf(IncompleteError, c.pos(), "non-concrete slice subject %s", x.X)
   961  		return nil
   962  	case *Vertex:
   963  		if !v.IsList() {
   964  			break
   965  		}
   966  
   967  		var (
   968  			lo = uint64(0)
   969  			hi = uint64(len(v.Arcs))
   970  		)
   971  		if x.Lo != nil {
   972  			lo = c.uint64(c.value(x.Lo), as)
   973  		}
   974  		if x.Hi != nil {
   975  			hi = c.uint64(c.value(x.Hi), as)
   976  			if hi > uint64(len(v.Arcs)) {
   977  				return c.NewErrf("index %d out of range", hi)
   978  			}
   979  		}
   980  		if lo > hi {
   981  			return c.NewErrf("invalid slice index: %d > %d", lo, hi)
   982  		}
   983  
   984  		n := c.newList(c.src, v.Parent)
   985  		for i, a := range v.Arcs[lo:hi] {
   986  			label, err := MakeLabel(a.Source(), int64(i), IntLabel)
   987  			if err != nil {
   988  				c.AddBottom(&Bottom{Src: a.Source(), Err: err})
   989  				return nil
   990  			}
   991  			arc := *a
   992  			arc.Parent = n
   993  			arc.Label = label
   994  			n.Arcs = append(n.Arcs, &arc)
   995  		}
   996  		n.status = Finalized
   997  		return n
   998  
   999  	case *Bytes:
  1000  		var (
  1001  			lo = uint64(0)
  1002  			hi = uint64(len(v.B))
  1003  		)
  1004  		if x.Lo != nil {
  1005  			lo = c.uint64(c.value(x.Lo), as)
  1006  		}
  1007  		if x.Hi != nil {
  1008  			hi = c.uint64(c.value(x.Hi), as)
  1009  			if hi > uint64(len(v.B)) {
  1010  				return c.NewErrf("index %d out of range", hi)
  1011  			}
  1012  		}
  1013  		if lo > hi {
  1014  			return c.NewErrf("invalid slice index: %d > %d", lo, hi)
  1015  		}
  1016  		return c.newBytes(v.B[lo:hi])
  1017  	}
  1018  
  1019  	if isError(v) {
  1020  		return v
  1021  	}
  1022  	return c.NewErrf("cannot slice %v (type %s)", v, v.Kind())
  1023  }
  1024  
  1025  // An Interpolation is a string interpolation.
  1026  //
  1027  //    "a \(b) c"
  1028  //
  1029  type Interpolation struct {
  1030  	Src   *ast.Interpolation
  1031  	K     Kind   // string or bytes
  1032  	Parts []Expr // odd: strings, even sources
  1033  }
  1034  
  1035  func (x *Interpolation) Source() ast.Node {
  1036  	if x.Src == nil {
  1037  		return nil
  1038  	}
  1039  	return x.Src
  1040  }
  1041  
  1042  func (x *Interpolation) evaluate(c *OpContext) Value {
  1043  	buf := bytes.Buffer{}
  1044  	for _, e := range x.Parts {
  1045  		v := c.value(e)
  1046  		if x.K == BytesKind {
  1047  			buf.Write(c.ToBytes(v))
  1048  		} else {
  1049  			buf.WriteString(c.ToString(v))
  1050  		}
  1051  	}
  1052  	if err := c.Err(); err != nil {
  1053  		err = &Bottom{
  1054  			Code: err.Code,
  1055  			Err:  errors.Wrapf(err.Err, pos(x), "invalid interpolation"),
  1056  		}
  1057  		// c.AddBottom(err)
  1058  		// return nil
  1059  		return err
  1060  	}
  1061  	if x.K == BytesKind {
  1062  		return &Bytes{x.Src, buf.Bytes(), nil}
  1063  	}
  1064  	return &String{x.Src, buf.String(), nil}
  1065  }
  1066  
  1067  // UnaryExpr is a unary expression.
  1068  //
  1069  //    Op X
  1070  //    -X !X +X
  1071  //
  1072  type UnaryExpr struct {
  1073  	Src *ast.UnaryExpr
  1074  	Op  Op
  1075  	X   Expr
  1076  }
  1077  
  1078  func (x *UnaryExpr) Source() ast.Node {
  1079  	if x.Src == nil {
  1080  		return nil
  1081  	}
  1082  	return x.Src
  1083  }
  1084  
  1085  func (x *UnaryExpr) evaluate(c *OpContext) Value {
  1086  	if !c.concreteIsPossible(x.Op, x.X) {
  1087  		return nil
  1088  	}
  1089  	v := c.value(x.X)
  1090  	if isError(v) {
  1091  		return v
  1092  	}
  1093  
  1094  	op := x.Op
  1095  	k := kind(v)
  1096  	expectedKind := k
  1097  	switch op {
  1098  	case SubtractOp:
  1099  		if v, ok := v.(*Num); ok {
  1100  			f := *v
  1101  			f.X.Neg(&v.X)
  1102  			f.Src = x.Src
  1103  			return &f
  1104  		}
  1105  		expectedKind = NumKind
  1106  
  1107  	case AddOp:
  1108  		if v, ok := v.(*Num); ok {
  1109  			// TODO: wrap in thunk to save position of '+'?
  1110  			return v
  1111  		}
  1112  		expectedKind = NumKind
  1113  
  1114  	case NotOp:
  1115  		if v, ok := v.(*Bool); ok {
  1116  			return &Bool{x.Src, !v.B}
  1117  		}
  1118  		expectedKind = BoolKind
  1119  	}
  1120  	if k&expectedKind != BottomKind {
  1121  		c.addErrf(IncompleteError, pos(x.X),
  1122  			"operand %s of '%s' not concrete (was %s)", x.X, op, k)
  1123  		return nil
  1124  	}
  1125  	return c.NewErrf("invalid operation %s (%s %s)", x, op, k)
  1126  }
  1127  
  1128  // BinaryExpr is a binary expression.
  1129  //
  1130  //    X + Y
  1131  //    X & Y
  1132  //
  1133  type BinaryExpr struct {
  1134  	Src *ast.BinaryExpr
  1135  	Op  Op
  1136  	X   Expr
  1137  	Y   Expr
  1138  }
  1139  
  1140  func (x *BinaryExpr) Source() ast.Node {
  1141  	if x.Src == nil {
  1142  		return nil
  1143  	}
  1144  	return x.Src
  1145  }
  1146  
  1147  func (x *BinaryExpr) evaluate(c *OpContext) Value {
  1148  	env := c.Env(0)
  1149  	if x.Op == AndOp {
  1150  		// Anonymous Arc
  1151  		v := &Vertex{Conjuncts: []Conjunct{{env, x, CloseInfo{}}}}
  1152  		c.Unify(v, Finalized)
  1153  		return v
  1154  	}
  1155  
  1156  	if !c.concreteIsPossible(x.Op, x.X) || !c.concreteIsPossible(x.Op, x.Y) {
  1157  		return nil
  1158  	}
  1159  
  1160  	// TODO: allow comparing to a literal Bottom only. Find something more
  1161  	// principled perhaps. One should especially take care that two values
  1162  	// evaluating to Bottom don't evaluate to true. For now we check for
  1163  	// Bottom here and require that one of the values be a Bottom literal.
  1164  	if x.Op == EqualOp || x.Op == NotEqualOp {
  1165  		if isLiteralBottom(x.X) {
  1166  			return c.validate(env, x.Src, x.Y, x.Op)
  1167  		}
  1168  		if isLiteralBottom(x.Y) {
  1169  			return c.validate(env, x.Src, x.X, x.Op)
  1170  		}
  1171  	}
  1172  
  1173  	left, _ := c.Concrete(env, x.X, x.Op)
  1174  	right, _ := c.Concrete(env, x.Y, x.Op)
  1175  
  1176  	if err := CombineErrors(x.Src, left, right); err != nil {
  1177  		return err
  1178  	}
  1179  
  1180  	if err := c.Err(); err != nil {
  1181  		return err
  1182  	}
  1183  
  1184  	return BinOp(c, x.Op, left, right)
  1185  }
  1186  
  1187  func (c *OpContext) validate(env *Environment, src ast.Node, x Expr, op Op) (r Value) {
  1188  	s := c.PushState(env, src)
  1189  	if c.nonMonotonicLookupNest == 0 {
  1190  		c.nonMonotonicGeneration++
  1191  	}
  1192  
  1193  	var match bool
  1194  	// NOTE: using Unwrap is maybe note entirely accurate, as it may discard
  1195  	// a future error. However, if it does so, the error will at least be
  1196  	// reported elsewhere.
  1197  	switch b := c.value(x).(type) {
  1198  	case nil:
  1199  	case *Bottom:
  1200  		if b.Code == CycleError {
  1201  			c.PopState(s)
  1202  			c.AddBottom(b)
  1203  			return nil
  1204  		}
  1205  		match = op == EqualOp
  1206  		// We have a nonmonotonic use of a failure. Referenced fields should
  1207  		// not be added anymore.
  1208  		c.nonMonotonicRejectNest++
  1209  		c.evalState(x, Partial)
  1210  		c.nonMonotonicRejectNest--
  1211  
  1212  	default:
  1213  		// TODO(cycle): if EqualOp:
  1214  		// - ensure to pass special status to if clause or keep a track of "hot"
  1215  		//   paths.
  1216  		// - evaluate hypothetical struct
  1217  		// - walk over all fields and verify that fields are not contradicting
  1218  		//   previously marked fields.
  1219  		//
  1220  		switch {
  1221  		case b.Concreteness() > Concrete:
  1222  			// TODO: mimic comparison to bottom semantics. If it is a valid
  1223  			// value, check for concreteness that this level only. This
  1224  			// should ultimately be replaced with an exists and valid
  1225  			// builtin.
  1226  			match = op == EqualOp
  1227  		default:
  1228  			match = op != EqualOp
  1229  		}
  1230  		c.nonMonotonicLookupNest++
  1231  		c.evalState(x, Partial)
  1232  		c.nonMonotonicLookupNest--
  1233  	}
  1234  
  1235  	c.PopState(s)
  1236  	return &Bool{src, match}
  1237  }
  1238  
  1239  // A CallExpr represents a call to a builtin.
  1240  //
  1241  //    len(x)
  1242  //    strings.ToLower(x)
  1243  //
  1244  type CallExpr struct {
  1245  	Src  *ast.CallExpr
  1246  	Fun  Expr
  1247  	Args []Expr
  1248  }
  1249  
  1250  func (x *CallExpr) Source() ast.Node {
  1251  	if x.Src == nil {
  1252  		return nil
  1253  	}
  1254  	return x.Src
  1255  }
  1256  
  1257  func (x *CallExpr) evaluate(c *OpContext) Value {
  1258  	fun := c.value(x.Fun)
  1259  	var b *Builtin
  1260  	switch f := fun.(type) {
  1261  	case *Builtin:
  1262  		b = f
  1263  
  1264  	case *BuiltinValidator:
  1265  		// We allow a validator that takes no arguments accept the validated
  1266  		// value to be called with zero arguments.
  1267  		switch {
  1268  		case f.Src != nil:
  1269  			c.AddErrf("cannot call previously called validator %s", x.Fun)
  1270  
  1271  		case f.Builtin.IsValidator(len(x.Args)):
  1272  			v := *f
  1273  			v.Src = x
  1274  			return &v
  1275  
  1276  		default:
  1277  			b = f.Builtin
  1278  		}
  1279  
  1280  	default:
  1281  		c.AddErrf("cannot call non-function %s (type %s)", x.Fun, kind(fun))
  1282  		return nil
  1283  	}
  1284  	args := []Value{}
  1285  	for i, a := range x.Args {
  1286  		expr := c.value(a)
  1287  		switch v := expr.(type) {
  1288  		case nil:
  1289  			// There SHOULD be an error in the context. If not, we generate
  1290  			// one.
  1291  			c.Assertf(pos(x.Fun), c.HasErr(),
  1292  				"argument %d to function %s is incomplete", i, x.Fun)
  1293  
  1294  		case *Bottom:
  1295  			// TODO(errors): consider adding an argument index for this errors.
  1296  			// On the other hand, this error is really not related to the
  1297  			// argument itself, so maybe it is good as it is.
  1298  			c.AddBottom(v)
  1299  
  1300  		default:
  1301  			args = append(args, expr)
  1302  		}
  1303  	}
  1304  	if c.HasErr() {
  1305  		return nil
  1306  	}
  1307  	if b.IsValidator(len(args)) {
  1308  		return &BuiltinValidator{x, b, args}
  1309  	}
  1310  	result := b.call(c, pos(x), args)
  1311  	if result == nil {
  1312  		return nil
  1313  	}
  1314  	return c.evalState(result, Partial)
  1315  }
  1316  
  1317  // A Builtin is a value representing a native function call.
  1318  type Builtin struct {
  1319  	// TODO:  make these values for better type checking.
  1320  	Params []Param
  1321  	Result Kind
  1322  	Func   func(c *OpContext, args []Value) Expr
  1323  
  1324  	Package Feature
  1325  	Name    string
  1326  }
  1327  
  1328  type Param struct {
  1329  	Name  Feature // name of the argument; mostly for documentation
  1330  	Value Value   // Could become Value later, using disjunctions for defaults.
  1331  }
  1332  
  1333  // Kind returns the kind mask of this parameter.
  1334  func (p Param) Kind() Kind {
  1335  	return p.Value.Kind()
  1336  }
  1337  
  1338  // Default reports the default value for this Param or nil if there is none.
  1339  func (p Param) Default() Value {
  1340  	d, ok := p.Value.(*Disjunction)
  1341  	if !ok || d.NumDefaults != 1 {
  1342  		return nil
  1343  	}
  1344  	return d.Values[0]
  1345  }
  1346  
  1347  func (x *Builtin) WriteName(w io.Writer, c *OpContext) {
  1348  	_, _ = fmt.Fprintf(w, "%s.%s", x.Package.StringValue(c), x.Name)
  1349  }
  1350  
  1351  // Kind here represents the case where Builtin is used as a Validator.
  1352  func (x *Builtin) Kind() Kind {
  1353  	return FuncKind
  1354  }
  1355  
  1356  func (x *Builtin) BareValidator() *BuiltinValidator {
  1357  	if len(x.Params) != 1 ||
  1358  		(x.Result != BoolKind && x.Result != BottomKind) {
  1359  		return nil
  1360  	}
  1361  	return &BuiltinValidator{Builtin: x}
  1362  }
  1363  
  1364  // IsValidator reports whether b should be interpreted as a Validator for the
  1365  // given number of arguments.
  1366  func (b *Builtin) IsValidator(numArgs int) bool {
  1367  	return numArgs == len(b.Params)-1 &&
  1368  		b.Result&^BoolKind == 0 &&
  1369  		b.Params[numArgs].Default() == nil
  1370  }
  1371  
  1372  func bottom(v Value) *Bottom {
  1373  	if x, ok := v.(*Vertex); ok {
  1374  		v = x.Value()
  1375  	}
  1376  	b, _ := v.(*Bottom)
  1377  	return b
  1378  }
  1379  
  1380  func (x *Builtin) call(c *OpContext, p token.Pos, args []Value) Expr {
  1381  	fun := x // right now always x.
  1382  	if len(args) > len(x.Params) {
  1383  		c.addErrf(0, p,
  1384  			"too many arguments in call to %s (have %d, want %d)",
  1385  			fun, len(args), len(x.Params))
  1386  		return nil
  1387  	}
  1388  	for i := len(args); i < len(x.Params); i++ {
  1389  		v := x.Params[i].Default()
  1390  		if v == nil {
  1391  			c.addErrf(0, p,
  1392  				"not enough arguments in call to %s (have %d, want %d)",
  1393  				fun, len(args), len(x.Params))
  1394  			return nil
  1395  		}
  1396  		args = append(args, v)
  1397  	}
  1398  	for i, a := range args {
  1399  		if x.Params[i].Kind() == BottomKind {
  1400  			continue
  1401  		}
  1402  		if b := bottom(a); b != nil {
  1403  			return b
  1404  		}
  1405  		if k := kind(a); x.Params[i].Kind()&k == BottomKind {
  1406  			code := EvalError
  1407  			b, _ := args[i].(*Bottom)
  1408  			if b != nil {
  1409  				code = b.Code
  1410  			}
  1411  			c.addErrf(code, pos(a),
  1412  				"cannot use %s (type %s) as %s in argument %d to %s",
  1413  				a, k, x.Params[i].Kind(), i+1, fun)
  1414  			return nil
  1415  		}
  1416  		v := x.Params[i].Value
  1417  		if _, ok := v.(*BasicType); !ok {
  1418  			env := c.Env(0)
  1419  			x := &BinaryExpr{Op: AndOp, X: v, Y: a}
  1420  			n := &Vertex{Conjuncts: []Conjunct{{env, x, CloseInfo{}}}}
  1421  			c.Unify(n, Finalized)
  1422  			if _, ok := n.BaseValue.(*Bottom); ok {
  1423  				c.addErrf(0, pos(a),
  1424  					"cannot use %s as %s in argument %d to %s",
  1425  					a, v, i+1, fun)
  1426  				return nil
  1427  			}
  1428  			args[i] = n
  1429  		}
  1430  	}
  1431  	return x.Func(c, args)
  1432  }
  1433  
  1434  func (x *Builtin) Source() ast.Node { return nil }
  1435  
  1436  // A BuiltinValidator is a Value that results from evaluation a partial call
  1437  // to a builtin (using CallExpr).
  1438  //
  1439  //    strings.MinRunes(4)
  1440  //
  1441  type BuiltinValidator struct {
  1442  	Src     *CallExpr
  1443  	Builtin *Builtin
  1444  	Args    []Value // any but the first value
  1445  }
  1446  
  1447  func (x *BuiltinValidator) Source() ast.Node {
  1448  	if x.Src == nil {
  1449  		return x.Builtin.Source()
  1450  	}
  1451  	return x.Src.Source()
  1452  }
  1453  
  1454  func (x *BuiltinValidator) Pos() token.Pos {
  1455  	if src := x.Source(); src != nil {
  1456  		return src.Pos()
  1457  	}
  1458  	return token.NoPos
  1459  }
  1460  
  1461  func (x *BuiltinValidator) Kind() Kind {
  1462  	return x.Builtin.Params[0].Kind()
  1463  }
  1464  
  1465  func (x *BuiltinValidator) validate(c *OpContext, v Value) *Bottom {
  1466  	args := make([]Value, len(x.Args)+1)
  1467  	args[0] = v
  1468  	copy(args[1:], x.Args)
  1469  
  1470  	return validateWithBuiltin(c, x.Pos(), x.Builtin, args)
  1471  }
  1472  
  1473  func validateWithBuiltin(c *OpContext, src token.Pos, b *Builtin, args []Value) *Bottom {
  1474  	var severeness ErrorCode
  1475  	var err errors.Error
  1476  
  1477  	res := b.call(c, src, args)
  1478  	switch v := res.(type) {
  1479  	case nil:
  1480  		return nil
  1481  
  1482  	case *Bottom:
  1483  		if v == nil {
  1484  			return nil // caught elsewhere, but be defensive.
  1485  		}
  1486  		severeness = v.Code
  1487  		err = v.Err
  1488  
  1489  	case *Bool:
  1490  		if v.B {
  1491  			return nil
  1492  		}
  1493  
  1494  	default:
  1495  		return c.NewErrf("invalid validator %s.%s", b.Package.StringValue(c), b.Name)
  1496  	}
  1497  
  1498  	// failed:
  1499  	var buf bytes.Buffer
  1500  	b.WriteName(&buf, c)
  1501  	if len(args) > 1 {
  1502  		buf.WriteString("(")
  1503  		for i, a := range args[1:] {
  1504  			if i > 0 {
  1505  				_, _ = buf.WriteString(", ")
  1506  			}
  1507  			buf.WriteString(c.Str(a))
  1508  		}
  1509  		buf.WriteString(")")
  1510  	}
  1511  
  1512  	vErr := c.NewPosf(src, "invalid value %s (does not satisfy %s)", args[0], buf.String())
  1513  
  1514  	for _, v := range args {
  1515  		vErr.AddPosition(v)
  1516  	}
  1517  
  1518  	return &Bottom{Code: severeness, Err: errors.Wrap(vErr, err)}
  1519  }
  1520  
  1521  // A Disjunction represents a disjunction, where each disjunct may or may not
  1522  // be marked as a default.
  1523  type DisjunctionExpr struct {
  1524  	Src    *ast.BinaryExpr
  1525  	Values []Disjunct
  1526  
  1527  	HasDefaults bool
  1528  }
  1529  
  1530  // A Disjunct is used in Disjunction.
  1531  type Disjunct struct {
  1532  	Val     Expr
  1533  	Default bool
  1534  }
  1535  
  1536  func (x *DisjunctionExpr) Source() ast.Node {
  1537  	if x.Src == nil {
  1538  		return nil
  1539  	}
  1540  	return x.Src
  1541  }
  1542  
  1543  func (x *DisjunctionExpr) evaluate(c *OpContext) Value {
  1544  	e := c.Env(0)
  1545  	v := &Vertex{Conjuncts: []Conjunct{{e, x, CloseInfo{}}}}
  1546  	c.Unify(v, Finalized) // TODO: also partial okay?
  1547  	// TODO: if the disjunction result originated from a literal value, we may
  1548  	// consider the result closed to create more permanent errors.
  1549  	return v
  1550  }
  1551  
  1552  // A Conjunction is a conjunction of values that cannot be represented as a
  1553  // single value. It is the result of unification.
  1554  type Conjunction struct {
  1555  	Src    ast.Expr
  1556  	Values []Value
  1557  }
  1558  
  1559  func (x *Conjunction) Source() ast.Node { return x.Src }
  1560  func (x *Conjunction) Kind() Kind {
  1561  	k := TopKind
  1562  	for _, v := range x.Values {
  1563  		k &= v.Kind()
  1564  	}
  1565  	return k
  1566  }
  1567  
  1568  // A disjunction is a disjunction of values. It is the result of expanding
  1569  // a DisjunctionExpr if the expression cannot be represented as a single value.
  1570  type Disjunction struct {
  1571  	Src ast.Expr
  1572  
  1573  	// Values are the non-error disjuncts of this expression. The first
  1574  	// NumDefault values are default values.
  1575  	Values []*Vertex
  1576  
  1577  	Errors *Bottom // []bottom
  1578  
  1579  	// NumDefaults indicates the number of default values.
  1580  	NumDefaults int
  1581  	HasDefaults bool
  1582  }
  1583  
  1584  func (x *Disjunction) Source() ast.Node { return x.Src }
  1585  func (x *Disjunction) Kind() Kind {
  1586  	k := BottomKind
  1587  	for _, v := range x.Values {
  1588  		k |= v.Kind()
  1589  	}
  1590  	return k
  1591  }
  1592  
  1593  // A ForClause represents a for clause of a comprehension. It can be used
  1594  // as a struct or list element.
  1595  //
  1596  //    for k, v in src {}
  1597  //
  1598  type ForClause struct {
  1599  	Syntax *ast.ForClause
  1600  	Key    Feature
  1601  	Value  Feature
  1602  	Src    Expr
  1603  	Dst    Yielder
  1604  }
  1605  
  1606  func (x *ForClause) Source() ast.Node {
  1607  	if x.Syntax == nil {
  1608  		return nil
  1609  	}
  1610  	return x.Syntax
  1611  }
  1612  
  1613  func (x *ForClause) yield(c *OpContext, f YieldFunc) {
  1614  	n := c.node(x, x.Src, true, AllArcs)
  1615  	for _, a := range n.Arcs {
  1616  		if !a.Label.IsRegular() {
  1617  			continue
  1618  		}
  1619  
  1620  		c.Unify(a, Partial)
  1621  
  1622  		n := &Vertex{status: Finalized}
  1623  
  1624  		// TODO: only needed if value label != _
  1625  
  1626  		b := &Vertex{
  1627  			Label:     x.Value,
  1628  			BaseValue: a,
  1629  		}
  1630  		n.Arcs = append(n.Arcs, b)
  1631  
  1632  		if x.Key != 0 {
  1633  			v := &Vertex{Label: x.Key}
  1634  			key := a.Label.ToValue(c)
  1635  			v.AddConjunct(MakeRootConjunct(c.Env(0), key))
  1636  			v.SetValue(c, Finalized, key)
  1637  			n.Arcs = append(n.Arcs, v)
  1638  		}
  1639  
  1640  		sub := c.spawn(n)
  1641  		saved := c.PushState(sub, x.Dst.Source())
  1642  		x.Dst.yield(c, f)
  1643  		if b := c.PopState(saved); b != nil {
  1644  			c.AddBottom(b)
  1645  			break
  1646  		}
  1647  		if c.HasErr() {
  1648  			break
  1649  		}
  1650  	}
  1651  }
  1652  
  1653  // An IfClause represents an if clause of a comprehension. It can be used
  1654  // as a struct or list element.
  1655  //
  1656  //    if cond {}
  1657  //
  1658  type IfClause struct {
  1659  	Src       *ast.IfClause
  1660  	Condition Expr
  1661  	Dst       Yielder
  1662  }
  1663  
  1664  func (x *IfClause) Source() ast.Node {
  1665  	if x.Src == nil {
  1666  		return nil
  1667  	}
  1668  	return x.Src
  1669  }
  1670  
  1671  func (x *IfClause) yield(ctx *OpContext, f YieldFunc) {
  1672  	if ctx.BoolValue(ctx.value(x.Condition)) {
  1673  		x.Dst.yield(ctx, f)
  1674  	}
  1675  }
  1676  
  1677  // An LetClause represents a let clause in a comprehension.
  1678  //
  1679  //    for k, v in src {}
  1680  //
  1681  type LetClause struct {
  1682  	Src   *ast.LetClause
  1683  	Label Feature
  1684  	Expr  Expr
  1685  	Dst   Yielder
  1686  }
  1687  
  1688  func (x *LetClause) Source() ast.Node {
  1689  	if x.Src == nil {
  1690  		return nil
  1691  	}
  1692  	return x.Src
  1693  }
  1694  
  1695  func (x *LetClause) yield(c *OpContext, f YieldFunc) {
  1696  	n := &Vertex{Arcs: []*Vertex{
  1697  		{Label: x.Label, Conjuncts: []Conjunct{{c.Env(0), x.Expr, CloseInfo{}}}},
  1698  	}}
  1699  
  1700  	sub := c.spawn(n)
  1701  	saved := c.PushState(sub, x.Dst.Source())
  1702  	x.Dst.yield(c, f)
  1703  	if b := c.PopState(saved); b != nil {
  1704  		c.AddBottom(b)
  1705  	}
  1706  }
  1707  
  1708  // A ValueClause represents the value part of a comprehension.
  1709  type ValueClause struct {
  1710  	*StructLit
  1711  }
  1712  
  1713  func (x *ValueClause) Source() ast.Node {
  1714  	if x.StructLit == nil {
  1715  		return nil
  1716  	}
  1717  	if x.Src == nil {
  1718  		return nil
  1719  	}
  1720  	return x.Src
  1721  }
  1722  
  1723  func (x *ValueClause) yield(op *OpContext, f YieldFunc) {
  1724  	f(op.Env(0), x.StructLit)
  1725  }