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