[m-rev.] diff: fix omissions in the char module

Julien Fischer jfischer at opturion.com
Sun Aug 30 14:48:42 AEST 2015


Fix omissions in the char module.

The functions det_int_to_{binary,octal,decimal,hex)_digit/1 were supposed to
have been added at the same time as the corresponding semidet predicates but
weren't: add them.

In the char module, don't call unexpected/3 in cases where the error arises as
a result of bad inputs: throwing an exception in that case *is* expected.

library/char.m:
      As above.

NEWS:
      Announce the above additions.

samples/e.m:
      Avoid a call to an obsolete predicate and update syntax.

Julien.

diff --git a/NEWS b/NEWS
index ffcf4cd..620f672 100644
--- a/NEWS
+++ b/NEWS
@@ -62,10 +62,10 @@ Changes to the Mercury standard library:

      - is_decimal_digit/1
      - is_base_digit/2
-    - int_to_binary_digit/2
-    - int_to_octal_digit/2
-    - int_to_decimal_digit/2
-    - int_to_hex_digit/2
+    - int_to_binary_digit/2, det_int_to_binary_digit/1
+    - int_to_octal_digit/2, det_int_to_octal_digit/1
+    - int_to_decimal_digit/2, det_int_to_decimal_digit/1
+    - int_to_hex_digit/2, det_int_to_hex_digit/1
      - base_int_to_digit/3, det_base_int_to_digit/2
      - binary_digit_to_int/2, det_binary_digit_to_int/1
      - octal_digit_to_int/2, det_octal_digit_to_int/1
diff --git a/library/char.m b/library/char.m
index 67f72e3..3c93b37 100644
--- a/library/char.m
+++ b/library/char.m
@@ -166,19 +166,35 @@
      %
  :- pred int_to_binary_digit(int::in, char::out) is semidet.

+    % As above, but throw an exception instead of failing.
+    %
+:- func det_int_to_binary_digit(int) = char.
+
      % Convert an integer 0-7 to an octal digit (0-7) in the ASCII range.
      %
  :- pred int_to_octal_digit(int::in, char::out) is semidet.

+    % As above, but throw an exception instead of failing.
+    %
+:- func det_int_to_octal_digit(int) = char.
+
      % Convert an integer 0-9 to a decimal digit (0-9) in the ASCII range.
      %
  :- pred int_to_decimal_digit(int::in, char::out) is semidet.

+    % As above, but throw an exception in instead of failing.
+    %
+:- func det_int_to_decimal_digit(int) = char.
+
      % Convert an integer 0-15 to an uppercase hexadecimal digit (0-9, A-F) in
      % the ASCII range.
      %
  :- pred int_to_hex_digit(int::in, char::out) is semidet.

+    % As above, but throw an exception in instead of failing.
+    %
+:- func det_int_to_hex_digit(int) = char.
+
      % base_int_to_digit(Base, Int, Char):
      % True iff Char is a decimal digit (0-9) or an uppercase letter (A-Z)
      % representing the value Int (0-35) in the given base.
@@ -547,7 +563,7 @@ is_base_digit(Base, Digit) :-
      ( if 2 =< Base, Base =< 36 then
          base_digit_to_int(Base, Digit, _Int)
      else
-        unexpected($module, $pred, "char.is_base_digit: invalid base")
+        error("char.is_base_digit: invalid base")
      ).

  %---------------------------------------------------------------------------%
@@ -562,7 +578,7 @@ det_binary_digit_to_int(Digit) = Int :-
      ( if binary_digit_to_int(Digit, IntPrime) then
          Int = IntPrime
      else
-        unexpected($module, $pred, "char.binary_digit_to_int failed")
+        error("char.binary_digit_to_int failed")
      ).

  octal_digit_to_int('0', 0).
