cue: fix 0/0

Should be error, not NaN.

Closes #84

Change-Id: I061b7e32b069c1fea3123fb981a4eddf87c61910
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/3044
Reviewed-by: Marcel van Lohuizen <mpvl@google.com>
diff --git a/cue/binop.go b/cue/binop.go
index b9b6149..55286f4 100644
--- a/cue/binop.go
+++ b/cue/binop.go
@@ -956,30 +956,33 @@
 		case opMul:
 			_, _ = ctx.Mul(&n.v, &x.v, &y.v)
 		case opQuo:
-			cond, _ := ctx.Quo(&n.v, &x.v, &y.v)
+			cond, err := ctx.Quo(&n.v, &x.v, &y.v)
+			if err != nil {
+				return ctx.mkErr(src, err.Error())
+			}
 			if cond.DivisionByZero() {
-				return ctx.mkErr(src, "divide by zero")
+				return ctx.mkErr(src, "division by zero")
 			}
 			_, _, _ = ctx.Reduce(&n.v, &n.v)
 			n.k = floatKind
 		case opIDiv:
 			if y.v.IsZero() {
-				return ctx.mkErr(src, "divide by zero")
+				return ctx.mkErr(src, "division by zero")
 			}
 			intOp(ctx, n, (*big.Int).Div, x, y)
 		case opIMod:
 			if y.v.IsZero() {
-				return ctx.mkErr(src, "divide by zero")
+				return ctx.mkErr(src, "division by zero")
 			}
 			intOp(ctx, n, (*big.Int).Mod, x, y)
 		case opIQuo:
 			if y.v.IsZero() {
-				return ctx.mkErr(src, "divide by zero")
+				return ctx.mkErr(src, "division by zero")
 			}
 			intOp(ctx, n, (*big.Int).Quo, x, y)
 		case opIRem:
 			if y.v.IsZero() {
-				return ctx.mkErr(src, "divide by zero")
+				return ctx.mkErr(src, "division by zero")
 			}
 			intOp(ctx, n, (*big.Int).Rem, x, y)
 		}
diff --git a/cue/resolve_test.go b/cue/resolve_test.go
index 1e5cbd4..9a0f471 100644
--- a/cue/resolve_test.go
+++ b/cue/resolve_test.go
@@ -137,8 +137,14 @@
 			div1: 2.0 / 3 * 6   // 4
 			div2: 2 / 3 * 6     // 4
 			divZero: 1.0 / 0
+			div00: 0 / 0
 			b: 1 != 4
 
+			idiv00: 0 div 0
+			imod00: 0 mod 0
+			iquo00: 0 quo 0
+			irem00: 0 rem 0
+
 			v1: 1.0T/2.0
 			v2: 2.0 == 2
 			v3: 2.0/3.0
@@ -159,8 +165,13 @@
 			`sum: 1, ` +
 			`div1: 4.00000000000000000000000, ` +
 			`div2: 4.00000000000000000000000, ` +
-			`divZero: _|_((1.0 / 0):divide by zero), ` +
+			`divZero: _|_((1.0 / 0):division by zero), ` +
+			`div00: _|_((0 / 0):division undefined), ` +
 			`b: true, ` +
+			`idiv00: _|_((0 div 0):division by zero), ` +
+			`imod00: _|_((0 mod 0):division by zero), ` +
+			`iquo00: _|_((0 quo 0):division by zero), ` +
+			`irem00: _|_((0 rem 0):division by zero), ` +
 			`v1: 5e+11, ` +
 			`v2: true, ` +
 			`v3: 0.666666666666666666666667, ` +
@@ -205,8 +216,6 @@
 			m4: -5 mod -2  // 1
 			me1: 2.0 mod 1
 			me2: 2 mod 1.0
-
-			// TODO: handle divide by zero
 			`,
 		out: `<0>{q1: 2, q2: -2, q3: -2, q4: 2, ` +
 			`qe1: _|_((2.0 quo 1):invalid operation 2.0 quo 1 (mismatched types float and int)), ` +
diff --git a/cue/types_test.go b/cue/types_test.go
index ca16b49..bcfc85e 100644
--- a/cue/types_test.go
+++ b/cue/types_test.go
@@ -342,7 +342,7 @@
 		float64: 0,
 		prec:    2,
 		fmt:     'f',
-		err:     "divide by zero",
+		err:     "division by zero",
 		kind:    BottomKind,
 	}, {
 		value:   "1.797693134862315708145274237317043567982e+308",
@@ -1755,6 +1755,9 @@
 		value: `3.0e100`,
 		json:  `3.0E+100`,
 	}, {
+		value: `0/0`,
+		err:   "division undefined",
+	}, {
 		value: `[]`,
 		json:  `[]`,
 	}, {