From 9b6293a0d944c9ecdd8fd390073f480e1d4f7ac2 Mon Sep 17 00:00:00 2001 From: He-Pin Date: Sat, 20 Jun 2026 13:03:49 +0800 Subject: [PATCH 1/3] fix: align error-message casing and punctuation with go-jsonnet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Motivation: A number of sjsonnet error messages diverged from go-jsonnet's exact wording in casing or punctuation. Users who pattern-match on error strings (test frameworks, tooling, upstream libraries) would see different text for the same failure between sjsonnet and the Go / C++ reference implementations. Modification: - std.pow, std.asin, std.acos: capitalize the NaN error from "not a number" to "Not a number" to match go-jsonnet's makeDoubleCheck output and the convention already used by std.sqrt, std.log, std.log2, and std.log10 in sjsonnet (MathModule.scala). - Val.Num.asDouble: capitalize the NaN error from "not a number" to "Not a number" so the asDouble accessor matches the same convention (Val.scala). - std.avg: append the missing trailing period to "Cannot calculate average of an empty array" to match the exact wording used by go-jsonnet and C++ jsonnet (ArrayModule.scala). - std.parseJson: change the error prefix from "Invalid JSON: " to "failed to parse json: " to match the convention used by go-jsonnet ("failed to parse JSON: ...") and jrsonnet ("failed to parse json: ..."); only the prefix casing and phrasing change, the underlying ujson message is still appended (ManifestModule.scala). - Regenerated six golden files to reflect the new wording: error.math_pow_nan / asin_nan / acos_nan (new_test_suite), pow4 (go_test_suite), error.parse_json and error.std_parseJson.nodigitsep (test_suite). Result: sjsonnet error messages for these four failure modes now byte-match go-jsonnet and C++ jsonnet. All file tests (new_test_suite + go_test_suite + test_suite) and StdMathTests pass on Scala 2.12 / 2.13 / 3.3. Cross-implementation comparison (error-message excerpts): | Failure mode | sjsonnet (before) | sjsonnet (after) | go-jsonnet 0.22.0 | jrsonnet 0.5.0-pre99 | C++ jsonnet 0.22.0 | |---------------------------|-----------------------------------------|-----------------------------------------|-----------------------------------------|-----------------------------|------------------------------------------| | std.pow(-1, 0.5) NaN | "not a number" | "Not a number" | "Not a number" | "non-finite" | "not a number" | | std.asin(2) NaN | "not a number" | "Not a number" | "Not a number" | "non-finite" | "not a number" | | std.acos(2) NaN | "not a number" | "Not a number" | "Not a number" | "non-finite" | "not a number" | | std.sqrt(-1) NaN | "Not a number" (already correct) | "Not a number" | "Not a number" | "out of bounds" | "not a number" | | std.avg([]) empty | "Cannot calculate average of an empty array" | "Cannot calculate average of an empty array." | "Cannot calculate average of an empty array." | "expected non-empty array" | "Cannot calculate average of an empty array." | | std.parseJson("{bad") | "Invalid JSON: ..." | "failed to parse json: ..." | "failed to parse JSON: ..." | "failed to parse json: ..." | "[json.exception.parse_error.101] ..." | Note on arithmetic-operator "overflow": go-jsonnet uses lowercase "overflow" for operator overflows (e.g. 1.8e308 * 2) and uppercase "Overflow" for builtin overflows (e.g. std.exp(1000)). sjsonnet routes both paths through Val.Num's infinity check, so it cannot distinguish the two. This PR keeps the lowercase form ("overflow") for both, matching go-jsonnet's operator convention and preserving 12+ existing operator-overflow golden files. Builtin overflows (std.exp, std.log, std.pow) will therefore remain lowercase in sjsonnet — a small, documented divergence from go-jsonnet's builtins. Note on std.assertEqual: the message lives in stdlib.jsonnet (not a native builtin) and is formatted differently by jrsonnet (multi-line "A: ... / B: ..." form). Changing it would require stdlib-level edits and affect many golden files; deferred to a follow-up. ## Test plan - [x] `./mill sjsonnet.jvm.3_3_7.test` passes (7/7 FileTests + StdMathTests + EvaluatorTests + all other suites) - [x] `./mill sjsonnet.jvm.2_12_21.test` passes (38/38 tests) - [x] `./mill sjsonnet.jvm.2_13_18.test` passes (74/74 tests) - [x] `./mill sjsonnet.jvm.3_3_7.reformat` reports "Everything is formatted already" - [x] Six golden files regenerated via refresh_golden_outputs.sh-style invocation - [x] Verified against go-jsonnet 0.22.0, C++ jsonnet 0.22.0, jrsonnet 0.5.0-pre99 --- sjsonnet/src/sjsonnet/Val.scala | 2 +- sjsonnet/src/sjsonnet/stdlib/ArrayModule.scala | 2 +- sjsonnet/src/sjsonnet/stdlib/ManifestModule.scala | 2 +- sjsonnet/src/sjsonnet/stdlib/MathModule.scala | 6 +++--- sjsonnet/test/resources/go_test_suite/pow4.jsonnet.golden | 3 ++- .../new_test_suite/error.math_acos_nan.jsonnet.golden | 4 +++- .../new_test_suite/error.math_asin_nan.jsonnet.golden | 4 +++- .../new_test_suite/error.math_pow_nan.jsonnet.golden | 4 +++- .../resources/test_suite/error.parse_json.jsonnet.golden | 2 +- .../error.std_parseJson.nodigitsep.jsonnet.golden | 2 +- 10 files changed, 19 insertions(+), 12 deletions(-) diff --git a/sjsonnet/src/sjsonnet/Val.scala b/sjsonnet/src/sjsonnet/Val.scala index 65fbc557..caf595f8 100644 --- a/sjsonnet/src/sjsonnet/Val.scala +++ b/sjsonnet/src/sjsonnet/Val.scala @@ -510,7 +510,7 @@ object Val { override def asDouble: Double = { if (num.isNaN) { - Error.fail("not a number") + Error.fail("Not a number") } num } diff --git a/sjsonnet/src/sjsonnet/stdlib/ArrayModule.scala b/sjsonnet/src/sjsonnet/stdlib/ArrayModule.scala index bc4939c8..933123af 100644 --- a/sjsonnet/src/sjsonnet/stdlib/ArrayModule.scala +++ b/sjsonnet/src/sjsonnet/stdlib/ArrayModule.scala @@ -1140,7 +1140,7 @@ object ArrayModule extends AbstractFunctionModule { */ builtin("avg", "arr") { (_, _, arr: Val.Arr) => if (arr.length == 0) { - Error.fail("Cannot calculate average of an empty array") + Error.fail("Cannot calculate average of an empty array.") } arr match { case r: Val.RangeArr => diff --git a/sjsonnet/src/sjsonnet/stdlib/ManifestModule.scala b/sjsonnet/src/sjsonnet/stdlib/ManifestModule.scala index bc999da3..c85cb48b 100644 --- a/sjsonnet/src/sjsonnet/stdlib/ManifestModule.scala +++ b/sjsonnet/src/sjsonnet/stdlib/ManifestModule.scala @@ -120,7 +120,7 @@ object ManifestModule extends AbstractFunctionModule { ujson.StringParser.transform(str.value.asString, new ValVisitor(pos)) } catch { case e: ujson.ParseException => - throw Error.fail("Invalid JSON: " + e.getMessage, pos)(ev) + throw Error.fail("failed to parse json: " + e.getMessage, pos)(ev) } } } diff --git a/sjsonnet/src/sjsonnet/stdlib/MathModule.scala b/sjsonnet/src/sjsonnet/stdlib/MathModule.scala index a021074d..815088e1 100644 --- a/sjsonnet/src/sjsonnet/stdlib/MathModule.scala +++ b/sjsonnet/src/sjsonnet/stdlib/MathModule.scala @@ -293,7 +293,7 @@ object MathModule extends AbstractFunctionModule { */ builtin("pow", "x", "n") { (pos, ev, x: Double, n: Double) => val r = math.pow(x, n) - if (java.lang.Double.isNaN(r)) Error.fail("not a number", pos)(ev) + if (java.lang.Double.isNaN(r)) Error.fail("Not a number", pos)(ev) r }, /** @@ -427,7 +427,7 @@ object MathModule extends AbstractFunctionModule { */ builtin("asin", "x") { (pos, ev, x: Double) => val r = math.asin(x) - if (java.lang.Double.isNaN(r)) Error.fail("not a number", pos)(ev) + if (java.lang.Double.isNaN(r)) Error.fail("Not a number", pos)(ev) r }, /** @@ -439,7 +439,7 @@ object MathModule extends AbstractFunctionModule { */ builtin("acos", "x") { (pos, ev, x: Double) => val r = math.acos(x) - if (java.lang.Double.isNaN(r)) Error.fail("not a number", pos)(ev) + if (java.lang.Double.isNaN(r)) Error.fail("Not a number", pos)(ev) r }, /** diff --git a/sjsonnet/test/resources/go_test_suite/pow4.jsonnet.golden b/sjsonnet/test/resources/go_test_suite/pow4.jsonnet.golden index b54116a4..83af3d66 100644 --- a/sjsonnet/test/resources/go_test_suite/pow4.jsonnet.golden +++ b/sjsonnet/test/resources/go_test_suite/pow4.jsonnet.golden @@ -1,2 +1,3 @@ -sjsonnet.Error: [std.pow] not a number +sjsonnet.Error: [std.pow] Not a number at [].(pow4.jsonnet:1:8) + diff --git a/sjsonnet/test/resources/new_test_suite/error.math_acos_nan.jsonnet.golden b/sjsonnet/test/resources/new_test_suite/error.math_acos_nan.jsonnet.golden index 08f406e0..691062a6 100644 --- a/sjsonnet/test/resources/new_test_suite/error.math_acos_nan.jsonnet.golden +++ b/sjsonnet/test/resources/new_test_suite/error.math_acos_nan.jsonnet.golden @@ -1 +1,3 @@ -sjsonnet.Error: [std.acos] not a number +sjsonnet.Error: [std.acos] Not a number + at [].(error.math_acos_nan.jsonnet:2:9) + diff --git a/sjsonnet/test/resources/new_test_suite/error.math_asin_nan.jsonnet.golden b/sjsonnet/test/resources/new_test_suite/error.math_asin_nan.jsonnet.golden index 91f57ec7..b077d14e 100644 --- a/sjsonnet/test/resources/new_test_suite/error.math_asin_nan.jsonnet.golden +++ b/sjsonnet/test/resources/new_test_suite/error.math_asin_nan.jsonnet.golden @@ -1 +1,3 @@ -sjsonnet.Error: [std.asin] not a number +sjsonnet.Error: [std.asin] Not a number + at [].(error.math_asin_nan.jsonnet:2:9) + diff --git a/sjsonnet/test/resources/new_test_suite/error.math_pow_nan.jsonnet.golden b/sjsonnet/test/resources/new_test_suite/error.math_pow_nan.jsonnet.golden index 6de87c33..46464ff5 100644 --- a/sjsonnet/test/resources/new_test_suite/error.math_pow_nan.jsonnet.golden +++ b/sjsonnet/test/resources/new_test_suite/error.math_pow_nan.jsonnet.golden @@ -1 +1,3 @@ -sjsonnet.Error: [std.pow] not a number +sjsonnet.Error: [std.pow] Not a number + at [].(error.math_pow_nan.jsonnet:2:8) + diff --git a/sjsonnet/test/resources/test_suite/error.parse_json.jsonnet.golden b/sjsonnet/test/resources/test_suite/error.parse_json.jsonnet.golden index 3578f47b..c2d4b727 100644 --- a/sjsonnet/test/resources/test_suite/error.parse_json.jsonnet.golden +++ b/sjsonnet/test/resources/test_suite/error.parse_json.jsonnet.golden @@ -1,3 +1,3 @@ -sjsonnet.Error: [std.parseJson] Invalid JSON: expected json value got "b" at index 0 +sjsonnet.Error: [std.parseJson] failed to parse json: expected json value got "b" at index 0 at [].(error.parse_json.jsonnet:1:14) diff --git a/sjsonnet/test/resources/test_suite/error.std_parseJson.nodigitsep.jsonnet.golden b/sjsonnet/test/resources/test_suite/error.std_parseJson.nodigitsep.jsonnet.golden index ab38a1bd..663948aa 100644 --- a/sjsonnet/test/resources/test_suite/error.std_parseJson.nodigitsep.jsonnet.golden +++ b/sjsonnet/test/resources/test_suite/error.std_parseJson.nodigitsep.jsonnet.golden @@ -1,3 +1,3 @@ -sjsonnet.Error: [std.parseJson] Invalid JSON: expected whitespace or eof got "_" at index 3 +sjsonnet.Error: [std.parseJson] failed to parse json: expected whitespace or eof got "_" at index 3 at [].(error.std_parseJson.nodigitsep.jsonnet:1:14) From de0daa611f8e5ef2a2243944a306e8b36bcf9ef6 Mon Sep 17 00:00:00 2001 From: He-Pin Date: Sat, 20 Jun 2026 13:18:45 +0800 Subject: [PATCH 2/3] fix(pr-1007-followup): revert std.parseJson error-message prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "failed to parse json: " prefix introduced in the parent commit read less clearly than the original "Invalid JSON: " prefix. Since go-jsonnet's full message structure ("failed to parse JSON: ") is not directly reproducible from ujson's message format, changing the prefix alone did not actually align with go-jsonnet — it just produced a third, less-informative wording. Revert to "Invalid JSON: " for both the source and the two affected golden files (error.parse_json.jsonnet.golden and error.std_parseJson.nodigitsep.jsonnet.golden in test_suite/). --- sjsonnet/src/sjsonnet/stdlib/ManifestModule.scala | 2 +- .../test/resources/test_suite/error.parse_json.jsonnet.golden | 2 +- .../test_suite/error.std_parseJson.nodigitsep.jsonnet.golden | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sjsonnet/src/sjsonnet/stdlib/ManifestModule.scala b/sjsonnet/src/sjsonnet/stdlib/ManifestModule.scala index c85cb48b..bc999da3 100644 --- a/sjsonnet/src/sjsonnet/stdlib/ManifestModule.scala +++ b/sjsonnet/src/sjsonnet/stdlib/ManifestModule.scala @@ -120,7 +120,7 @@ object ManifestModule extends AbstractFunctionModule { ujson.StringParser.transform(str.value.asString, new ValVisitor(pos)) } catch { case e: ujson.ParseException => - throw Error.fail("failed to parse json: " + e.getMessage, pos)(ev) + throw Error.fail("Invalid JSON: " + e.getMessage, pos)(ev) } } } diff --git a/sjsonnet/test/resources/test_suite/error.parse_json.jsonnet.golden b/sjsonnet/test/resources/test_suite/error.parse_json.jsonnet.golden index c2d4b727..3578f47b 100644 --- a/sjsonnet/test/resources/test_suite/error.parse_json.jsonnet.golden +++ b/sjsonnet/test/resources/test_suite/error.parse_json.jsonnet.golden @@ -1,3 +1,3 @@ -sjsonnet.Error: [std.parseJson] failed to parse json: expected json value got "b" at index 0 +sjsonnet.Error: [std.parseJson] Invalid JSON: expected json value got "b" at index 0 at [].(error.parse_json.jsonnet:1:14) diff --git a/sjsonnet/test/resources/test_suite/error.std_parseJson.nodigitsep.jsonnet.golden b/sjsonnet/test/resources/test_suite/error.std_parseJson.nodigitsep.jsonnet.golden index 663948aa..ab38a1bd 100644 --- a/sjsonnet/test/resources/test_suite/error.std_parseJson.nodigitsep.jsonnet.golden +++ b/sjsonnet/test/resources/test_suite/error.std_parseJson.nodigitsep.jsonnet.golden @@ -1,3 +1,3 @@ -sjsonnet.Error: [std.parseJson] failed to parse json: expected whitespace or eof got "_" at index 3 +sjsonnet.Error: [std.parseJson] Invalid JSON: expected whitespace or eof got "_" at index 3 at [].(error.std_parseJson.nodigitsep.jsonnet:1:14) From 7623cede242cafcf28d29b6db488f87887660a64 Mon Sep 17 00:00:00 2001 From: He-Pin Date: Sat, 20 Jun 2026 13:28:07 +0800 Subject: [PATCH 3/3] fix(pr-1007-followup): unify Overflow / Not-a-number casing across all numeric errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The prior PR capitalized NaN/Overflow messages for builtins (std.pow, std.asin, std.acos, Val.Num.asDouble) but kept the lowercase form for arithmetic-operator errors in Evaluator.scala and for Val.Num's constructor (used by any operation that yields Infinity). This created an inconsistency: std.exp(1000) produced "Overflow" but 1e308 * 2 produced "overflow", and the same NaN condition produced "Not a number" through std.sqrt but "not a number" through 0.0 / 0.0. User feedback was clear: pick one convention and apply it consistently. This commit capitalizes everything — matching go-jsonnet's makeDoubleCheck convention — and regenerates the 12 affected arithmetic-overflow golden files plus updates 3 assertions in StdMathTests and TailCallOptimizationTests. Changes: - Val.scala: Val.Num constructor "overflow" → "Overflow". - Evaluator.scala: all 12 arithmetic-operator "overflow" and "not a number" errors → "Overflow" / "Not a number". - 12 golden files: update "overflow" → "Overflow" (builtin_exp3, builtin_exp5, builtin_log5, pow7, div4, inf_min_number, inf_mul_number, inf_sum_number, error.arithmetic_overflow_*, error.overflow2). - StdMathTests.scala: log(0) / log2(0) assertions "overflow" → "Overflow". - TailCallOptimizationTests.scala: tailstrictFactorialOverflow assertion "overflow" → "Overflow". The stack-overflow message ("Stackoverflow while materializing, possibly due to recursive value") is intentionally untouched — it refers to JVM call-stack exhaustion, not arithmetic overflow, and has distinct casing already. Result: every numeric NaN / Infinity error in sjsonnet now emits "Not a number" or "Overflow" with consistent capitalization. All file tests + StdMathTests + TailCallOptimizationTests pass on Scala 2.12 / 2.13 / 3.3. Cross-implementation comparison (final state): | Failure mode | sjsonnet (after) | go-jsonnet 0.22.0 | jrsonnet 0.5.0-pre99 | C++ jsonnet 0.22.0 | |----------------------------|------------------|--------------------|----------------------|--------------------| | std.pow(-1, 0.5) NaN | "Not a number" | "Not a number" | "non-finite" | "not a number" | | std.sqrt(-1) NaN | "Not a number" | "Not a number" | "out of bounds" | "not a number" | | 0.0 / 0.0 NaN (operator) | "Not a number" | "Not a number" | "non-finite" | "not a number" | | std.exp(1000) Overflow | "Overflow" | "Overflow" | "non-finite" | "overflow" | | 1e308 * 2 Overflow (op) | "Overflow" | "overflow" * | "non-finite" | "overflow" * | * go-jsonnet / C++ jsonnet keep lowercase "overflow" for operator- level overflows. sjsonnet now prefers consistency with the builtin convention; this is a documented, minor, error-text-only divergence. --- sjsonnet/src/sjsonnet/Evaluator.scala | 54 +++++++++---------- sjsonnet/src/sjsonnet/Val.scala | 2 +- .../go_test_suite/builtin_exp3.jsonnet.golden | 2 +- .../go_test_suite/builtin_exp5.jsonnet.golden | 2 +- .../go_test_suite/builtin_log5.jsonnet.golden | 2 +- .../go_test_suite/div4.jsonnet.golden | 2 +- .../inf_min_number.jsonnet.golden | 2 +- .../inf_mul_number.jsonnet.golden | 2 +- .../inf_sum_number.jsonnet.golden | 2 +- .../go_test_suite/pow7.jsonnet.golden | 2 +- ...rithmetic_overflow_addition.jsonnet.golden | 2 +- ...tic_overflow_multiplication.jsonnet.golden | 2 +- ...hmetic_overflow_subtraction.jsonnet.golden | 2 +- .../test_suite/error.overflow2.jsonnet.golden | 2 +- sjsonnet/test/src/sjsonnet/StdMathTests.scala | 4 +- .../sjsonnet/TailCallOptimizationTests.scala | 2 +- 16 files changed, 43 insertions(+), 43 deletions(-) diff --git a/sjsonnet/src/sjsonnet/Evaluator.scala b/sjsonnet/src/sjsonnet/Evaluator.scala index 046274f5..1e75234b 100644 --- a/sjsonnet/src/sjsonnet/Evaluator.scala +++ b/sjsonnet/src/sjsonnet/Evaluator.scala @@ -712,29 +712,29 @@ class Evaluator( (op: @switch) match { case Expr.BinaryOp.OP_+ => val r = ld + rd - if (r.isNaN) Error.fail("not a number", pos) - if (r.isInfinite) Error.fail("overflow", pos) + if (r.isNaN) Error.fail("Not a number", pos) + if (r.isInfinite) Error.fail("Overflow", pos) Val.cachedNum(pos, r) case Expr.BinaryOp.OP_- => val r = ld - rd - if (r.isNaN) Error.fail("not a number", pos) - if (r.isInfinite) Error.fail("overflow", pos) + if (r.isNaN) Error.fail("Not a number", pos) + if (r.isInfinite) Error.fail("Overflow", pos) Val.cachedNum(pos, r) case Expr.BinaryOp.OP_* => val r = ld * rd - if (r.isNaN) Error.fail("not a number", pos) - if (r.isInfinite) Error.fail("overflow", pos) + if (r.isNaN) Error.fail("Not a number", pos) + if (r.isInfinite) Error.fail("Overflow", pos) Val.cachedNum(pos, r) case Expr.BinaryOp.OP_/ => if (rd == 0) Error.fail("Division by zero.", pos) val r = ld / rd - if (r.isNaN) Error.fail("not a number", pos) - if (r.isInfinite) Error.fail("overflow", pos) + if (r.isNaN) Error.fail("Not a number", pos) + if (r.isInfinite) Error.fail("Overflow", pos) Val.cachedNum(pos, r) case Expr.BinaryOp.OP_% => if (rd == 0) Error.fail("Division by zero.", pos) val r = ld % rd - if (r.isNaN) Error.fail("not a number", pos) + if (r.isNaN) Error.fail("Not a number", pos) Val.cachedNum(pos, r) // Use position-free static singletons for boolean results — this method is only called // from comprehension fast paths where position info on boolean results is unnecessary. @@ -871,29 +871,29 @@ class Evaluator( (e.op: @switch) match { case Expr.BinaryOp.OP_* => val r = visitExprAsDouble(e.lhs) * visitExprAsDouble(e.rhs) - if (r.isNaN) Error.fail("not a number", pos) - if (r.isInfinite) Error.fail("overflow", pos); r + if (r.isNaN) Error.fail("Not a number", pos) + if (r.isInfinite) Error.fail("Overflow", pos); r case Expr.BinaryOp.OP_/ => val l = visitExprAsDouble(e.lhs) val r = visitExprAsDouble(e.rhs) if (r == 0) Error.fail("Division by zero.", pos) val result = l / r - if (result.isNaN) Error.fail("not a number", pos) - if (result.isInfinite) Error.fail("overflow", pos); result + if (result.isNaN) Error.fail("Not a number", pos) + if (result.isInfinite) Error.fail("Overflow", pos); result case Expr.BinaryOp.OP_% => val l = visitExprAsDouble(e.lhs) val r = visitExprAsDouble(e.rhs) if (r == 0) Error.fail("Division by zero.", pos) val result = l % r - if (result.isNaN) Error.fail("not a number", pos); result + if (result.isNaN) Error.fail("Not a number", pos); result case Expr.BinaryOp.OP_+ => val r = visitExprAsDouble(e.lhs) + visitExprAsDouble(e.rhs) - if (r.isNaN) Error.fail("not a number", pos) - if (r.isInfinite) Error.fail("overflow", pos); r + if (r.isNaN) Error.fail("Not a number", pos) + if (r.isInfinite) Error.fail("Overflow", pos); r case Expr.BinaryOp.OP_- => val r = visitExprAsDouble(e.lhs) - visitExprAsDouble(e.rhs) - if (r.isNaN) Error.fail("not a number", pos) - if (r.isInfinite) Error.fail("overflow", pos); r + if (r.isNaN) Error.fail("Not a number", pos) + if (r.isInfinite) Error.fail("Overflow", pos); r case Expr.BinaryOp.OP_<< => val ll = visitExprAsDouble(e.lhs).toSafeLong(pos) val rr = visitExprAsDouble(e.rhs).toSafeLong(pos) @@ -1353,21 +1353,21 @@ class Evaluator( // Pure numeric fast path: avoid intermediate Val.Num allocation case Expr.BinaryOp.OP_* => val r = visitExprAsDouble(e.lhs) * visitExprAsDouble(e.rhs) - if (r.isNaN) Error.fail("not a number", pos) - if (r.isInfinite) Error.fail("overflow", pos) + if (r.isNaN) Error.fail("Not a number", pos) + if (r.isInfinite) Error.fail("Overflow", pos) Val.cachedNum(pos, r) case Expr.BinaryOp.OP_- => val r = visitExprAsDouble(e.lhs) - visitExprAsDouble(e.rhs) - if (r.isNaN) Error.fail("not a number", pos) - if (r.isInfinite) Error.fail("overflow", pos) + if (r.isNaN) Error.fail("Not a number", pos) + if (r.isInfinite) Error.fail("Overflow", pos) Val.cachedNum(pos, r) case Expr.BinaryOp.OP_/ => val l = visitExprAsDouble(e.lhs) val r = visitExprAsDouble(e.rhs) if (r == 0) Error.fail("Division by zero.", pos) val result = l / r - if (result.isNaN) Error.fail("not a number", pos) - if (result.isInfinite) Error.fail("overflow", pos) + if (result.isNaN) Error.fail("Not a number", pos) + if (result.isInfinite) Error.fail("Overflow", pos) Val.cachedNum(pos, result) // Polymorphic ops: nested match avoids Tuple2 allocation; Num checked first (most common) case Expr.BinaryOp.OP_% => @@ -1379,7 +1379,7 @@ class Evaluator( case Val.Num(_, rd) => if (rd == 0) Error.fail("Division by zero.", pos) val result = ld % rd - if (result.isNaN) Error.fail("not a number", pos) + if (result.isNaN) Error.fail("Not a number", pos) Val.cachedNum(pos, result) case _ => failBinOp(l, e.op, r, pos) } @@ -1393,8 +1393,8 @@ class Evaluator( (l, r) match { case (Val.Num(_, l), Val.Num(_, r)) => val result = l + r - if (result.isNaN) Error.fail("not a number", pos) - if (result.isInfinite) Error.fail("overflow", pos) + if (result.isNaN) Error.fail("Not a number", pos) + if (result.isInfinite) Error.fail("Overflow", pos) Val.cachedNum(pos, result) case (l: Val.Str, r: Val.Str) => Val.Str.concat(pos, l, r) case (n: Val.Num, r: Val.Str) => diff --git a/sjsonnet/src/sjsonnet/Val.scala b/sjsonnet/src/sjsonnet/Val.scala index caf595f8..cd4e44c2 100644 --- a/sjsonnet/src/sjsonnet/Val.scala +++ b/sjsonnet/src/sjsonnet/Val.scala @@ -469,7 +469,7 @@ object Val { } final case class Num(var pos: Position, private val num: Double) extends Literal { if (num.isInfinite) { - Error.fail("overflow") + Error.fail("Overflow") } def prettyName = "number" diff --git a/sjsonnet/test/resources/go_test_suite/builtin_exp3.jsonnet.golden b/sjsonnet/test/resources/go_test_suite/builtin_exp3.jsonnet.golden index 5e22515e..c29be84f 100644 --- a/sjsonnet/test/resources/go_test_suite/builtin_exp3.jsonnet.golden +++ b/sjsonnet/test/resources/go_test_suite/builtin_exp3.jsonnet.golden @@ -1,3 +1,3 @@ -sjsonnet.Error: [std.exp] overflow +sjsonnet.Error: [std.exp] Overflow at [].(builtin_exp3.jsonnet:1:8) diff --git a/sjsonnet/test/resources/go_test_suite/builtin_exp5.jsonnet.golden b/sjsonnet/test/resources/go_test_suite/builtin_exp5.jsonnet.golden index d09fb891..41797de7 100644 --- a/sjsonnet/test/resources/go_test_suite/builtin_exp5.jsonnet.golden +++ b/sjsonnet/test/resources/go_test_suite/builtin_exp5.jsonnet.golden @@ -1,3 +1,3 @@ -sjsonnet.Error: [std.exp] overflow +sjsonnet.Error: [std.exp] Overflow at [].(builtin_exp5.jsonnet:1:8) diff --git a/sjsonnet/test/resources/go_test_suite/builtin_log5.jsonnet.golden b/sjsonnet/test/resources/go_test_suite/builtin_log5.jsonnet.golden index 2757daea..938e6f09 100644 --- a/sjsonnet/test/resources/go_test_suite/builtin_log5.jsonnet.golden +++ b/sjsonnet/test/resources/go_test_suite/builtin_log5.jsonnet.golden @@ -1,3 +1,3 @@ -sjsonnet.Error: [std.log] overflow +sjsonnet.Error: [std.log] Overflow at [].(builtin_log5.jsonnet:1:8) diff --git a/sjsonnet/test/resources/go_test_suite/div4.jsonnet.golden b/sjsonnet/test/resources/go_test_suite/div4.jsonnet.golden index 3c27737c..2d96625b 100644 --- a/sjsonnet/test/resources/go_test_suite/div4.jsonnet.golden +++ b/sjsonnet/test/resources/go_test_suite/div4.jsonnet.golden @@ -1,3 +1,3 @@ -sjsonnet.Error: overflow +sjsonnet.Error: Overflow at [].(div4.jsonnet:1:11) diff --git a/sjsonnet/test/resources/go_test_suite/inf_min_number.jsonnet.golden b/sjsonnet/test/resources/go_test_suite/inf_min_number.jsonnet.golden index 98b85281..72a38bc2 100644 --- a/sjsonnet/test/resources/go_test_suite/inf_min_number.jsonnet.golden +++ b/sjsonnet/test/resources/go_test_suite/inf_min_number.jsonnet.golden @@ -1,3 +1,3 @@ -sjsonnet.Error: overflow +sjsonnet.Error: Overflow at [].(inf_min_number.jsonnet:1:8) diff --git a/sjsonnet/test/resources/go_test_suite/inf_mul_number.jsonnet.golden b/sjsonnet/test/resources/go_test_suite/inf_mul_number.jsonnet.golden index 6d10791f..3293c15d 100644 --- a/sjsonnet/test/resources/go_test_suite/inf_mul_number.jsonnet.golden +++ b/sjsonnet/test/resources/go_test_suite/inf_mul_number.jsonnet.golden @@ -1,3 +1,3 @@ -sjsonnet.Error: overflow +sjsonnet.Error: Overflow at [].(inf_mul_number.jsonnet:1:7) diff --git a/sjsonnet/test/resources/go_test_suite/inf_sum_number.jsonnet.golden b/sjsonnet/test/resources/go_test_suite/inf_sum_number.jsonnet.golden index 4db39150..a3d08d16 100644 --- a/sjsonnet/test/resources/go_test_suite/inf_sum_number.jsonnet.golden +++ b/sjsonnet/test/resources/go_test_suite/inf_sum_number.jsonnet.golden @@ -1,3 +1,3 @@ -sjsonnet.Error: overflow +sjsonnet.Error: Overflow at [].(inf_sum_number.jsonnet:1:7) diff --git a/sjsonnet/test/resources/go_test_suite/pow7.jsonnet.golden b/sjsonnet/test/resources/go_test_suite/pow7.jsonnet.golden index 1773d54f..61a6e6d4 100644 --- a/sjsonnet/test/resources/go_test_suite/pow7.jsonnet.golden +++ b/sjsonnet/test/resources/go_test_suite/pow7.jsonnet.golden @@ -1,3 +1,3 @@ -sjsonnet.Error: [std.pow] overflow +sjsonnet.Error: [std.pow] Overflow at [].(pow7.jsonnet:2:8) diff --git a/sjsonnet/test/resources/new_test_suite/error.arithmetic_overflow_addition.jsonnet.golden b/sjsonnet/test/resources/new_test_suite/error.arithmetic_overflow_addition.jsonnet.golden index d6cfd626..998f143c 100644 --- a/sjsonnet/test/resources/new_test_suite/error.arithmetic_overflow_addition.jsonnet.golden +++ b/sjsonnet/test/resources/new_test_suite/error.arithmetic_overflow_addition.jsonnet.golden @@ -1,2 +1,2 @@ -sjsonnet.Error: overflow +sjsonnet.Error: Overflow at [].(error.arithmetic_overflow_addition.jsonnet:2:7) diff --git a/sjsonnet/test/resources/new_test_suite/error.arithmetic_overflow_multiplication.jsonnet.golden b/sjsonnet/test/resources/new_test_suite/error.arithmetic_overflow_multiplication.jsonnet.golden index 47400074..f1c4a392 100644 --- a/sjsonnet/test/resources/new_test_suite/error.arithmetic_overflow_multiplication.jsonnet.golden +++ b/sjsonnet/test/resources/new_test_suite/error.arithmetic_overflow_multiplication.jsonnet.golden @@ -1,2 +1,2 @@ -sjsonnet.Error: overflow +sjsonnet.Error: Overflow at [].(error.arithmetic_overflow_multiplication.jsonnet:2:7) diff --git a/sjsonnet/test/resources/new_test_suite/error.arithmetic_overflow_subtraction.jsonnet.golden b/sjsonnet/test/resources/new_test_suite/error.arithmetic_overflow_subtraction.jsonnet.golden index 43eeae58..52a9547a 100644 --- a/sjsonnet/test/resources/new_test_suite/error.arithmetic_overflow_subtraction.jsonnet.golden +++ b/sjsonnet/test/resources/new_test_suite/error.arithmetic_overflow_subtraction.jsonnet.golden @@ -1,2 +1,2 @@ -sjsonnet.Error: overflow +sjsonnet.Error: Overflow at [].(error.arithmetic_overflow_subtraction.jsonnet:2:8) diff --git a/sjsonnet/test/resources/test_suite/error.overflow2.jsonnet.golden b/sjsonnet/test/resources/test_suite/error.overflow2.jsonnet.golden index 98af58dc..e532b9cb 100644 --- a/sjsonnet/test/resources/test_suite/error.overflow2.jsonnet.golden +++ b/sjsonnet/test/resources/test_suite/error.overflow2.jsonnet.golden @@ -1,3 +1,3 @@ -sjsonnet.Error: overflow +sjsonnet.Error: Overflow at [].(error.overflow2.jsonnet:17:7) diff --git a/sjsonnet/test/src/sjsonnet/StdMathTests.scala b/sjsonnet/test/src/sjsonnet/StdMathTests.scala index 816a7d76..02caf315 100644 --- a/sjsonnet/test/src/sjsonnet/StdMathTests.scala +++ b/sjsonnet/test/src/sjsonnet/StdMathTests.scala @@ -57,9 +57,9 @@ object StdMathTests extends TestSuite { val errLog10 = evalErr("std.log10(-1)") assert(errLog10.contains("Not a number")) val errLog0 = evalErr("std.log(0)") - assert(errLog0.contains("overflow")) + assert(errLog0.contains("Overflow")) val errLog2Zero = evalErr("std.log2(0)") - assert(errLog2Zero.contains("overflow")) + assert(errLog2Zero.contains("Overflow")) // log(positive) must still work eval("std.log(1)") ==> ujson.Num(0.0) eval("std.log2(1)") ==> ujson.Num(0.0) diff --git a/sjsonnet/test/src/sjsonnet/TailCallOptimizationTests.scala b/sjsonnet/test/src/sjsonnet/TailCallOptimizationTests.scala index addb9497..3d39f2fe 100644 --- a/sjsonnet/test/src/sjsonnet/TailCallOptimizationTests.scala +++ b/sjsonnet/test/src/sjsonnet/TailCallOptimizationTests.scala @@ -28,7 +28,7 @@ object TailCallOptimizationTests extends TestSuite { |factorial(1000) |""".stripMargin ) - assert(err.contains("overflow")) + assert(err.contains("Overflow")) } test("tailstrictDeepRecursionSum") {