[m-rev.] for post-commit review: implement compile time evaluation for uint operations

Julien Fischer jfischer at opturion.com
Sun May 14 02:36:18 AEST 2017


For post-commit review by anyone.

Implement compile time evaluation for uint operations.

compiler/const_prop.m:
     Extend this module to support compile time evaluation of uint operations.

compiler/uint_emu.m:
     A new module that emulates `uint' operations for the bits-per-uint in
     a manner similar to the int_emu module.

compiler/libs.m:
     Include the new module.

tests/hard_coded/constant_prop_1.{m,exp}:
tests/hard_coded/constant_prop_2.{m,exp}:
     Test compile time evaluation of uint operations.

     Update coding style in these tests.

tests/hard_coded/Mmakefile:
     Conform to the above changes.  (XXX the existing check
     for the Java grade doesn't actually work.)

     Delete left over IL and GCC backend stuff.

Julien.

diff --git a/compiler/const_prop.m b/compiler/const_prop.m
index e878a2ed7..3c6bb26c7 100644
--- a/compiler/const_prop.m
+++ b/compiler/const_prop.m
@@ -52,6 +52,7 @@
  :- import_module hlds.make_goal.
  :- import_module libs.int_emu.
  :- import_module libs.options.
+:- import_module libs.uint_emu.

  :- import_module bool.
  :- import_module float.
@@ -59,6 +60,7 @@
  :- import_module maybe.
  :- import_module pair.
  :- import_module string.
+:- import_module uint.

  %---------------------------------------------------------------------------%

@@ -149,6 +151,10 @@ evaluate_det_call(Globals, ModuleName, ProcName, ModeNum, Args,
              ModuleName = "int",
              evaluate_det_call_int_1(Globals, ProcName, ModeNum, X,
                  OutputArg, OutputArgVal)
+        ;
+            ModuleName = "uint",
+            evaluate_det_call_uint_1(Globals, ProcName, ModeNum, X,
+                OutputArg, OutputArgVal)
          )
      ;
          Args = [X, Y],
@@ -158,6 +164,10 @@ evaluate_det_call(Globals, ModuleName, ProcName, ModeNum, Args,
              evaluate_det_call_int_2(Globals, ProcName, ModeNum, X, Y,
                  OutputArg, OutputArgVal)
          ;
+            ModuleName = "uint",
+            evaluate_det_call_uint_2(Globals, ProcName, ModeNum, X, Y,
+                OutputArg, OutputArgVal)
+        ;
              ModuleName = "float",
              evaluate_det_call_float_2(Globals, ProcName, ModeNum, X, Y,
                  OutputArg, OutputArgVal)
@@ -174,6 +184,10 @@ evaluate_det_call(Globals, ModuleName, ProcName, ModeNum, Args,
              evaluate_det_call_int_3(Globals, ProcName, ModeNum, X, Y, Z,
                  OutputArg, OutputArgVal)
          ;
+            ModuleName = "uint",
+            evaluate_det_call_uint_3(Globals, ProcName, ModeNum, X, Y ,Z,
+                OutputArg, OutputArgVal)
+        ;
              ModuleName = "float",
              evaluate_det_call_float_3(Globals, ProcName, ModeNum, X, Y, Z,
                  OutputArg, OutputArgVal)
@@ -197,6 +211,20 @@ evaluate_det_call_int_1(Globals, ProcName, ModeNum, X,
          target_bits_per_int(Globals, bits_per_int(OutputArgVal))
      ).

+:- pred evaluate_det_call_uint_1(globals::in, string::in, int::in,
+    arg_hlds_info::in, arg_hlds_info::out, cons_id::out) is semidet.
+
+evaluate_det_call_uint_1(Globals, ProcName, ModeNum, X, OutputArg, ConsId) :-
+    (
+        ProcName = "bits_per_uint",
+        ModeNum = 0,
+        OutputArg = X,
+        globals.lookup_bool_option(Globals, pregenerated_dist, no),
+        target_bits_per_uint(Globals, bits_per_uint(OutputArgVal)),
+        % NOTE: this returns an int not a uint.
+        ConsId = int_const(OutputArgVal)
+    ).
+
  :- pred evaluate_det_call_int_2(globals::in, string::in, int::in,
      arg_hlds_info::in, arg_hlds_info::in, arg_hlds_info::out, cons_id::out)
      is semidet.
@@ -258,6 +286,20 @@ evaluate_det_call_int_2(Globals, ProcName, ModeNum, X, Y,
          int_emu.rem_bits_per_int(XVal, BitsPerInt, OutputArgVal)
      ).

+:- pred evaluate_det_call_uint_2(globals::in, string::in, int::in,
+    arg_hlds_info::in, arg_hlds_info::in, arg_hlds_info::out, cons_id::out)
+    is semidet.
+
+evaluate_det_call_uint_2(_Globals, ProcName, ModeNum, X, Y,
+        OutputArg, uint_const(OutputArgVal)) :-
+    (
+        ProcName = "\\",
+        ModeNum = 0,
+        X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+        OutputArg = Y,
+        OutputArgVal = \ XVal
+    ).
+
  :- pred evaluate_det_call_float_2(globals::in, string::in, int::in,
      arg_hlds_info::in, arg_hlds_info::in, arg_hlds_info::out, cons_id::out)
      is semidet.
@@ -496,6 +538,174 @@ evaluate_det_call_int_3(Globals, ProcName, ModeNum, X, Y, Z,
          OutputArgVal = xor(XVal, YVal)
      ).

+:- pred evaluate_det_call_uint_3(globals::in, string::in, int::in,
+    arg_hlds_info::in, arg_hlds_info::in, arg_hlds_info::in,
+    arg_hlds_info::out, cons_id::out) is semidet.
+
+evaluate_det_call_uint_3(Globals, ProcName, ModeNum, X, Y, Z,
+        OutputArg, uint_const(OutputArgVal)) :-
+    (
+        ProcName = "+",
+        ModeNum = 0,
+        X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+        Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
+        OutputArg = Z,
+        globals.lookup_bool_option(Globals, pregenerated_dist, no),
+        uint_emu.target_bits_per_uint(Globals, BitsPerUInt),
+        uint_emu.plus(BitsPerUInt, XVal, YVal, OutputArgVal)
+    ;
+        ProcName = "+",
+        ModeNum = 1,
+        Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
+        Z ^ arg_inst = bound(_, _, [bound_functor(uint_const(ZVal), [])]),
+        OutputArg = X,
+        globals.lookup_bool_option(Globals, pregenerated_dist, no),
+        uint_emu.target_bits_per_uint(Globals, BitsPerUInt),
+        uint_emu.minus(BitsPerUInt, ZVal, YVal, OutputArgVal)
+    ;
+        ProcName = "+",
+        ModeNum = 2,
+        X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+        Z ^ arg_inst = bound(_, _, [bound_functor(uint_const(ZVal), [])]),
+        OutputArg = Y,
+        globals.lookup_bool_option(Globals, pregenerated_dist, no),
+        uint_emu.target_bits_per_uint(Globals, BitsPerUInt),
+        uint_emu.minus(BitsPerUInt, ZVal, XVal, OutputArgVal)
+    ;
+        ProcName = "-",
+        ModeNum = 0,
+        X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+        Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
+        OutputArg = Z,
+        globals.lookup_bool_option(Globals, pregenerated_dist, no),
+        uint_emu.target_bits_per_uint(Globals, BitsPerUInt),
+        uint_emu.minus(BitsPerUInt, XVal, YVal, OutputArgVal)
+    ;
+        ProcName = "-",
+        ModeNum = 1,
+        Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
+        Z ^ arg_inst = bound(_, _, [bound_functor(uint_const(ZVal), [])]),
+        OutputArg = X,
+        globals.lookup_bool_option(Globals, pregenerated_dist, no),
+        uint_emu.target_bits_per_uint(Globals, BitsPerUInt),
+        uint_emu.plus(BitsPerUInt, YVal, ZVal, OutputArgVal)
+    ;
+        ProcName = "-",
+        ModeNum = 2,
+        X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+        Z ^ arg_inst = bound(_, _, [bound_functor(uint_const(ZVal), [])]),
+        OutputArg = Y,
+        globals.lookup_bool_option(Globals, pregenerated_dist, no),
+        uint_emu.target_bits_per_uint(Globals, BitsPerUInt),
+        uint_emu.minus(BitsPerUInt, XVal, ZVal, OutputArgVal)
+    ;
+        ProcName = "*",
+        ModeNum = 0,
+        X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+        Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
+        OutputArg = Z,
+        globals.lookup_bool_option(Globals, pregenerated_dist, no),
+        uint_emu.target_bits_per_uint(Globals, BitsPerUInt),
+        uint_emu.times(BitsPerUInt, XVal, YVal, OutputArgVal)
+    ;
+        ProcName = "//",
+        ModeNum = 0,
+        X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+        Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
+        YVal \= cast_from_int(0),
+        OutputArg = Z,
+        globals.lookup_bool_option(Globals, pregenerated_dist, no),
+        uint_emu.target_bits_per_uint(Globals, BitsPerUInt),
+        uint_emu.quotient(BitsPerUInt, XVal, YVal, OutputArgVal)
+    ;
+        ProcName = "mod",
+        ModeNum = 0,
+        X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+        Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
+        YVal \= cast_from_int(0),
+        OutputArg = Z,
+        globals.lookup_bool_option(Globals, pregenerated_dist, no),
+        uint_emu.target_bits_per_uint(Globals, BitsPerUInt),
+        uint_emu.mod(BitsPerUInt, XVal, YVal, OutputArgVal)
+    ;
+        ProcName = "rem",
+        ModeNum = 0,
+        X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+        Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
+        YVal \= cast_from_int(0),
+        OutputArg = Z,
+        globals.lookup_bool_option(Globals, pregenerated_dist, no),
+        uint_emu.target_bits_per_uint(Globals, BitsPerUInt),
+        uint_emu.rem(BitsPerUInt, XVal, YVal, OutputArgVal)
+    ;
+        ProcName = "unchecked_rem",
+        ModeNum = 0,
+        X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+        Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
+        YVal \= cast_from_int(0),
+        OutputArg = Z,
+        globals.lookup_bool_option(Globals, pregenerated_dist, no),
+        uint_emu.target_bits_per_uint(Globals, BitsPerUInt),
+        uint_emu.unchecked_rem(BitsPerUInt, XVal, YVal, OutputArgVal)
+    ;
+        ProcName = "unchecked_left_shift",
+        ModeNum = 0,
+        X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+        Y ^ arg_inst = bound(_, _, [bound_functor(int_const(YVal), [])]),
+        OutputArg = Z,
+        globals.lookup_bool_option(Globals, pregenerated_dist, no),
+        uint_emu.target_bits_per_uint(Globals, BitsPerUInt),
+        uint_emu.unchecked_left_shift(BitsPerUInt, XVal, YVal, OutputArgVal)
+    ;
+        ProcName = "<<",
+        ModeNum = 0,
+        X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+        Y ^ arg_inst = bound(_, _, [bound_functor(int_const(YVal), [])]),
+        OutputArg = Z,
+        globals.lookup_bool_option(Globals, pregenerated_dist, no),
+        uint_emu.target_bits_per_uint(Globals, BitsPerUInt),
+        uint_emu.left_shift(BitsPerUInt, XVal, YVal, OutputArgVal)
+    ;
+        ProcName = "unchecked_right_shift",
+        ModeNum = 0,
+        X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+        Y ^ arg_inst = bound(_, _, [bound_functor(int_const(YVal), [])]),
+        OutputArg = Z,
+        globals.lookup_bool_option(Globals, pregenerated_dist, no),
+        uint_emu.target_bits_per_uint(Globals, BitsPerUInt),
+        uint_emu.unchecked_right_shift(BitsPerUInt, XVal, YVal, OutputArgVal)
+    ;
+        ProcName = ">>",
+        ModeNum = 0,
+        X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+        Y ^ arg_inst = bound(_, _, [bound_functor(int_const(YVal), [])]),
+        OutputArg = Z,
+        globals.lookup_bool_option(Globals, pregenerated_dist, no),
+        uint_emu.target_bits_per_uint(Globals, BitsPerUInt),
+        uint_emu.right_shift(BitsPerUInt, XVal, YVal, OutputArgVal)
+    ;
+        ProcName = "/\\",
+        ModeNum = 0,
+        X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+        Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
+        OutputArg = Z,
+        OutputArgVal = XVal /\ YVal
+    ;
+        ProcName = "\\/",
+        ModeNum = 0,
+        X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+        Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
+        OutputArg = Z,
+        OutputArgVal = XVal \/ YVal
+    ;
+        ProcName = "xor",
+        ModeNum = 0,
+        X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+        Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
+        OutputArg = Z,
+        OutputArgVal = xor(XVal, YVal)
+    ).
+
  :- pred evaluate_det_call_float_3(globals::in, string::in, int::in,
      arg_hlds_info::in, arg_hlds_info::in, arg_hlds_info::in,
      arg_hlds_info::out, cons_id::out) is semidet.
@@ -615,6 +825,45 @@ evaluate_test("int", ">=", 0, Args, Result) :-
          Result = no
      ).

+    % Unsigned integer comparisons.
+
+evaluate_test("uint", "<", 0, Args, Result) :-
+    Args = [X, Y],
+    X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+    Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
+    ( if XVal < YVal then
+        Result = yes
+    else
+        Result = no
+    ).
+evaluate_test("uint", "=<", 0, Args, Result) :-
+    Args = [X, Y],
+    X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+    Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
+    ( if XVal =< YVal then
+        Result = yes
+    else
+        Result = no
+    ).
+evaluate_test("uint", ">", 0, Args, Result) :-
+    Args = [X, Y],
+    X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+    Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
+    ( if XVal > YVal then
+        Result = yes
+    else
+        Result = no
+    ).
+evaluate_test("uint", ">=", 0, Args, Result) :-
+    Args = [X, Y],
+    X ^ arg_inst = bound(_, _, [bound_functor(uint_const(XVal), [])]),
+    Y ^ arg_inst = bound(_, _, [bound_functor(uint_const(YVal), [])]),
+    ( if XVal >= YVal then
+        Result = yes
+    else
+        Result = no
+    ).
+
      % Float comparisons

  evaluate_test("float", "<", 0, Args, Result) :-
diff --git a/compiler/libs.m b/compiler/libs.m
index c7d56cabb..7e4c4f305 100644
--- a/compiler/libs.m
+++ b/compiler/libs.m
@@ -32,6 +32,7 @@
  :- include_module int_emu.
  :- include_module md4.
  :- include_module pickle.
+:- include_module uint_emu.

  % OS interfaces not provided by the standard library.
  :- include_module process_util.
diff --git a/compiler/uint_emu.m b/compiler/uint_emu.m
index e69de29bb..aa5dc6dd8 100644
--- a/compiler/uint_emu.m
+++ b/compiler/uint_emu.m
@@ -0,0 +1,149 @@
+%----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%----------------------------------------------------------------------------%
+% Copyright (C) 2017 The Mercury team.
+% This file may only be copied under the terms of the GNU General
+% Public License - see the file COPYING in the Mercury distribution.
+%----------------------------------------------------------------------------%
+%
+% File: uint_emu.m.
+% Main author: juliensf.
+%
+% Emulate `uint' operations for a given number of bits per int. These
+% predicates succeed only if the result is defined for the given arguments, and
+% the result can be represented by the `uint' type of the host compiler.
+%
+%----------------------------------------------------------------------------%
+
+:- module libs.uint_emu.
+:- interface.
+
+:- import_module libs.globals.
+
+%----------------------------------------------------------------------------%
+
+:- type bits_per_uint
+    --->    bits_per_uint(int).
+
+    % Return the number of bits per int for the selected compilation target.
+    %
+:- pred target_bits_per_uint(globals::in, bits_per_uint::out) is det.
+
+%----------------------------------------------------------------------------%
+
+:- pred plus(bits_per_uint::in, uint::in, uint::in, uint::out) is semidet.
+
+:- pred minus(bits_per_uint::in, uint::in, uint::in, uint::out) is semidet.
+
+:- pred times(bits_per_uint::in, uint::in, uint::in, uint::out) is semidet.
+
+:- pred quotient(bits_per_uint::in, uint::in, uint::in, uint::out) is semidet.
+
+:- pred unchecked_quotient(bits_per_uint::in, uint::in, uint::in, uint::out)
+    is semidet.
+
+:- pred mod(bits_per_uint::in, uint::in, uint::in, uint::out) is semidet.
+
+:- pred rem(bits_per_uint::in, uint::in, uint::in, uint::out) is semidet.
+
+:- pred unchecked_rem(bits_per_uint::in, uint::in, uint::in, uint::out)
+    is semidet.
+
+:- pred left_shift(bits_per_uint::in, uint::in, int::in, uint::out) is semidet.
+
+:- pred unchecked_left_shift(bits_per_uint::in, uint::in, int::in, uint::out)
+    is semidet.
+
+:- pred right_shift(bits_per_uint::in, uint::in, int::in, uint::out) is semidet.
+
+:- pred unchecked_right_shift(bits_per_uint::in, uint::in, int::in, uint::out)
+    is semidet.
+
+%----------------------------------------------------------------------------%
+%----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module int.
+:- import_module integer.
+:- import_module uint.
+
+:- import_module libs.options.
+
+%----------------------------------------------------------------------------%
+
+target_bits_per_uint(Globals, bits_per_uint(BitsPerUInt)) :-
+    globals.get_target(Globals, Target),
+    (
+        Target = target_c,
+        globals.lookup_int_option(Globals, bits_per_word, BitsPerUInt)
+    ;
+        ( Target = target_csharp
+        ; Target = target_java
+        ; Target = target_erlang
+        ),
+        BitsPerUInt = 32
+    ).
+
+%----------------------------------------------------------------------------%
+
+plus(BitsPerUInt, X, Y, Z) :-
+    to_uint_in_range(BitsPerUInt, integer.from_uint(X) + integer.from_uint(Y),
+        Z).
+
+minus(BitsPerUInt, X, Y, Z) :-
+    to_uint_in_range(BitsPerUInt, integer.from_uint(X) - integer.from_uint(Y),
+        Z).
+
+times(BitsPerUInt, X, Y, Z) :-
+    to_uint_in_range(BitsPerUInt, integer.from_uint(X) * integer.from_uint(Y),
+        Z).
+
+quotient(BitsPerUInt, X, Y, Z) :-
+    to_uint_in_range(BitsPerUInt, integer.from_uint(X) // integer.from_uint(Y),
+        Z).
+
+unchecked_quotient(BitsPerUInt, X, Y, Z) :-
+    Y \= cast_from_int(0),
+    quotient(BitsPerUInt, X, Y, Z).
+
+mod(BitsPerUInt, X, Y, Z) :-
+    to_uint_in_range(BitsPerUInt, integer.from_uint(X) mod integer.from_uint(Y),
+        Z).
+
+rem(BitsPerUInt, X, Y, Z) :-
+    to_uint_in_range(BitsPerUInt, integer.from_uint(X) rem integer.from_uint(Y),
+        Z).
+
+unchecked_rem(BitsPerUInt, X, Y, Z) :-
+    Y \= cast_from_int(0),
+    rem(BitsPerUInt, X, Y, Z).
+
+left_shift(BitsPerUInt, X, Y, Z) :-
+    BitsPerUInt = bits_per_uint(N),
+    Y >= 0,
+    Y < N,
+    to_uint_in_range(BitsPerUInt, integer.from_uint(X) << Y, Z).
+
+unchecked_left_shift(BitsPerUInt, X, Y, Z) :-
+    left_shift(BitsPerUInt, X, Y, Z).
+
+right_shift(BitsPerUInt, X, Y, Z) :-
+    BitsPerUInt = bits_per_uint(N),
+    Y >= 0,
+    Y < N,
+    to_uint_in_range(BitsPerUInt, integer.from_uint(X) >> Y, Z).
+
+unchecked_right_shift(BitsPerUInt, X, Y, Z) :-
+    right_shift(BitsPerUInt, X, Y, Z).
+
+:- pred to_uint_in_range(bits_per_uint::in, integer::in, uint::out) is semidet.
+
+to_uint_in_range(bits_per_uint(BitsPerUInt), Integer, UInt) :-
+    Integer >= integer.zero,
+    Integer =< pow(integer(2), integer(BitsPerUInt)),
+    integer.to_uint(Integer, UInt).
+
+%----------------------------------------------------------------------------%
+:- end_module libs.uint_emu.
+%----------------------------------------------------------------------------%
diff --git a/tests/hard_coded/Mmakefile b/tests/hard_coded/Mmakefile
index 5643d7cde..f145d7f2d 100644
--- a/tests/hard_coded/Mmakefile
+++ b/tests/hard_coded/Mmakefile
@@ -899,22 +899,12 @@ constant_prop_1.c: constant_prop_1.c_date
  	grep foobar $@
  	grep 1234 $@
  	grep '5678\.0' $@
-constant_prop_1.s: constant_prop_1.s_date
-	grep foobar $@
-	grep 1234 $@
-	grep '5678\.0' $@
-constant_prop_1.pic_s: constant_prop_1.pic_s_date
-	grep foobar $@
-	grep 1234 $@
-	grep '5678\.0' $@
+	grep 2468U $@
  constant_prop_1.java: constant_prop_1.java_date
  	grep foobar $@
  	grep 1234 $@
  	grep '5678\.0' $@
-constant_prop_1.il: constant_prop_1.il_date
-	grep foobar $@
-	grep 1234 $@
-	grep '5678\.0' $@
+	grep 2468 $@

  # Force intermod_unused_args2.m to be compiled and analysed before
  # intermod_unused_args.m.
diff --git a/tests/hard_coded/constant_prop_1.exp b/tests/hard_coded/constant_prop_1.exp
index 6aebe660e..78ca25537 100644
--- a/tests/hard_coded/constant_prop_1.exp
+++ b/tests/hard_coded/constant_prop_1.exp
@@ -1,3 +1,4 @@
  foobar
  1234
  5678.0
+2468
diff --git a/tests/hard_coded/constant_prop_1.m b/tests/hard_coded/constant_prop_1.m
index bee77ee1b..2ce3bb536 100644
--- a/tests/hard_coded/constant_prop_1.m
+++ b/tests/hard_coded/constant_prop_1.m
@@ -1,7 +1,7 @@
  %---------------------------------------------------------------------------%
  % vim: ts=4 sw=4 et ft=mercury
  %---------------------------------------------------------------------------%
-%
+
  :- module constant_prop_1.
  :- interface.
  :- import_module io.
@@ -13,8 +13,10 @@
  :- import_module int.
  :- import_module float.
  :- import_module string.
+:- import_module uint.

-main -->
-    io.write_string("foo" ++ "bar"), io.nl,
-    io.write_int(1 * 1000 + 2 * 100 + 3 * 10 + 4), io.nl,
-    io.write_float(5.0 * 1000.0 + 6.0 * 100.0 + 7.0 * 10.0 + 8.0), io.nl.
+main(!IO) :-
+    io.write_string("foo" ++ "bar", !IO), io.nl(!IO),
+    io.write_int(1 * 1000 + 2 * 100 + 3 * 10 + 4, !IO), io.nl(!IO),
+    io.write_float(5.0 * 1000.0 + 6.0 * 100.0 + 7.0 * 10.0 + 8.0, !IO), io.nl(!IO),
+    io.write_uint(2u * 1000u + 4u * 100u + 6u * 10u + 8u, !IO), io.nl(!IO).
diff --git a/tests/hard_coded/constant_prop_2.exp b/tests/hard_coded/constant_prop_2.exp
index bbee0e1a4..bbddadb49 100644
--- a/tests/hard_coded/constant_prop_2.exp
+++ b/tests/hard_coded/constant_prop_2.exp
@@ -2,6 +2,7 @@ yes
  yes
  yes
  yes
+yes
  no
  43
  no
diff --git a/tests/hard_coded/constant_prop_2.m b/tests/hard_coded/constant_prop_2.m
index 62af61b69..5ff7c0e63 100644
--- a/tests/hard_coded/constant_prop_2.m
+++ b/tests/hard_coded/constant_prop_2.m
@@ -12,54 +12,59 @@

  :- import_module float.
  :- import_module int.
-:- import_module std_util.
  :- import_module string.
+:- import_module uint.

-main -->
-    ( { "abc" ++ "xyz" = "abcxyz" } ->
-        io.write_string("yes"), io.nl
-    ;
-        link_error
+main(!IO) :-
+    ( if "abc" ++ "xyz" = "abcxyz" then
+        io.write_string("yes", !IO), io.nl(!IO)
+    else
+        link_error(!IO)
      ),
-    ( { 5 * 10000 + 4 * 1000 + 3 * 100 + 2 * 10 + 1 = 54321 } ->
-        io.write_string("yes"), io.nl
-    ;
-        link_error
+    ( if 5 * 10000 + 4 * 1000 + 3 * 100 + 2 * 10 + 1 = 54321 then
+        io.write_string("yes", !IO), io.nl(!IO)
+    else
+        link_error(!IO)
      ),
-    ( { 4.0 * 1000.0 + 3.0 * 100.0 + 2.0 * 10.0 + 1.0 = 4321.0 } ->
-        io.write_string("yes"), io.nl
-    ;
-        link_error
+    ( if 4.0 * 1000.0 + 3.0 * 100.0 + 2.0 * 10.0 + 1.0 = 4321.0 then
+        io.write_string("yes", !IO), io.nl(!IO)
+    else
+        link_error(!IO)
      ),
-    ( { private_builtin.typed_unify(42, 42) } ->
-        io.write_string("yes"), io.nl
-    ;
-        link_error
+    ( if 8u * 1000u + 6u * 100u + 4u * 10u + 2u = 8642u then
+        io.write_string("yes", !IO), io.nl(!IO)
+    else
+        link_error(!IO)
      ),
-    ( { private_builtin.typed_unify(1, 2) } ->
-        link_error
-    ;
-        io.write_string("no"), io.nl
+    ( if private_builtin.typed_unify(42, 42) then
+        io.write_string("yes", !IO), io.nl(!IO)
+    else
+        link_error(!IO)
      ),
-    ( { private_builtin.typed_unify(43, X1) } ->
-        io.write_int(X1), io.nl
-    ;
-        link_error
+    ( if private_builtin.typed_unify(1, 2) then
+        link_error(!IO)
+    else
+        io.write_string("no", !IO), io.nl(!IO)
      ),
-    ( { private_builtin.typed_unify(44, _ `with_type` string) } ->
-        link_error
-    ;
-        io.write_string("no"), io.nl
+    ( if private_builtin.typed_unify(43, X1) then
+        io.write_int(X1, !IO), io.nl(!IO)
+    else
+        link_error(!IO)
      ),
-    ( { dynamic_cast(45, X2) } ->
-        io.write_int(X2), io.nl
-    ;
-        link_error
+    ( if private_builtin.typed_unify(44, _ `with_type` string) then
+        link_error(!IO)
+    else
+        io.write_string("no", !IO), io.nl(!IO)
      ),
-    ( { dynamic_cast(46, _ `with_type` string) } ->
-        link_error
-    ;
-        io.write_string("no"), io.nl
+    ( if dynamic_cast(45, X2) then
+        io.write_int(X2, !IO), io.nl(!IO)
+    else
+        link_error(!IO)
+    ),
+    ( if dynamic_cast(46, _ `with_type` string) then
+        link_error(!IO)
+    else
+        io.write_string("no", !IO), io.nl(!IO)
      ).

      % We should be able to optimize away all calls to this procedure


More information about the reviews mailing list