Skip to content

Commit 7ddfc67

Browse files
committed
Some progress, still need to test all error messages
1 parent e76f4d3 commit 7ddfc67

File tree

7 files changed

+168
-127
lines changed

7 files changed

+168
-127
lines changed

src/arr/trove/contracts.arr

+9-9
Original file line numberDiff line numberDiff line change
@@ -300,23 +300,23 @@ data FailureReason:
300300
end,
301301
method render-reason(self, loc, from-fail-arg):
302302
message = [ED.para:
303-
ED.text("The predicate"), ED.code(ED.text(self.name)),
304-
ED.text("in the annotation at"), draw-and-highlight(loc),
305-
ED.text("returned false for this value:"), ED.embed(self.val)]
303+
ED.text("The predicate "), ED.code(ED.text(self.name)),
304+
ED.text(" in the annotation at "), draw-and-highlight(loc),
305+
ED.text(" returned false for this value: "), ED.embed(self.val)]
306306
if self.is-implicit and not(loc.is-builtin()):
307307
[ED.error:
308308
message,
309309
[ED.para:
310-
ED.text("The unit"), ED.code(ED.text(self.actual)),
311-
ED.text("was expected to match"), ED.code(ED.text(self.expected)),
312-
ED.text("due to the default of the"), ED.code(ED.text(self.name)),
313-
ED.text("annotation. Did you mean to specify another unit or the any unit (%<_>)?")]]
310+
ED.text("The unit "), ED.code(ED.text(self.actual)),
311+
ED.text(" was expected to match "), ED.code(ED.text(self.expected)),
312+
ED.text(" due to the default of the "), ED.code(ED.text(self.name)),
313+
ED.text(" annotation. Did you mean to specify another unit or the any unit (%<_>)?")]]
314314
else:
315315
[ED.error:
316316
message,
317317
[ED.para:
318-
ED.text("The unit"), ED.code(ED.text(self.actual)),
319-
ED.text("was expected to match"), ED.code(ED.text(self.expected))]]
318+
ED.text("The unit "), ED.code(ED.text(self.actual)),
319+
ED.text(" was expected to match "), ED.code(ED.text(self.expected))]]
320320
end
321321
end
322322
| record-fields-fail(val, field-failures :: List<FieldFailure>) with:

src/arr/trove/error.arr