@@ -578,7 +594,7 @@ det_octal_digit_to_int(Digit) = Int :-
      ( if octal_digit_to_int(Digit, IntPrime) then
          Int = IntPrime
      else
-        unexpected($module, $pred, "char.octal_digit_to_int failed")
+        error("char.octal_digit_to_int failed")
      ).

  decimal_digit_to_int('0', 0).
@@ -596,7 +612,7 @@ det_decimal_digit_to_int(Digit) = Int :-
      ( if decimal_digit_to_int(Digit, IntPrime) then
          Int = IntPrime
      else
-        unexpected($module, $pred, "char.decimal_digit_to_int failed")
+        error("char.decimal_digit_to_int failed")
      ).

  is_hex_digit(Digit, Int) :-
@@ -629,7 +645,7 @@ det_hex_digit_to_int(Digit) = Int :-
      ( if hex_digit_to_int(Digit, IntPrime) then
          Int = IntPrime
      else
-        unexpected($module, $pred, "char.hex_digit_to_int failed")
+        error("char.hex_digit_to_int failed")
      ).

  base_digit_to_int(Base, Digit, Int) :-
@@ -641,14 +657,14 @@ base_digit_to_int(Base, Digit, Int) :-
          ),
          Int < Base
      else
-        unexpected($module, $pred, "char.base_digit_to_int: invalid base")
+        error("char.base_digit_to_int: invalid base")
      ).

  det_base_digit_to_int(Base, Digit) = Int :-
      ( if base_digit_to_int(Base, Digit, IntPrime) then
          Int = IntPrime
      else
-        unexpected($module, $pred, "char.base_digit_to_int failed")
+        error("char.base_digit_to_int failed")
      ).

  %---------------------------------------------------------------------------%
@@ -659,6 +675,13 @@ det_base_digit_to_int(Base, Digit) = Int :-
  int_to_binary_digit(0, '0').
  int_to_binary_digit(1, '1').

+det_int_to_binary_digit(Int) = Digit :-
+    ( if int_to_binary_digit(Int, DigitPrime) then
+        Digit = DigitPrime
+    else
+        error("char.int_to_binary_digit failed")
+    ).
+
  int_to_octal_digit(0, '0').
  int_to_octal_digit(1, '1').
  int_to_octal_digit(2, '2').
@@ -668,6 +691,13 @@ int_to_octal_digit(5, '5').
  int_to_octal_digit(6, '6').
  int_to_octal_digit(7, '7').

+det_int_to_octal_digit(Int) = Digit :-
+    ( if int_to_octal_digit(Int, DigitPrime) then
+        Digit = DigitPrime
+    else
+        error("char.int_to_octal_digit failed")
+    ).
+
  int_to_decimal_digit(0, '0').
  int_to_decimal_digit(1, '1').
  int_to_decimal_digit(2, '2').
@@ -679,6 +709,13 @@ int_to_decimal_digit(7, '7').
  int_to_decimal_digit(8, '8').
  int_to_decimal_digit(9, '9').

+det_int_to_decimal_digit(Int) = Digit :-
+    ( if int_to_decimal_digit(Int, DigitPrime) then
+        Digit = DigitPrime
+    else
+        error("char.int_to_decimal_digit failed")
+    ).
+
  int_to_hex_digit(0, '0').
  int_to_hex_digit(1, '1').
  int_to_hex_digit(2, '2').
@@ -696,6 +733,13 @@ int_to_hex_digit(13, 'D').
  int_to_hex_digit(14, 'E').
  int_to_hex_digit(15, 'F').

+det_int_to_hex_digit(Int) = Digit :-
+    ( if int_to_hex_digit(Int, DigitPrime) then
+        Digit = DigitPrime
+    else
+        error("char.int_to_hex_digit failed")
+    ).
+
  int_to_hex_char(Int, Char) :-
      int_to_hex_digit(Int, Char).

@@ -704,14 +748,14 @@ base_int_to_digit(Base, Int, Digit) :-
          Int < Base,
          int_to_extended_digit(Int, Digit)
      else
