lang: ast: Clear env in ExprVar.Graph()

Fix the bug in ExprVar.Graph() described in the previous commit.
This commit is contained in:
Samuel Gélineau
2023-12-01 23:39:43 -05:00
parent 72235b0fd4
commit 1ff2c9bbd9

View File

@@ -8460,9 +8460,29 @@ func (obj *ExprVar) Unify() ([]interfaces.Invariant, error) {
// to avoid duplicating production of the incoming input value from the bound // to avoid duplicating production of the incoming input value from the bound
// expression. // expression.
func (obj *ExprVar) Graph(env map[string]interfaces.Func) (*pgraph.Graph, interfaces.Func, error) { func (obj *ExprVar) Graph(env map[string]interfaces.Func) (*pgraph.Graph, interfaces.Func, error) {
// Delegate to the target. // Delegate to the targetExpr.
target := obj.scope.Variables[obj.Name] targetExpr := obj.scope.Variables[obj.Name]
graph, varFunc, err := target.Graph(env) if _, isParam := targetExpr.(*ExprParam); isParam {
// The variable points to a function parameter. We should be able to find
// this parameter in the environment.
targetFunc, exists := env[obj.Name]
if !exists {
return nil, nil, fmt.Errorf("param `%s` is not in the environment", obj.Name)
}
graph, err := pgraph.NewGraph("ExprParam")
if err != nil {
return nil, nil, err
}
graph.AddVertex(targetFunc)
return graph, targetFunc, nil
}
// The variable points to a top-level expression. The parameters which are
// visible at this use site must not be visible at the definition site, so
// we pass an empty environment.
emptyEnv := map[string]interfaces.Func{}
graph, varFunc, err := targetExpr.Graph(emptyEnv)
return graph, varFunc, err return graph, varFunc, err
} }
@@ -8620,21 +8640,7 @@ func (obj *ExprParam) Unify() ([]interfaces.Invariant, error) {
// that fulfill the Stmt interface do not produces vertices, where as their // that fulfill the Stmt interface do not produces vertices, where as their
// children might. // children might.
func (obj *ExprParam) Graph(env map[string]interfaces.Func) (*pgraph.Graph, interfaces.Func, error) { func (obj *ExprParam) Graph(env map[string]interfaces.Func) (*pgraph.Graph, interfaces.Func, error) {
// Since ExprParam represents a function parameter, we want to receive values panic("ExprParam.Graph(): should not happen, ExprVar.Graph() should handle the case where the ExprVar points to an ExprParam")
// from the arguments passed to the function. The caller of ExprParam.Graph()
// should already know what those arguments are, so we can simply look up the
// argument by name in the environment.
paramFunc, exists := env[obj.Name]
if !exists {
return nil, nil, fmt.Errorf("param `%s` is not in the environment", obj.Name)
}
graph, err := pgraph.NewGraph("ExprParam")
if err != nil {
return nil, nil, err
}
graph.AddVertex(paramFunc)
return graph, paramFunc, nil
} }
// SetValue here is a no-op, because algorithmically when this is called from // SetValue here is a no-op, because algorithmically when this is called from