The temporary failures for unknown variables and functions can now become precise. Today you give both a clear, positioned message using the position each node has carried since it was parsed.
Report positioned errors for an undefined variable and an undefined function.
Two lessons left placeholder errors behind: the variable lookup and the function
dispatch each failed with a bare message and no position. Now that the errors chapter
is establishing a consistent <what> at position <n> style, upgrade both. The Var
node has carried its name’s position since you first parsed it, and the Call node
has carried the function name’s position, so y + 1 reports the unknown y at
position 0, and foo(2) reports the unknown foo at position 0.
Consistency is the point. A user who mistypes a name, whether it is meant to be a variable or a function, gets the same shape of message pointing at the same place. The evaluator now handles the three ways evaluation can go wrong from bad references and arithmetic: a divide by zero, an unknown variable, and an unknown function. One class of mistake remains, calling a known function the wrong way, and that is next.
// Var lookup: upgrade the temporary message to a positioned oneif !ok {return 0, fmt.Errorf("undefined variable: %s at position %d", n.Name, n.Pos)}// Call dispatch: the fall-through for an unknown name becomesreturn 0, fmt.Errorf("undefined function: %s at position %d", n.Name, n.Pos)