[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