+60-81
Original file line numberDiff line numberDiff line change
@@ -2471,122 +2471,101 @@ data RuntimeError:
24712471
[ED.error: base-err]
24722472
end
24732473
end
2474-
| incompatible-units(op-name, l, r) with:
2475-
method render-fancy-reason(self, maybe-stack-loc, src-available, maybe-ast):
2474+
| incompatible-units(reason, u, v) with:
2475+
# TODO Fix spacing in render-fancy-reason (and maybe render-reason)
2476+
method render-fancy-reason(self, maybe-stack-loc, src-available, maybe-ast) block:
2477+
base-err-msg = [ED.para:
2478+
ED.text("The units "),
2479+
ED.code(ED.text(self.u)),
2480+
ED.text(" and "),
2481+
ED.code(ED.text(self.v)),
2482+
ED.text(" are not compatible")]
24762483
[ED.error:
2477-
cases(O.Option) maybe-stack-loc(0, false):
2484+
cases(O.Option) maybe-stack-loc(0, true) block:
24782485
| some(loc) =>
2486+
default-err-msg = [ED.sequence:
2487+
ed-intro(self.reason, loc, -1, true),
2488+
ED.cmcode(loc),
2489+
base-err-msg]
24792490
if loc.is-builtin():
24802491
[ED.sequence:
2481-
ed-intro(self.op-name + " operation", loc, -1, true),
2482-
[ED.para:
2483-
ED.text("The left side had the unit: "),
2484-
ED.code(ED.text(self.l))],
2485-
[ED.para:
2486-
ED.text("The right side had the unit: "),
2487-
ED.code(ED.text(self.r))],
2488-
[ED.para: ED.text("These units are not compatible")],
2492+
ed-intro(self.reason, loc, -1, true),
2493+
base-err-msg,
24892494
please-report-bug()]
24902495
else if src-available(loc):
24912496
cases(O.Option) maybe-ast(loc):
24922497
| some(ast) =>
2493-
left-loc = ast.left.l
2494-
right-loc = ast.right.l
2495-
[ED.sequence:
2496-
ed-intro(self.op-name + " operation", loc, -1, true),
2497-
ED.cmcode(loc),
2498-
[ED.para:
2499-
ED.text("The "),
2500-
ED.highlight(ED.text("left side"), [ED.locs: left-loc], 0),
2501-
ED.text(" had the unit:")],
2502-
ED.code(ED.text(self.l)),
2503-
[ED.para:
2504-
ED.text("The "),
2505-
ED.highlight(ED.text("right side"), [ED.locs: right-loc], 1),
2506-
ED.text(" had the unit: ")],
2507-
ED.code(ED.text(self.r)),
2508-
[ED.para: ED.text("These units are not compatible")]]
2509-
| none =>
2510-
[ED.sequence:
2511-
ed-intro(self.op-name + " operation", loc, -1, true),
2512-
ED.cmcode(loc),
2513-
[ED.para:
2514-
ED.text("The left side had the unit: "),
2515-
ED.code(ED.text(self.l))],
2516-
[ED.para:
2517-
ED.text("The right side had the unit: "),
2518-
ED.code(ED.text(self.r))],
2519-
[ED.para: ED.text("These units are not compatible")]]
2498+
cases(Any) ast:
2499+
| s-op(_l, op-l, opname, l, r) =>
2500+
left-loc = l.l
2501+
right-loc = r.l
2502+
[ED.sequence:
2503+
ed-intro(self.reason, loc, -1, true),
2504+
ED.cmcode(loc),
2505+
[ED.para:
2506+
ED.text("The "),
2507+
ED.highlight(ED.text("left side"), [ED.locs: left-loc], 0),
2508+
ED.text(" had the unit:")],
2509+
ED.code(ED.text(self.u)),
2510+
[ED.para:
2511+
ED.text("The "),
2512+
ED.highlight(ED.text("right side"), [ED.locs: right-loc], 1),
2513+
ED.text(" had the unit: ")],
2514+
ED.code(ED.text(self.v)),
2515+
[ED.para: ED.text("These units are not compatible")]]
2516+
| else => default-err-msg
2517+
end
2518+
| none => default-err-msg
25202519
end
25212520
else:
2522-
[ED.sequence:
2523-
ed-intro(self.op-name + " operation", loc, -1, true),
2524-
ED.cmcode(loc),
2525-
[ED.para:
2526-
ED.text("The left side had the unit: "),
2527-
ED.code(ED.text(self.l))],
2528-
[ED.para:
2529-
ED.text("The right side had the unit: "),
2530-
ED.code(ED.text(self.r))],
2531-
[ED.para: ED.text("These units are not compatible")]]
2521+
default-err-msg
25322522
end
25332523
| none =>
25342524
[ED.sequence:
25352525
[ED.para:
25362526
ED.text("A "),
2537-
ED.code(ED.text(self.opname)),
2538-
ED.text(" operation errored.")],
2539-
[ED.para:
2540-
ED.text("The left side had the unit: "),
2541-
ED.code(ED.text(self.l))],
2542-
[ED.para:
2543-
ED.text("The right side had the unit: "),
2544-
ED.code(ED.text(self.r))],
2545-
[ED.para: ED.text("These units are not compatible")]]
2527+
ED.code(ED.text(self.reason)),
2528+
ED.text(" errored.")],
2529+
base-err-msg]
25462530
end]
25472531
end,
2548-
method render-reason(self):
2532+
method render-reason(self) block:
2533+
base-err-msg = [ED.para:
2534+
ED.text("The units "),
2535+
ED.code(ED.text(self.u)),
2536+
ED.text(" and "),
2537+
ED.code(ED.text(self.v)),
2538+
ED.text(" are not compatible")]
25492539
[ED.error: ED.maybe-stack-loc(0, false,
25502540
lam(loc):
25512541
[ED.sequence:
2552-
ed-simple-intro(self.op-name + " operation", loc),
2553-
[ED.para:
2554-
ED.text("The left side had the unit: "),
2555-
ED.code(ED.text(self.l))],
2556-
[ED.para:
2557-
ED.text("The right side had the unit: "),
2558-
ED.code(ED.text(self.r))],
2559-
[ED.para: ED.text("These units are not compatible")]]
2542+
ed-simple-intro(self.reason, loc),
2543+
base-err-msg]
25602544
end,
25612545
[ED.sequence:
25622546
[ED.para:
25632547
ED.text("A "),
2564-
ED.code(ED.text(self.opname)),
2565-
ED.text(" operation errored.")],
2566-
[ED.para:
2567-
ED.text("The left side had the unit: "),
2568-
ED.code(ED.text(self.l))],
2569-
[ED.para:
2570-
ED.text("The right side had the unit: "),
2571-
ED.code(ED.text(self.r))],
2572-
[ED.para: ED.text("These units are not compatible")]])]
2548+
ED.code(ED.text(self.reason)),
2549+
ED.text(" errored.")],
2550+
base-err-msg])]
25732551
end
2574-
| invalid-unit-state(op-name, n, desc) with:
2552+
| invalid-unit-state(opname, n, desc) with:
2553+
# TODO: update
25752554
method render-fancy-reason(self, maybe-stack-loc, src-available, maybe-ast):
25762555
[ED.error:
25772556
cases(O.Option) maybe-stack-loc(0, false):
25782557
| some(loc) =>
25792558
if loc.is-builtin():
25802559
[ED.sequence:
2581-
ed-intro(self.op-name + " function", loc, -1, true),
2560+
ed-intro(self.opname + " function", loc, -1, true),
25822561
[ED.para:
25832562
ED.code(ED.text(tostring(self.n))),
25842563
ED.text(" is an invalid argument because: "),
25852564
ED.text(self.desc)],
25862565
please-report-bug()]
25872566
else if src-available(loc):
25882567
[ED.sequence:
2589-
ed-intro(self.op-name + " function", loc, -1, true),
2568+
ed-intro(self.opname + " function", loc, -1, true),
25902569
ED.cmcode(loc),
25912570
[ED.para:
25922571
ED.code(ED.text(tostring(self.n))),
@@ -2596,7 +2575,7 @@ data RuntimeError:
25962575
| none =>
25972576
[ED.sequence:
25982577
[ED.para:
2599-
ED.text("The " + self.op-name + " function failed.")],
2578+
ED.text("The " + self.opname + " function failed.")],
26002579
[ED.para:
26012580
ED.code(ED.text(tostring(self.n))),
26022581
ED.text(" is an invalid argument because: "),
@@ -2607,14 +2586,14 @@ data RuntimeError:
26072586
[ED.error: ED.maybe-stack-loc(0, false,
26082587
lam(loc):
26092588
[ED.sequence:
2610-
ed-simple-intro(self.op-name + " function", loc),
2589+
ed-simple-intro(self.opname + " function", loc),
26112590
[ED.para:
26122591
ED.code(ED.text(tostring(self.n))),
26132592
ED.text(" is an invalid argument because: "),
26142593
ED.text(self.desc)]]
26152594
end,
26162595
[ED.sequence:
2617-
[ED.para: ED.text("The " + self.op-name + " function failed.")],
2596+
[ED.para: ED.text("The " + self.opname + " function failed.")],
26182597
[ED.para:
26192598
ED.code(ED.text(tostring(self.n))),
26202599
ED.text(" is an invalid argument because: "),

src/js/base/js-numbers.js

+23-13
Original file line numberDiff line numberDiff line change
@@ -372,13 +372,13 @@ define("pyret-base/js/js-numbers", function() {
372372
{isXSpecialCase: function(x, errbacks) {
373373
return isInteger(x) && _integerIsZero(x) },
374374
onXSpecialCase: function(x, y, errbacks) {
375-
ensureSameUnits(x, y, errbacks, "+");
375+
ensureSameUnits(x, y, errbacks, "+ operation");
376376
return y;
377377
},
378378
isYSpecialCase: function(y, errbacks) {
379379
return isInteger(y) && _integerIsZero(y) },
380380
onYSpecialCase: function(x, y, errbacks) {
381-
ensureSameUnits(x, y, errbacks, "+");
381+
ensureSameUnits(x, y, errbacks, "+ operation");
382382
return x;
383383
}
384384
});
@@ -411,13 +411,13 @@ define("pyret-base/js/js-numbers", function() {
411411
{isXSpecialCase: function(x, errbacks) {
412412
return isInteger(x) && _integerIsZero(x) },
413413
onXSpecialCase: function(x, y, errbacks) {
414-
ensureSameUnits(x, y, errbacks, "-");
414+
ensureSameUnits(x, y, errbacks, "- operation");
415415
return negate(y, errbacks);
416416
},
417417
isYSpecialCase: function(y, errbacks) {
418418
return isInteger(y) && _integerIsZero(y) },
419419
onYSpecialCase: function(x, y, errbacks) {
420-
ensureSameUnits(x, y, errbacks, "-");
420+
ensureSameUnits(x, y, errbacks, "- operation");
421421
return x;
422422
}
423423
});
@@ -550,7 +550,10 @@ define("pyret-base/js/js-numbers", function() {
550550
};
551551

552552
// used for within
553-
var roughlyEquals = function(x, y, delta, errbacks) {
553+
var roughlyEquals = function(x, y, delta, where, errbacks) {
554+
ensureSameUnits(x, y, errbacks, where + "'s arguments");
555+
ensureSameUnits(y, delta, errbacks, where + "'s tolerance");
556+
554557
if (isNegative(delta)) {
555558
errbacks.throwToleranceError("negative tolerance " + delta);
556559
}
@@ -559,7 +562,7 @@ define("pyret-base/js/js-numbers", function() {
559562

560563
if (isRoughnum(delta) && delta.n === Number.MIN_VALUE) {
561564
if ((isRoughnum(x) || isRoughnum(y)) &&
562-
(Math.abs(subtract(x,y).n) === Number.MIN_VALUE)) {
565+
(Math.abs(_withoutUnit(subtract(x,y)).n) === Number.MIN_VALUE)) {
563566
errbacks.throwToleranceError("roughnum tolerance too small for meaningful comparison, " + x + ' ' + y + ' ' + delta);
564567
}
565568
}
@@ -571,7 +574,12 @@ define("pyret-base/js/js-numbers", function() {
571574
return approxEquals(ratx, raty, ratdelta, errbacks);
572575
};
573576

574-
var roughlyEqualsRel = function(computedValue, trueValue, delta, errbacks) {
577+
var roughlyEqualsRel = function(computedValue, trueValue, delta, where, errbacks) {
578+
if (!checkUnit(getUnit(delta), UNIT_ONE)) {
579+
errbacks.throwInvalidUnitState("relative rough equality", delta, "tolerance cannot have a unit");
580+
}
581+
ensureSameUnits(computedValue, trueValue, errbacks, where + "'s arguments");
582+
575583
if (isNegative(delta)) {
576584
errbacks.throwRelToleranceError('negative relative tolerance ' + delta)
577585
}
@@ -1177,6 +1185,8 @@ define("pyret-base/js/js-numbers", function() {
11771185
newUnit[unitName] = u[unitName];
11781186
newUnit[COUNT_FIELD] += 1;
11791187
}
1188+
1189+
if (newUnit[COUNT_FIELD] === 0) return UNIT_ONE;
11801190
return newUnit;
11811191
}
11821192

@@ -1714,32 +1724,32 @@ define("pyret-base/js/js-numbers", function() {
17141724
};
17151725

17161726
Unitnum.prototype.greaterThan = function(n, errbacks) {
1717-
ensureSameUnits(this, n, errbacks, ">");
1727+
ensureSameUnits(this, n, errbacks, "> operation");
17181728
return greaterThan(_withoutUnit(this.n), _withoutUnit(n));
17191729
};
17201730

17211731
Unitnum.prototype.greaterThanOrEqual = function(n, errbacks) {
1722-
ensureSameUnits(this, n, errbacks, ">=");
1732+
ensureSameUnits(this, n, errbacks, ">= operation");
17231733
return greaterThanOrEqual(_withoutUnit(this.n), _withoutUnit(n));
17241734
};
17251735

17261736
Unitnum.prototype.lessThan = function(n, errbacks) {
1727-
ensureSameUnits(this, n, errbacks, "<");
1737+
ensureSameUnits(this, n, errbacks, "< operation");
17281738
return lessThan(_withoutUnit(this.n), _withoutUnit(n));
17291739
};
17301740

17311741
Unitnum.prototype.lessThanOrEqual = function(n, errbacks) {
1732-
ensureSameUnits(this, n, errbacks, "<=");
1742+
ensureSameUnits(this, n, errbacks, "<= operation");
17331743
return lessThanOrEqual(_withoutUnit(this.n), _withoutUnit(n));
17341744
};
17351745

17361746
Unitnum.prototype.add = function(n, errbacks) {
1737-
ensureSameUnits(this, n, errbacks, "+");
1747+
ensureSameUnits(this, n, errbacks, "+ operation");
17381748
return _withUnit(add(_withoutUnit(this), _withoutUnit(n), errbacks), this.u, false);
17391749
};
17401750

17411751
Unitnum.prototype.subtract = function(n, errbacks) {
1742-
ensureSameUnits(this, n, errbacks, "-");
1752+
ensureSameUnits(this, n, errbacks, "- operation");
17431753
return _withUnit(subtract(_withoutUnit(this), _withoutUnit(n), errbacks), this.u, false);
17441754
};
17451755

0 commit comments

Comments
 (0)