func ord(x Value) int {
switch x.(type) {
default:
- return -1 // force invalid value into "x position" in match
+ // force invalid value into "x position" in match
+ // (don't panic here so that callers can provide a better error message)
+ return -1
case unknownVal:
return 0
case boolVal, stringVal:
// match returns the matching representation (same type) with the
// smallest complexity for two values x and y. If one of them is
-// numeric, both of them must be numeric. If one of them is Unknown,
-// both results are Unknown.
+// numeric, both of them must be numeric. If one of them is Unknown
+// or invalid (say, nil) both results are that value.
//
func match(x, y Value) (_, _ Value) {
if ord(x) > ord(y) {
}
}
- return x, x // force unknown and invalid values into "x position" in callers of match
+ // force unknown and invalid values into "x position" in callers of match
+ // (don't panic here so that callers can provide a better error message)
+ return x, x
}
// BinaryOp returns the result of the binary expression x op y.
// instead of token.QUO; the result is guaranteed to be Int in this case.
// Division by zero leads to a run-time panic.
//
-func BinaryOp(x Value, op token.Token, y Value) Value {
- x, y = match(x, y)
+func BinaryOp(x_ Value, op token.Token, y_ Value) Value {
+ x, y := match(x_, y_)
switch x := x.(type) {
case unknownVal:
}
Error:
- panic(fmt.Sprintf("invalid binary operation %v %s %v", x, op, y))
+ panic(fmt.Sprintf("invalid binary operation %v %s %v", x_, op, y_))
}
func add(x, y Value) Value { return BinaryOp(x, token.ADD, y) }
// If one of the operands is Unknown, the result is
// false.
//
-func Compare(x Value, op token.Token, y Value) bool {
- x, y = match(x, y)
+func Compare(x_ Value, op token.Token, y_ Value) bool {
+ x, y := match(x_, y_)
switch x := x.(type) {
case unknownVal:
}
}
- panic(fmt.Sprintf("invalid comparison %v %s %v", x, op, y))
+ panic(fmt.Sprintf("invalid comparison %v %s %v", x_, op, y_))
}