[m-rev.] for review: Improve `integer' module interface.
Peter Wang
novalazy at gmail.com
Fri Feb 13 16:59:07 AEDT 2015
Add integer.to_int/2 which fails instead of throwing an exception if the
value cannot be represented as an `int'.
Deprecate semidet functions:
from_string/1, from_base_string/2, int/1
Add semidet predicates to replace them:
from_string/2, from_base_string/3, det_to_int/1
library/integer.m:
As above.
library/string.format.m:
Conform to changes.
NEWS:
Announce changes.
diff --git a/NEWS b/NEWS
index d3e35d8..bfa7323 100644
--- a/NEWS
+++ b/NEWS
@@ -100,6 +100,19 @@ Changes to the Mercury standard library:
- infinity/0
+* The following predicates and functions have been added to the integer module:
+
+ - from_string/2
+ - from_base_string/3
+ - to_int/2
+ - det_to_int/1
+
+ The following functions in the integer module have been deprecated:
+
+ - from_string/1
+ - from_base_string/2
+ - int/1
+
* The following predicates and functions have been added to the require module:
- error/2
diff --git a/library/integer.m b/library/integer.m
index 4312c33..eb962be 100644
--- a/library/integer.m
+++ b/library/integer.m
@@ -38,7 +38,10 @@
:- func to_string(integer) = string.
+:- pred from_string(string::in, integer::out) is semidet.
+
:- func from_string(string::in) = (integer::out) is semidet.
+:- pragma obsolete(from_string/1).
:- func det_from_string(string) = integer.
@@ -46,9 +49,12 @@
% The string must contain one or more digits in the specified base,
% optionally preceded by a plus or minus sign. For bases > 10, digits
% 10 to 35 are represented by the letters A-Z or a-z. If the string
- % does not match this syntax then the function fails.
+ % does not match this syntax then the predicate fails.
%
+:- pred from_base_string(int::in, string::in, integer::out) is semidet.
+
:- func from_base_string(int, string) = integer is semidet.
+:- pragma obsolete(from_base_string/2).
% As above but throws an exception rather than failing.
%
@@ -95,7 +101,18 @@
:- func pow(integer, integer) = integer.
:- func float(integer) = float.
+
+ % Convert an integer to an int.
+ % Fails if the integer is not in the range [min_int, max_int].
+ %
+:- pred to_int(integer::in, int::out) is semidet.
+
+ % As above but throws an exception rather than failing.
+ %
+:- func det_to_int(integer) = int.
+
:- func int(integer) = int.
+:- pragma obsolete(int/1).
:- func zero = integer.
@@ -1038,17 +1055,21 @@ float_list(_, Accum, []) = Accum.
float_list(FBase, Accum, [H | T]) =
float_list(FBase, Accum * FBase + float.float(H), T).
-integer.int(Integer) = Int :-
- (
- Integer >= integer(int.min_int),
- Integer =< integer(int.max_int)
- ->
- Integer = i(_Sign, Digits),
- Int = int_list(Digits, 0)
+integer.to_int(Integer, Int) :-
+ Integer >= integer(int.min_int),
+ Integer =< integer(int.max_int),
+ Integer = i(_Sign, Digits),
+ Int = int_list(Digits, 0).
+
+integer.det_to_int(Integer) = Int :-
+ ( integer.to_int(Integer, IntPrime) ->
+ Int = IntPrime
;
error("integer.int: domain error (conversion would overflow)")
).
+integer.int(Integer) = integer.det_to_int(Integer).
+
:- func int_list(list(int), int) = int.
int_list([], Accum) = Accum.
@@ -1064,11 +1085,14 @@ integer.one = i(1, [1]).
%
integer.from_string(S) = Big :-
+ integer.from_string(S, Big).
+
+integer.from_string(S, Big) :-
string.to_char_list(S, Cs),
string_to_integer(Cs) = Big.
integer.det_from_string(S) =
- ( I = integer.from_string(S) ->
+ ( integer.from_string(S, I) ->
I
;
func_error(
@@ -1264,6 +1288,9 @@ printbase_pos_mul_list([X|Xs], Carry, Y) =
%---------------------------------------------------------------------------%
integer.from_base_string(Base, String) = Integer :-
+ integer.from_base_string(Base, String, Integer).
+
+integer.from_base_string(Base, String, Integer) :-
string.index(String, 0, Char),
Len = string.length(String),
( Char = ('-') ->
@@ -1291,7 +1318,7 @@ accumulate_integer(Base, Char, !N) :-
!:N = (integer(Base) * !.N) + Digit.
integer.det_from_base_string(Base, String) = Integer :-
- ( Integer0 = integer.from_base_string(Base, String) ->
+ ( integer.from_base_string(Base, String, Integer0) ->
Integer = Integer0
;
error("integer.det_from_base_string")
diff --git a/library/string.format.m b/library/string.format.m
index d95e350..697d971 100644
--- a/library/string.format.m
+++ b/library/string.format.m
@@ -1084,7 +1084,7 @@ justify_string(Flags, MaybeWidth, Str) = JustifiedStr :-
%
% The input is an arbitrary precision integer because if either
%
-% - the original number is a signed int, and its value is minint, or
+% - the original number is a signed int, and its value is min_int, or
% - the original number is an unsigned int, and its value has the most
% significant bit set,
%
@@ -1102,8 +1102,8 @@ justify_string(Flags, MaybeWidth, Str) = JustifiedStr :-
abs_integer_to_octal(Num) = NumStr :-
( if Num > integer(0) then
Integer8 = integer(8),
- FrontDigitsStr = abs_int_to_octal(int(Num // Integer8)),
- LastDigitStr = get_octal_digit(int(Num rem Integer8)),
+ FrontDigitsStr = abs_int_to_octal(det_to_int(Num // Integer8)),
+ LastDigitStr = get_octal_digit(det_to_int(Num rem Integer8)),
NumStr = append(FrontDigitsStr, LastDigitStr)
else
NumStr = ""
@@ -1126,8 +1126,8 @@ abs_int_to_octal(Num) = NumStr :-
abs_integer_to_decimal(Num) = NumStr :-
( if Num > integer(0) then
Integer10 = integer(10),
- FrontDigitsStr = abs_int_to_decimal(int(Num // Integer10)),
- LastDigitStr = get_decimal_digit(int(Num rem Integer10)),
+ FrontDigitsStr = abs_int_to_decimal(det_to_int(Num // Integer10)),
+ LastDigitStr = get_decimal_digit(det_to_int(Num rem Integer10)),
NumStr = append(FrontDigitsStr, LastDigitStr)
else
NumStr = ""
@@ -1153,8 +1153,8 @@ abs_int_to_decimal(Num) = NumStr :-
abs_integer_to_hex_lc(Num) = NumStr :-
( if Num > integer(0) then
Integer16 = integer(16),
- FrontDigitsStr = abs_int_to_hex_lc(int(Num // Integer16)),
- LastDigitStr = get_hex_digit_lc(int(Num rem Integer16)),
+ FrontDigitsStr = abs_int_to_hex_lc(det_to_int(Num // Integer16)),
+ LastDigitStr = get_hex_digit_lc(det_to_int(Num rem Integer16)),
NumStr = append(FrontDigitsStr, LastDigitStr)
else
NumStr = ""
@@ -1163,8 +1163,8 @@ abs_integer_to_hex_lc(Num) = NumStr :-
abs_integer_to_hex_uc(Num) = NumStr :-
( if Num > integer(0) then
Integer16 = integer(16),
- FrontDigitsStr = abs_int_to_hex_uc(int(Num // Integer16)),
- LastDigitStr = get_hex_digit_uc(int(Num rem Integer16)),
+ FrontDigitsStr = abs_int_to_hex_uc(det_to_int(Num // Integer16)),
+ LastDigitStr = get_hex_digit_uc(det_to_int(Num rem Integer16)),
NumStr = append(FrontDigitsStr, LastDigitStr)
else
NumStr = ""
--
2.1.2
More information about the reviews
mailing list