Skip to content

Commit

Permalink
internal/core/adt: unexport VertexStatus
Browse files Browse the repository at this point in the history
We are moving away from a state model,
so make it an implementation detail.

Added IsUnprocessed to composite.go
to remove the few remaining API uses.

Signed-off-by: Marcel van Lohuizen <mpvl@gmail.com>
Change-Id: Icaf9534eceaeaab577dad3acde562ef8b29dc0a0
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/551410
Reviewed-by: Aram Hăvărneanu <aram@cue.works>
Reviewed-by: Roger Peppe <rogpeppe@gmail.com>
Unity-Result: CUEcueckoo <cueckoo@cuelang.org>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
  • Loading branch information
mpvl committed Mar 24, 2023
1 parent 97904e3 commit 185eed7
Show file tree
Hide file tree
Showing 10 changed files with 188 additions and 182 deletions.
2 changes: 1 addition & 1 deletion cue/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ func linkParent(p *parent, node, arc *adt.Vertex) *parent {
func remakeValue(base Value, env *adt.Environment, v adt.Expr) Value {
// TODO: right now this is necessary because disjunctions do not have
// populated conjuncts.
if v, ok := v.(*adt.Vertex); ok && v.Status() >= adt.Partial {
if v, ok := v.(*adt.Vertex); ok && !v.IsUnprocessed() {
return Value{base.idx, v, nil}
}
n := &adt.Vertex{Label: base.v.Label}
Expand Down
6 changes: 3 additions & 3 deletions internal/core/adt/adt.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func Resolve(ctx *OpContext, c Conjunct) *Vertex {
v = x

case Resolver:
r, err := ctx.resolveState(c, x, Finalized)
r, err := ctx.resolveState(c, x, finalized)
if err != nil {
v = err
break
Expand Down Expand Up @@ -108,14 +108,14 @@ type Evaluator interface {

// evaluate evaluates the underlying expression. If the expression
// is incomplete, it may record the error in ctx and return nil.
evaluate(ctx *OpContext, state VertexStatus) Value
evaluate(ctx *OpContext, state vertexStatus) Value
}

// A Resolver represents a reference somewhere else within a tree that resolves
// a value.
type Resolver interface {
Node
resolve(ctx *OpContext, state VertexStatus) *Vertex
resolve(ctx *OpContext, state vertexStatus) *Vertex
}

type YieldFunc func(env *Environment)
Expand Down
78 changes: 42 additions & 36 deletions internal/core/adt/composite.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func (e *Environment) evalCached(c *OpContext, x Expr) Value {
// Save and restore errors to ensure that only relevant errors are
// associated with the cash.
err := c.errs
v = c.evalState(x, Partial) // TODO: should this be Finalized?
v = c.evalState(x, partial) // TODO: should this be finalized?
c.e, c.src = env, src
c.errs = err
if b, ok := v.(*Bottom); !ok || !b.IsIncomplete() {
Expand Down Expand Up @@ -164,7 +164,7 @@ type Vertex struct {
// TODO: move the following status fields to nodeContext.

// status indicates the evaluation progress of this vertex.
status VertexStatus
status vertexStatus

// hasAllConjuncts indicates that the set of conjuncts is complete.
// This is the case if the conjuncts of all its ancestors have been
Expand Down Expand Up @@ -353,71 +353,77 @@ func (s *StructInfo) useForAccept() bool {
return true
}

// VertexStatus indicates the evaluation progress of a Vertex.
type VertexStatus int8
// vertexStatus indicates the evaluation progress of a Vertex.
type vertexStatus int8

const (
// Unprocessed indicates a Vertex has not been processed before.
// unprocessed indicates a Vertex has not been processed before.
// Value must be nil.
Unprocessed VertexStatus = iota
unprocessed vertexStatus = iota

// Evaluating means that the current Vertex is being evaluated. If this is
// evaluating means that the current Vertex is being evaluated. If this is
// encountered it indicates a reference cycle. Value must be nil.
Evaluating
evaluating

// Partial indicates that the result was only partially evaluated. It will
// partial indicates that the result was only partially evaluated. It will
// need to be fully evaluated to get a complete results.
//
// TODO: this currently requires a renewed computation. Cache the
// nodeContext to allow reusing the computations done so far.
Partial
partial

// Conjuncts is the state reached when all conjuncts have been evaluated,
// conjuncts is the state reached when all conjuncts have been evaluated,
// but without recursively processing arcs.
Conjuncts
conjuncts

// EvaluatingArcs indicates that the arcs of the Vertex are currently being
// evaluatingArcs indicates that the arcs of the Vertex are currently being
// evaluated. If this is encountered it indicates a structural cycle.
// Value does not have to be nil
EvaluatingArcs
evaluatingArcs

// Finalized means that this node is fully evaluated and that the results
// finalized means that this node is fully evaluated and that the results
// are save to use without further consideration.
Finalized
finalized
)

func (s VertexStatus) String() string {
func (s vertexStatus) String() string {
switch s {
case Unprocessed:
case unprocessed:
return "unprocessed"
case Evaluating:
case evaluating:
return "evaluating"
case Partial:
case partial:
return "partial"
case Conjuncts:
case conjuncts:
return "conjuncts"
case EvaluatingArcs:
case evaluatingArcs:
return "evaluatingArcs"
case Finalized:
case finalized:
return "finalized"
default:
return "unknown"
}
}

func (v *Vertex) Status() VertexStatus {
func (v *Vertex) Status() vertexStatus {
return v.status
}

// ForceDone prevents v from being evaluated.
func (v *Vertex) ForceDone() {
v.updateStatus(Finalized)
v.updateStatus(finalized)
}

func (v *Vertex) updateStatus(s VertexStatus) {
// IsUnprocessed reports whether v is unprocessed.
func (v *Vertex) IsUnprocessed() bool {
return v.status == unprocessed
}

func (v *Vertex) updateStatus(s vertexStatus) {
Assertf(v.status <= s+1, "attempt to regress status from %d to %d", v.Status(), s)

if s == Finalized && v.BaseValue == nil {
if s == finalized && v.BaseValue == nil {
// TODO: for debugging.
// panic("not finalized")
}
v.status = s
Expand Down Expand Up @@ -490,7 +496,7 @@ func (v *Vertex) ToDataSingle() *Vertex {
w := *v
w.isData = true
w.state = nil
w.status = Finalized
w.status = finalized
return &w
}

Expand All @@ -508,7 +514,7 @@ func (v *Vertex) ToDataAll(ctx *OpContext) *Vertex {
}
w := *v
w.state = nil
w.status = Finalized
w.status = finalized

w.BaseValue = toDataAll(ctx, w.BaseValue)
w.Arcs = arcs
Expand Down Expand Up @@ -585,13 +591,13 @@ func (v *Vertex) Finalize(c *OpContext) {
// case the caller did not handle existing errors in the context.
err := c.errs
c.errs = nil
c.unify(v, Finalized)
c.unify(v, finalized)
c.errs = err
}

// CompleteArcs ensures the set of arcs has been computed.
func (v *Vertex) CompleteArcs(c *OpContext) {
c.unify(v, Conjuncts)
c.unify(v, conjuncts)
}

func (v *Vertex) AddErr(ctx *OpContext, b *Bottom) {
Expand All @@ -600,10 +606,10 @@ func (v *Vertex) AddErr(ctx *OpContext, b *Bottom) {

// SetValue sets the value of a node.
func (v *Vertex) SetValue(ctx *OpContext, value BaseValue) *Bottom {
return v.setValue(ctx, Finalized, value)
return v.setValue(ctx, finalized, value)
}

func (v *Vertex) setValue(ctx *OpContext, state VertexStatus, value BaseValue) *Bottom {
func (v *Vertex) setValue(ctx *OpContext, state vertexStatus, value BaseValue) *Bottom {
v.BaseValue = value
v.updateStatus(state)
return nil
Expand All @@ -616,7 +622,7 @@ func ToVertex(v Value) *Vertex {
return x
default:
n := &Vertex{
status: Finalized,
status: finalized,
BaseValue: x,
}
n.AddConjunct(MakeRootConjunct(nil, v))
Expand Down Expand Up @@ -674,7 +680,7 @@ func (v *Vertex) Kind() Kind {
// not known at this time what the type is.
switch {
// TODO: using this line would be more stable.
// case v.status != Finalized && v.state != nil:
// case v.status != finalized && v.state != nil:
case v.state != nil:
return v.state.kind
case v.BaseValue == nil:
Expand Down Expand Up @@ -906,7 +912,7 @@ func (v *Vertex) addConjunctUnchecked(c Conjunct) {
// it, whilst doing the same for any vertices on the notify list, recursively.
func (n *nodeContext) addConjunctDynamic(c Conjunct) {
n.node.Conjuncts = append(n.node.Conjuncts, c)
n.addExprConjunct(c, Partial)
n.addExprConjunct(c, partial)
n.notifyConjunct(c)

}
Expand Down
6 changes: 3 additions & 3 deletions internal/core/adt/comprehension.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ type compState struct {
comp *Comprehension
i int
f YieldFunc
state VertexStatus
state vertexStatus
}

// yield evaluates a Comprehension within the given Environment and and calls
Expand All @@ -277,7 +277,7 @@ func (c *OpContext) yield(
node *Vertex, // errors are associated with this node
env *Environment, // env for field for which this yield is called
comp *Comprehension,
state VertexStatus,
state vertexStatus,
f YieldFunc, // called for every result
) *Bottom {
s := &compState{
Expand Down Expand Up @@ -323,7 +323,7 @@ func (s *compState) yield(env *Environment) (ok bool) {
// injectComprehension evaluates and inserts embeddings. It first evaluates all
// embeddings before inserting the results to ensure that the order of
// evaluation does not matter.
func (n *nodeContext) injectComprehensions(allP *[]envYield, allowCycle bool, state VertexStatus) (progress bool) {
func (n *nodeContext) injectComprehensions(allP *[]envYield, allowCycle bool, state vertexStatus) (progress bool) {
ctx := n.ctx

all := *allP
Expand Down
32 changes: 16 additions & 16 deletions internal/core/adt/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ func (c *OpContext) Env(upCount int32) *Environment {

func (c *OpContext) relNode(upCount int32) *Vertex {
e := c.e.up(upCount)
c.unify(e.Vertex, Partial)
c.unify(e.Vertex, partial)
return e.Vertex
}

Expand Down Expand Up @@ -467,10 +467,10 @@ func (c *OpContext) PopArc(saved *Vertex) {
// Should only be used to insert Conjuncts. TODO: perhaps only return Conjuncts
// and error.
func (c *OpContext) Resolve(x Conjunct, r Resolver) (*Vertex, *Bottom) {
return c.resolveState(x, r, Finalized)
return c.resolveState(x, r, finalized)
}

func (c *OpContext) resolveState(x Conjunct, r Resolver, state VertexStatus) (*Vertex, *Bottom) {
func (c *OpContext) resolveState(x Conjunct, r Resolver, state vertexStatus) (*Vertex, *Bottom) {
s := c.PushConjunct(x)

arc := r.resolve(c, state)
Expand All @@ -493,7 +493,7 @@ func (c *OpContext) resolveState(x Conjunct, r Resolver, state VertexStatus) (*V
func (c *OpContext) Lookup(env *Environment, r Resolver) (*Vertex, *Bottom) {
s := c.PushState(env, r.Source())

arc := r.resolve(c, Partial)
arc := r.resolve(c, partial)

err := c.PopState(s)

Expand Down Expand Up @@ -586,7 +586,7 @@ func (c *OpContext) getDefault(v Value) (result Value, ok bool) {
func (c *OpContext) Evaluate(env *Environment, x Expr) (result Value, complete bool) {
s := c.PushState(env, x.Source())

val := c.evalState(x, Partial)
val := c.evalState(x, partial)

complete = true

Expand All @@ -612,7 +612,7 @@ func (c *OpContext) Evaluate(env *Environment, x Expr) (result Value, complete b
return val, true
}

func (c *OpContext) evaluateRec(v Conjunct, state VertexStatus) Value {
func (c *OpContext) evaluateRec(v Conjunct, state vertexStatus) Value {
x := v.Expr()
s := c.PushConjunct(v)

Expand All @@ -633,15 +633,15 @@ func (c *OpContext) evaluateRec(v Conjunct, state VertexStatus) Value {
// value evaluates expression v within the current environment. The result may
// be nil if the result is incomplete. value leaves errors untouched to that
// they can be collected by the caller.
func (c *OpContext) value(x Expr, state VertexStatus) (result Value) {
func (c *OpContext) value(x Expr, state vertexStatus) (result Value) {
v := c.evalState(x, state)

v, _ = c.getDefault(v)
v = Unwrap(v)
return v
}

func (c *OpContext) evalState(v Expr, state VertexStatus) (result Value) {
func (c *OpContext) evalState(v Expr, state vertexStatus) (result Value) {
savedSrc := c.src
c.src = v.Source()
err := c.errs
Expand All @@ -655,7 +655,7 @@ func (c *OpContext) evalState(v Expr, state VertexStatus) (result Value) {
switch b.Code {
case IncompleteError:
case CycleError:
if state == Partial {
if state == partial {
break
}
fallthrough
Expand Down Expand Up @@ -728,7 +728,7 @@ func (c *OpContext) wrapCycleError(src ast.Node, b *Bottom) *Bottom {
// unifyNode returns a possibly partially evaluated node value.
//
// TODO: maybe return *Vertex, *Bottom
func (c *OpContext) unifyNode(v Expr, state VertexStatus) (result Value) {
func (c *OpContext) unifyNode(v Expr, state vertexStatus) (result Value) {
savedSrc := c.src
c.src = v.Source()
err := c.errs
Expand Down Expand Up @@ -790,7 +790,7 @@ func (c *OpContext) unifyNode(v Expr, state VertexStatus) (result Value) {
}
}

func (c *OpContext) lookup(x *Vertex, pos token.Pos, l Feature, state VertexStatus) *Vertex {
func (c *OpContext) lookup(x *Vertex, pos token.Pos, l Feature, state vertexStatus) *Vertex {
if l == InvalidLabel || x == nil {
// TODO: is it possible to have an invalid label here? Maybe through the
// API?
Expand Down Expand Up @@ -861,7 +861,7 @@ func (c *OpContext) lookup(x *Vertex, pos token.Pos, l Feature, state VertexStat
if state > a.status {
c.unify(a, state)
} else if a.state != nil {
c.unify(a, Partial)
c.unify(a, partial)
}

if a.IsConstraint() {
Expand All @@ -872,7 +872,7 @@ func (c *OpContext) lookup(x *Vertex, pos token.Pos, l Feature, state VertexStat
label := l.SelectorString(c.Runtime)
c.AddBottom(&Bottom{
Code: code,
Permanent: x.status >= Conjuncts,
Permanent: x.status >= conjuncts,
Err: c.NewPosf(pos,
"cannot reference optional field: %s", label),
})
Expand All @@ -889,11 +889,11 @@ func (c *OpContext) lookup(x *Vertex, pos token.Pos, l Feature, state VertexStat
// As long as we have incomplete information, we cannot mark the
// inability to look up a field as "final", as it may resolve down the
// line.
permanent := x.status > Conjuncts
permanent := x.status > conjuncts
if m, _ := x.BaseValue.(*ListMarker); m != nil && !m.IsOpen {
permanent = true
}
if (state > Partial || permanent) && !x.Accept(c, l) {
if (state > partial || permanent) && !x.Accept(c, l) {
code = 0
} else if hasCycle {
code = CycleError
Expand Down Expand Up @@ -965,7 +965,7 @@ func pos(x Node) token.Pos {
return x.Source().Pos()
}

func (c *OpContext) node(orig Node, x Expr, scalar bool, state VertexStatus) *Vertex {
func (c *OpContext) node(orig Node, x Expr, scalar bool, state vertexStatus) *Vertex {
// TODO: always get the vertex. This allows a whole bunch of trickery
// down the line.
v := c.unifyNode(x, state)
Expand Down
Loading

0 comments on commit 185eed7

Please sign in to comment.