[m-rev.] diff: error checking for `int__rem/2'
Simon Taylor
stayl at cs.mu.OZ.AU
Sun Nov 4 04:36:00 AEDT 2001
Estimated hours taken: 0.25
library/int.m:
Add a clause for `int__rem/2' which throws an exception if
the right operand is zero.
Add declarations for the `int__unchecked_rem/2', which
does not perform any checking.
compiler/builtin_ops.m:
`int__rem/2' is no longer a builtin.
compiler/const_prop.m:
Handle `int__unchecked_rem/2'.
NEWS:
Document the changes.
Index: NEWS
===================================================================
RCS file: /home/mercury1/repository/mercury/NEWS,v
retrieving revision 1.222
diff -u -u -r1.222 NEWS
--- NEWS 26 Oct 2001 07:55:44 -0000 1.222
+++ NEWS 3 Nov 2001 17:31:16 -0000
@@ -49,7 +49,10 @@
* The predicates and functions in int.m, float, math.m and array.m now
generate exceptions rather than program aborts on domain errors and
- out-of-bounds array accesses.
+ out-of-bounds array accesses. There are new functions
+ `float__unchecked_quotient/2', `int__unchecked_quotient/2' and
+ `int__unchecked_rem/2' for which no checking is performed and the
+ behaviour if the right operand is zero is undefined.
* We've removed the buggy reverse modes of the arithmetic functions in
float.m and extras/complex_numbers (because of rounding errors the
Index: compiler/builtin_ops.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/builtin_ops.m,v
retrieving revision 1.9
diff -u -u -r1.9 builtin_ops.m
--- compiler/builtin_ops.m 24 Oct 2001 06:51:06 -0000 1.9
+++ compiler/builtin_ops.m 3 Nov 2001 16:16:47 -0000
@@ -191,8 +191,6 @@
assign(Z, binary((*), leaf(X), leaf(Y)))).
builtin_translation("int", "unchecked_quotient", 0, [X, Y, Z],
assign(Z, binary((/), leaf(X), leaf(Y)))).
-builtin_translation("int", "rem", 0, [X, Y, Z],
- assign(Z, binary((mod), leaf(X), leaf(Y)))).
builtin_translation("int", "unchecked_rem", 0, [X, Y, Z],
assign(Z, binary((mod), leaf(X), leaf(Y)))).
builtin_translation("int", "unchecked_left_shift", 0, [X, Y, Z],
Index: compiler/const_prop.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/const_prop.m,v
retrieving revision 1.12
diff -u -u -r1.12 const_prop.m
--- compiler/const_prop.m 2 Sep 2001 16:39:29 -0000 1.12
+++ compiler/const_prop.m 3 Nov 2001 16:57:04 -0000
@@ -186,11 +186,18 @@
YVal \= 0,
ZVal is XVal mod YVal.
+ % This isn't actually a builtin.
evaluate_builtin_tri("int", "rem", 0, X, Y, Z, Z, int_const(ZVal)) :-
X = _XVar - bound(_XUniq, [functor(int_const(XVal), [])]),
Y = _YVar - bound(_YUniq, [functor(int_const(YVal), [])]),
YVal \= 0,
ZVal is XVal rem YVal.
+
+evaluate_builtin_tri("int", "unchecked_rem", 0, X, Y, Z, Z, int_const(ZVal)) :-
+ X = _XVar - bound(_XUniq, [functor(int_const(XVal), [])]),
+ Y = _YVar - bound(_YUniq, [functor(int_const(YVal), [])]),
+ YVal \= 0,
+ ZVal is unchecked_rem(XVal, YVal).
evaluate_builtin_tri("int", "unchecked_left_shift",
0, X, Y, Z, Z, int_const(ZVal)) :-
Index: library/int.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/int.m,v
retrieving revision 1.78
diff -u -u -r1.78 int.m
--- library/int.m 17 Oct 2001 05:10:36 -0000 1.78
+++ library/int.m 3 Nov 2001 16:15:38 -0000
@@ -133,9 +133,18 @@
% X rem Y = X - (X // Y) * Y
% `mod' has nicer mathematical properties for negative X,
% but `rem' is typically more efficient.
+ %
+ % Throws a `math__domain_error' exception if the right operand
+ % is zero. See the comments at the top of math.m to find out how to
+ % disable domain checks.
:- func int rem int = int.
:- mode in rem in = uo is det.
+ % unchecked_rem(X, Y) is the same as X rem Y, but the
+ % behaviour is undefined if the right operand is zero.
+:- func unchecked_rem(int, int) = int.
+:- mode unchecked_rem(in, in) = uo is det.
+
% Left shift.
% X << Y returns X "left shifted" by Y bits.
% To be precise, if Y is negative, the result is
@@ -292,11 +301,21 @@
Div = unchecked_quotient(X, Y)
).
+% XXX uncomment this line when the change to make `rem' a non-builtin
+% is installed everywhere.
+%:- pragma inline(rem/2).
+X rem Y = Rem :-
+ ( domain_checks, Y = 0 ->
+ throw(math__domain_error("int:rem"))
+ ;
+ Rem = unchecked_rem(X, Y)
+ ).
+
% This code is included here rather than just calling
% the version in math.m because we currently don't do
% transitive inter-module inlining, so code which uses
% `//'/2 but doesn't import math.m couldn't have the
- % domain check optimized away..
+ % domain check optimized away.
:- pred domain_checks is semidet.
:- pragma inline(domain_checks/0).
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list