c4dd673bf4
This change required OpenEdges to be passed around as pointers, which in turn required me to audit how value copying is being done everywhere and simplify it in a few places. I think I covered all the bases. The new internals of Graph allow the graph's actual structure to be reflected within the graph itself. For example, if the OpenEdges of two ValueIns are equivalent then the same OpenEdge pointer is shared for the two internally. This applies recursively, so if two OpenEdge tuples share an inner OpenEdge, they will share the same pointer. This change is a preliminary requirement for creating a graph mapping operation. Without OpenEdge deduplication the map operation would end up operating on the same OpenEdge multiple times, which would be incorrect.
81 lines
1.6 KiB
Go
81 lines
1.6 KiB
Go
// Package gg implements graph serialization to/from the gg text format.
|
|
package gg
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/mediocregopher/ginger/graph"
|
|
)
|
|
|
|
// ZeroValue is a Value with no fields set.
|
|
var ZeroValue Value
|
|
|
|
// Value represents a value which can be serialized by the gg text format.
|
|
type Value struct {
|
|
|
|
// Only one of these fields may be set
|
|
Name *string
|
|
Number *int64
|
|
Graph *graph.Graph[Value]
|
|
|
|
// TODO coming soon!
|
|
// String *string
|
|
|
|
// Optional fields indicating the token which was used to construct this
|
|
// Value, if any.
|
|
LexerToken *LexerToken
|
|
}
|
|
|
|
// IsZero returns true if the Value is the zero value (none of the sub-value
|
|
// fields are set). LexerToken is ignored for this check.
|
|
func (v Value) IsZero() bool {
|
|
return v.Equal(ZeroValue)
|
|
}
|
|
|
|
// Equal returns true if the passed in Value is equivalent, ignoring the
|
|
// LexerToken on either Value.
|
|
//
|
|
// Will panic if the passed in v2 is not a Value from this package.
|
|
func (v Value) Equal(v2g graph.Value) bool {
|
|
|
|
v2 := v2g.(Value)
|
|
|
|
v.LexerToken, v2.LexerToken = nil, nil
|
|
|
|
switch {
|
|
|
|
case v == ZeroValue && v2 == ZeroValue:
|
|
return true
|
|
|
|
case v.Name != nil && v2.Name != nil && *v.Name == *v2.Name:
|
|
return true
|
|
|
|
case v.Number != nil && v2.Number != nil && *v.Number == *v2.Number:
|
|
return true
|
|
|
|
case v.Graph != nil && v2.Graph != nil && v.Graph.Equal(v2.Graph):
|
|
return true
|
|
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func (v Value) String() string {
|
|
|
|
switch {
|
|
|
|
case v.Name != nil:
|
|
return *v.Name
|
|
|
|
case v.Number != nil:
|
|
return fmt.Sprint(*v.Number)
|
|
|
|
case v.Graph != nil:
|
|
return v.Graph.String()
|
|
|
|
default:
|
|
return "<zero>"
|
|
}
|
|
}
|