If a name does not resolve to anything then it resolves to itself
This commit is contained in:
parent
a7a5018f38
commit
22e14bbb3f
@ -1,6 +1,7 @@
|
||||
package vm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"code.betamike.com/mediocregopher/ginger/gg"
|
||||
@ -79,8 +80,6 @@ func FunctionFromGraph(g *gg.Graph, scope Scope) (Function, error) {
|
||||
return edgeFn(Identity(val)), nil
|
||||
}
|
||||
|
||||
name := *val.Name
|
||||
|
||||
if val.Equal(valNameIn) {
|
||||
return edgeFn(FunctionFunc(func(inArg Value) Value {
|
||||
return inArg
|
||||
@ -89,15 +88,17 @@ func FunctionFromGraph(g *gg.Graph, scope Scope) (Function, error) {
|
||||
|
||||
edgesIn := g.ValueIns(val.Value)
|
||||
|
||||
name := *val.Name
|
||||
|
||||
if l := len(edgesIn); l == 0 {
|
||||
|
||||
val, err := scope.Resolve(name)
|
||||
|
||||
if err != nil {
|
||||
resolvedVal, err := scope.Resolve(name)
|
||||
if errors.Is(err, ErrNameNotDefined) {
|
||||
return edgeFn(Identity(val)), nil
|
||||
} else if err != nil {
|
||||
return nil, fmt.Errorf("resolving name %q from the outer scope: %w", name, err)
|
||||
}
|
||||
|
||||
return edgeFn(Identity(val)), nil
|
||||
return edgeFn(Identity(resolvedVal)), nil
|
||||
|
||||
} else if l != 1 {
|
||||
return nil, fmt.Errorf("resolved name %q to %d input edges, rather than one", name, l)
|
||||
@ -123,7 +124,6 @@ func FunctionFromGraph(g *gg.Graph, scope Scope) (Function, error) {
|
||||
return valToEdgeFn(Value{Value: ggVal})
|
||||
},
|
||||
func(ggEdgeVal gg.OptionalValue, inEdgeFns []edgeFn) (edgeFn, error) {
|
||||
|
||||
if ggEdgeVal.Equal(valNameIf.Value) {
|
||||
|
||||
if len(inEdgeFns) != 3 {
|
||||
|
11
vm/scope.go
11
vm/scope.go
@ -1,13 +1,18 @@
|
||||
package vm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// ErrNameNotDefined is returned from Scope.Resolve when a name could not be
|
||||
// resolved within a Scope.
|
||||
var ErrNameNotDefined = errors.New("not defined")
|
||||
|
||||
// Scope encapsulates a set of name->Value mappings.
|
||||
type Scope interface {
|
||||
|
||||
// Resolve accepts a name and returns an Value.
|
||||
// Resolve accepts a name and returns an Value, or returns
|
||||
// ErrNameNotDefined.
|
||||
Resolve(string) (Value, error)
|
||||
}
|
||||
|
||||
@ -23,7 +28,7 @@ func (m ScopeMap) Resolve(name string) (Value, error) {
|
||||
v, ok := m[name]
|
||||
|
||||
if !ok {
|
||||
return Value{}, fmt.Errorf("%q not defined", name)
|
||||
return Value{}, ErrNameNotDefined
|
||||
}
|
||||
|
||||
return v, nil
|
||||
|
@ -32,10 +32,16 @@ func TestVM(t *testing.T) {
|
||||
in: Value{Value: gg.Number(1)},
|
||||
expErr: "name !foo cannot start with a '!'",
|
||||
},
|
||||
{
|
||||
src: `{foo = bar; !out = foo;}`,
|
||||
in: Value{},
|
||||
exp: Value{Value: gg.Name("bar")},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
t.Log(test.src)
|
||||
val, err := EvaluateSource(
|
||||
bytes.NewBufferString(test.src), test.in, GlobalScope,
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user