Package eval contains the high level CUE evaluation strategy.

CUE allows for a significant amount of freedom in order of evaluation due to the commutativity of the unification operation. This package implements one of the possible strategies.



This section is empty.


var Debug = false


func Equal

func Equal(ctx *adt.OpContext, v, w adt.Value) bool

func Evaluate

func Evaluate(r adt.Runtime, v *adt.Vertex)

func NewContext

func NewContext(r adt.Runtime, v *adt.Vertex) *adt.OpContext


type CloseDef

type CloseDef struct {
	Src adt.Node

	// And is used to track the IDs of a set of conjuncts. If IsDef or IsClosed
	// is true, a field is only allowed if at least one of the corresponding
	// fieldsets associated with this node or its embeddings allows it.
	// And nodes are linked in a ring, meaning that the last node points back
	// to the first node. This allows a traversal of all and nodes to commence
	// at any point in the ring.
	And adt.ID

	// NextEmbed indicates the first ID for a linked list of embedded
	// expressions. The node corresponding to the actual embedding is at
	// position NextEmbed+1. The linked-list nodes all have a value of -1 for
	// And. NextEmbed is 0 for the last element in the list.
	NextEmbed adt.ID

	// IsDef indicates this node is associated with a definition and that all
	// expressions are recursively closed. This value is "sticky" when a child
	// node copies the closedness data from a parent node.
	IsDef bool

	// IsClosed indicates this node is associated with the result of close().
	// A child vertex should not "inherit" this value.
	IsClosed bool

CloseDef defines how individual fieldSets (corresponding to conjuncts) combine to determine whether a field is contained in a closed set.

A CloseDef combines multiple conjuncts and embeddings. All CloseDefs are stored in slice. References to other CloseDefs are indices within this slice. Together they define the top of the tree of the expression tree of how conjuncts combine together (a canopy).

type Entry

type Entry = fieldSet

type Evaluator

type Evaluator struct {
	// contains filtered or unexported fields

func New

func New(r adt.Runtime) *Evaluator

func (*Evaluator) Eval

func (e *Evaluator) Eval(v *adt.Vertex) errors.Error

func (*Evaluator) Evaluate

func (e *Evaluator) Evaluate(c *adt.OpContext, v *adt.Vertex) adt.Value

Evaluate is used to evaluate a sub expression while evaluating a Vertex with Unify. It may or may not return the original Vertex. It may also terminate evaluation early if it has enough evidence that a certain value can be the only value in a valid configuration. This means that an error may go undetected at this point, as long as it is caught later.

func (*Evaluator) NewContext

func (e *Evaluator) NewContext(v *adt.Vertex) *adt.OpContext

func (*Evaluator) Stats

func (e *Evaluator) Stats() *Stats

func (*Evaluator) Unify

func (e *Evaluator) Unify(c *adt.OpContext, v *adt.Vertex, state adt.VertexStatus)

Unify implements adt.Unifier.

May not evaluate the entire value, but just enough to be able to compute.

Phase one: record everything concrete Phase two: record incomplete Phase three: record cycle.

func (*Evaluator) UnifyAccept

func (e *Evaluator) UnifyAccept(c *adt.OpContext, v *adt.Vertex, state adt.VertexStatus, accept adt.Acceptor)

UnifyAccept is like Unify, but takes an extra argument to override the accepted set of fields.

Instead of deriving the allowed set of fields, it verifies this set by consulting the given Acceptor. This can be useful when splitting an existing values into individual conjuncts and then unifying some of its components back into a new value. Under normal circumstances, this may not always succeed as the missing context may result in stricter closedness rules.

type Stats

type Stats struct {
	DisjunctCount int
	UnifyCount    int

func (*Stats) String

func (s *Stats) String() string