-        unexpected($module, $pred, "char.base_int_to_digit: invalid base")
+        error("char.base_int_to_digit: invalid base")
      ).

  det_base_int_to_digit(Base, Int) = Digit :-
      ( if base_int_to_digit(Base, Int, DigitPrime) then
          Digit = DigitPrime
      else
-        unexpected($module, $pred, "char.base_int_to_digit failed")
+        error("char.base_int_to_digit failed")
      ).

  %---------------------------------------------------------------------------%
@@ -723,7 +767,7 @@ det_int_to_digit(Int, Digit) :-
      ( if int_to_extended_digit(Int, DigitPrime) then
          Digit = DigitPrime
      else
-        unexpected($module, $pred, "char.int_to_digit failed")
+        error("char.int_to_digit failed")
      ).

  :- pred int_to_extended_digit(int, char).
diff --git a/samples/e.m b/samples/e.m
index c0a783c..b1640c9 100644
--- a/samples/e.m
+++ b/samples/e.m
@@ -56,7 +56,7 @@ columns = 78.
      %
  :- type int_stream
      --->    [int | int_stream]
-    ;   closure((func) = int_stream).
+    ;       closure((func) = int_stream).

  :- inst int_stream ==
      bound([ground | int_stream] ; closure((func) = is_out is det)).
@@ -67,13 +67,13 @@ columns = 78.
  %-----------------------------------------------------------------------------%

      % An infinite stream of ones.
-    % 
+    %
  :- func ones = (int_stream :: is_out) is det.

  ones = [1 | closure((func) = ones)].

      % All the digits of e in one stream.
-    % 
+    %
  :- func digits_of_e = (int_stream :: is_out) is det.

  digits_of_e = next_digit(ones).
@@ -90,7 +90,7 @@ scale(C, Digit, closure(Func), Stream) :-
  scale(C, Digit, [D | Ds], Stream) :-
      K = base * D,
      KdC = K // C,
-    ( KdC = (K + base - 1) // C ->
+    ( if KdC = (K + base - 1) // C then
          % We have the next digit.  Construct a closure to
          % generate the rest.

@@ -98,7 +98,7 @@ scale(C, Digit, [D | Ds], Stream) :-
          Stream = closure((func) = [K rem C + NextDigit | Stream0] :-
                  scale(C + 1, NextDigit, Ds, Stream0)
              )
-    ;
+    else
          % We have a carry to factor in, so calculate the next
          % digit eagerly then add it on.

@@ -112,12 +112,12 @@ scale(C, Digit, [D | Ds], Stream) :-

  main(!IO) :-
      io.command_line_arguments(Args, !IO),
-    (
+    ( if
          Args = [Arg | _],
          string.to_int(Arg, Digits0)
-    ->
+    then
          Digits = Digits0
-    ;
+    else
          Digits = default_digits
      ),
      string.int_to_base_string(2, base, BaseString),
@@ -127,19 +127,19 @@ main(!IO) :-
      io.nl(!IO).

      % Print out digits until we don't have any more.
-    % 
+    %
  :- pred main_2(int::in, int::in, int_stream::is_in, io::di, io::uo) is det.

-main_2(Digits, Columns, closure(Func), !IO) :- 
+main_2(Digits, Columns, closure(Func), !IO) :-
      main_2(Digits, Columns, apply(Func), !IO).
  main_2(Digits, Columns, [I | Is], !IO) :-
-    ( Digits = 0 ->
+    ( if Digits = 0 then
          true
-    ; Columns = 0 ->
+    else if Columns = 0 then
          io.nl(!IO),
          main_2(Digits, columns, [I | Is], !IO)
-    ;
-        char.det_int_to_digit(I, Digit),
+    else
+        Digit = char.det_int_to_decimal_digit(I),
          io.write_char(Digit, !IO),
          main_2(Digits - 1, Columns - 1, Is, !IO)
      ).



More information about the reviews mailing list