[m-rev.] for post-commit review: add casts to and from int32 and int{8, 16, 64}
Julien Fischer
jfischer at opturion.com
Fri Jan 14 14:46:54 AEDT 2022
For post-commit review by anyone.
The only thing that really requires review is the documentation and NEWS
file entry; the implementation is trivial.
-------------------------------------------
Add casts to and from int32 and int{8,16,64}.
library/int32.m:
Add the above casts.
NEWS:
Announce the additions.
tests/hard_coded/Mmakefile:
tests/hard_coded/int32_int{8,16,64}.{m,exp}:
Add tests of the new functions.
Julien.
diff --git a/NEWS b/NEWS
index 3b55efc..f5a842c 100644
--- a/NEWS
+++ b/NEWS
@@ -176,6 +176,17 @@ Changes to the Mercury standard library
- func `legacy_left_shift/2` (replacement: `<<`)
- func `legacy_right_shift/2` (replacement: `>>`)
+### Changes to the `int32` module
+
+* The following functions have been added:
+
+ - func `cast_to_int8`
+ - func `cast_from_int8`
+ - func `cast_to_int16`
+ - func `cast_from_int16`
+ - func `cast_to_int64`
+ - func `cast_from_int64`
+
### Changes to the `integer` module
* The following obsolete functions have been removed:
diff --git a/library/int32.m b/library/int32.m
index 0e50cb7..6e5a330 100644
--- a/library/int32.m
+++ b/library/int32.m
@@ -1,7 +1,7 @@
%---------------------------------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
-% Copyright (C) 2017-2018 The Mercury team.
+% Copyright (C) 2017-2022 The Mercury team.
% This file is distributed under the terms specified in COPYING.LIB.
%---------------------------------------------------------------------------%
%
@@ -68,6 +68,69 @@
%---------------------------------------------------------------------------%
%
+% Conversion to/from int8.
+%
+
+ % cast_to_int8(I32) = I8:
+ %
+ % Convert an int32 to an int8.
+ % Always succeeds, but will yield a result that is mathematically equal
+ % to I32 only if I32 is in [-(2^7), 2^7 - 1].
+ %
+:- func cast_to_int8(int32) = int8.
+
+ % cast_from_int8(I8) = I32:
+ %
+ % Convert an int8 to a int32.
+ % Always succeeds, and yields a result that is mathemtically equal
+ % to I8.
+ %
+:- func cast_from_int8(int8) = int32.
+
+%---------------------------------------------------------------------------%
+%
+% Conversion to/from int16.
+%
+
+ % cast_to_int16(I32) = I16:
+ %
+ % Convert an int32 to an int16.
+ % Always succeeds, but will yield a result that is mathematically equal
+ % to I32 only if I32 is in [-(2^15), 2^15 - 1].
+ %
+:- func cast_to_int16(int32) = int16.
+
+ % cast_from_int16(I16) = I32:
+ %
+ % Convert an int16 to a int32.
+ % Always succeeds, and yields a result that is mathemtically equal
+ % to I16.
+ %
+:- func cast_from_int16(int16) = int32.
+
+%---------------------------------------------------------------------------%
+%
+% Conversion to/from int64.
+%
+
+ % cast_to_int64(I32) = I64:
+ %
+ % Convert an int32 to an int64.
+ % Always succeeds, and always yields a result that is
+ % mathematically equal to I32.
+ %
+:- func cast_to_int64(int32) = int64.
+
+ % cast_from_int64(I64) = I32:
+ %
+ % Convert an int64 to a int32.
+ % Always succeeds, but will yield a result that is mathematically equal
+ % to I only if I is in [0, 2^32 - 1].
+ %
+:- func cast_from_int64(int64) = int32.
+
+%---------------------------------------------------------------------------%
+%
% Change of signedness.
%
@@ -476,6 +539,150 @@ det_from_int(I) = I32 :-
%---------------------------------------------------------------------------%
:- pragma foreign_proc("C",
+ cast_to_int8(I32::in) = (I8::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
+ does_not_affect_liveness],
+"
+ I8 = (int8_t) I32;
+").
+
+:- pragma foreign_proc("C#",
+ cast_to_int8(I32::in) = (I8::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I8 = (sbyte) I32;
+").
+
+:- pragma foreign_proc("Java",
+ cast_to_int8(I32::in) = (I8::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I8 = (byte) I32;
+").
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ cast_from_int8(I8::in) = (I32::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
+ does_not_affect_liveness],
+"
+ I32 = I8;
+").
+
+:- pragma foreign_proc("C#",
+ cast_from_int8(I8::in) = (I32::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I32 = I8;
+").
+
+:- pragma foreign_proc("Java",
+ cast_from_int8(I8::in) = (I32::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I32 = I8;
+").
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ cast_to_int16(I32::in) = (I16::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
+ does_not_affect_liveness],
+"
+ I16 = (int16_t) I32;
+").
+
+:- pragma foreign_proc("C#",
+ cast_to_int16(I32::in) = (I16::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I16 = (short) I32;
+").
+
+:- pragma foreign_proc("Java",
+ cast_to_int16(I32::in) = (I16::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I16 = (short) I32;
+").
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ cast_from_int16(I16::in) = (I32::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
+ does_not_affect_liveness],
+"
+ I32 = I16;
+").
+
+:- pragma foreign_proc("C#",
+ cast_from_int16(I16::in) = (I32::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I32 = I16;
+").
+
+:- pragma foreign_proc("Java",
+ cast_from_int16(I16::in) = (I32::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I32 = I16;
+").
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ cast_to_int64(I32::in) = (I64::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
+ does_not_affect_liveness],
+"
+ I64 = (int64_t) I32;
+").
+
+:- pragma foreign_proc("C#",
+ cast_to_int64(I32::in) = (I64::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I64 = (long) I32;
+").
+
+:- pragma foreign_proc("Java",
+ cast_to_int64(I32::in) = (I64::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I64 = (long) I32;
+").
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ cast_from_int64(I64::in) = (I32::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
+ does_not_affect_liveness],
+"
+ I32 = (int32_t) I64;
+").
+
+:- pragma foreign_proc("C#",
+ cast_from_int64(I64::in) = (I32::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I32 = (int) I64;
+").
+
+:- pragma foreign_proc("Java",
+ cast_from_int64(I64::in) = (I32::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I32 = (int) I64;
+").
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
cast_from_uint32(U32::in) = (I32::out),
[will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
does_not_affect_liveness],
diff --git a/tests/hard_coded/Mmakefile b/tests/hard_coded/Mmakefile
index 13c7e85..f3d88b0 100644
--- a/tests/hard_coded/Mmakefile
+++ b/tests/hard_coded/Mmakefile
@@ -209,6 +209,8 @@ ORDINARY_PROGS = \
inst_alias \
int16_from_bytes \
int32_from_bytes \
+ int32_int16_casts \
+ int32_int8_casts \
int64_from_bytes \
int_fold_up_down \
int_impl_imports \
diff --git a/tests/hard_coded/int32_int16_casts.exp b/tests/hard_coded/int32_int16_casts.exp
index e69de29..11f2d49 100644
--- a/tests/hard_coded/int32_int16_casts.exp
+++ b/tests/hard_coded/int32_int16_casts.exp
@@ -0,0 +1,38 @@
+cast_from_int16(-32768i16) = -32768i16
+cast_from_int16(-128i16) = -128i16
+cast_from_int16(-64i16) = -64i16
+cast_from_int16(-56i16) = -56i16
+cast_from_int16(-1i16) = -1i16
+cast_from_int16(0i16) = 0i16
+cast_from_int16(1i16) = 1i16
+cast_from_int16(7i16) = 7i16
+cast_from_int16(8i16) = 8i16
+cast_from_int16(15i16) = 15i16
+cast_from_int16(16i16) = 16i16
+cast_from_int16(31i16) = 31i16
+cast_from_int16(32i16) = 32i16
+cast_from_int16(63i16) = 63i16
+cast_from_int16(64i16) = 64i16
+cast_from_int16(127i16) = 127i16
+cast_from_int16(128i16) = 128i16
+cast_from_int16(32767i16) = 32767i16
+
+cast_to_int16(-32896i32) = 32640i16
+cast_to_int16(-64i32) = -64i16
+cast_to_int16(-32i32) = -32i16
+cast_to_int16(-16i32) = -16i16
+cast_to_int16(-8i32) = -8i16
+cast_to_int16(-1i32) = -1i16
+cast_to_int16(0i32) = 0i16
+cast_to_int16(1i32) = 1i16
+cast_to_int16(7i32) = 7i16
+cast_to_int16(8i32) = 8i16
+cast_to_int16(15i32) = 15i16
+cast_to_int16(16i32) = 16i16
+cast_to_int16(31i32) = 31i16
+cast_to_int16(32i32) = 32i16
+cast_to_int16(63i32) = 63i16
+cast_to_int16(64i32) = 64i16
+cast_to_int16(127i32) = 127i16
+cast_to_int16(128i32) = 128i16
+cast_to_int16(32767i32) = 32767i16
diff --git a/tests/hard_coded/int32_int16_casts.m b/tests/hard_coded/int32_int16_casts.m
index e69de29..10a77a8 100644
--- a/tests/hard_coded/int32_int16_casts.m
+++ b/tests/hard_coded/int32_int16_casts.m
@@ -0,0 +1,97 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%---------------------------------------------------------------------------%
+%
+% Test casting int32s to/from int16s.
+%
+%---------------------------------------------------------------------------%
+
+:- module int32_int16_casts.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module list.
+:- import_module string.
+:- import_module int32.
+:- import_module int16.
+
+%---------------------------------------------------------------------------%
+
+main(!IO) :-
+ list.foldl(do_cast_from_int16_test, int16s, !IO),
+ io.nl(!IO),
+ list.foldl(do_cast_to_int16_test, int32s, !IO).
+
+:- pred do_cast_from_int16_test(int16::in, io::di, io::uo) is det.
+
+do_cast_from_int16_test(I16, !IO) :-
+ io.format("cast_from_int16(%di16) = %di16\n",
+ [i16(I16), i32(cast_from_int16(I16))], !IO).
+
+:- pred do_cast_to_int16_test(int32::in, io::di, io::uo) is det.
+
+do_cast_to_int16_test(I32, !IO) :-
+ io.format("cast_to_int16(%di32) = %di16\n",
+ [i32(I32), i16(cast_to_int16(I32))], !IO).
+
+:- func int16s = list(int16).
+
+int16s = [
+ -32768i16,
+ -128i16,
+ -64i16,
+ -32i16
+ -16i16
+ -8i16,
+ -1i16,
+ 0i16,
+ 1i16,
+ 7i16,
+ 8i16,
+ 15i16,
+ 16i16,
+ 31i16,
+ 32i16,
+ 63i16,
+ 64i16,
+ 127i16,
+ 128i16,
+ 32767i16
+].
+
+:- func int32s = list(int32).
+
+int32s = [
+ -32768i32
+ -128i32,
+ -64i32,
+ -32i32,
+ -16i32,
+ -8i32,
+ -1i32,
+ 0i32,
+ 1i32,
+ 7i32,
+ 8i32,
+ 15i32,
+ 16i32,
+ 31i32,
+ 32i32,
+ 63i32,
+ 64i32,
+ 127i32,
+ 128i32,
+ 32767i32
+].
+
+%---------------------------------------------------------------------------%
+:- end_module int32_int16_casts.
+%---------------------------------------------------------------------------%
diff --git a/tests/hard_coded/int32_int64_casts.exp b/tests/hard_coded/int32_int64_casts.exp
index e69de29..7432828 100644
--- a/tests/hard_coded/int32_int64_casts.exp
+++ b/tests/hard_coded/int32_int64_casts.exp
@@ -0,0 +1,44 @@
+cast_from_int64(-2147483648i64) = -2147483648i64
+cast_from_int64(-2147483647i64) = -2147483647i64
+cast_from_int64(-32768i64) = -32768i64
+cast_from_int64(-128i64) = -128i64
+cast_from_int64(-64i64) = -64i64
+cast_from_int64(-56i64) = -56i64
+cast_from_int64(-1i64) = -1i64
+cast_from_int64(0i64) = 0i64
+cast_from_int64(1i64) = 1i64
+cast_from_int64(7i64) = 7i64
+cast_from_int64(8i64) = 8i64
+cast_from_int64(15i64) = 15i64
+cast_from_int64(16i64) = 16i64
+cast_from_int64(31i64) = 31i64
+cast_from_int64(32i64) = 32i64
+cast_from_int64(63i64) = 63i64
+cast_from_int64(64i64) = 64i64
+cast_from_int64(127i64) = 127i64
+cast_from_int64(128i64) = 128i64
+cast_from_int64(32767i64) = 32767i64
+cast_from_int64(2147483647i64) = 2147483647i64
+
+cast_to_int64(-2147483648i32) = -2147483648i64
+cast_to_int64(-2147483647i32) = -2147483647i64
+cast_to_int64(-32896i32) = -32896i64
+cast_to_int64(-64i32) = -64i64
+cast_to_int64(-32i32) = -32i64
+cast_to_int64(-16i32) = -16i64
+cast_to_int64(-8i32) = -8i64
+cast_to_int64(-1i32) = -1i64
+cast_to_int64(0i32) = 0i64
+cast_to_int64(1i32) = 1i64
+cast_to_int64(7i32) = 7i64
+cast_to_int64(8i32) = 8i64
+cast_to_int64(15i32) = 15i64
+cast_to_int64(16i32) = 16i64
+cast_to_int64(31i32) = 31i64
+cast_to_int64(32i32) = 32i64
+cast_to_int64(63i32) = 63i64
+cast_to_int64(64i32) = 64i64
+cast_to_int64(127i32) = 127i64
+cast_to_int64(128i32) = 128i64
+cast_to_int64(32767i32) = 32767i64
+cast_to_int64(2147483647i32) = 2147483647i64
diff --git a/tests/hard_coded/int32_int64_casts.m b/tests/hard_coded/int32_int64_casts.m
index e69de29..2b3fb20 100644
--- a/tests/hard_coded/int32_int64_casts.m
+++ b/tests/hard_coded/int32_int64_casts.m
@@ -0,0 +1,103 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%---------------------------------------------------------------------------%
+%
+% Test casting int32s to/from int64s.
+%
+%---------------------------------------------------------------------------%
+
+:- module int32_int64_casts.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module list.
+:- import_module string.
+:- import_module int32.
+:- import_module int64.
+
+%---------------------------------------------------------------------------%
+
+main(!IO) :-
+ list.foldl(do_cast_from_int64_test, int64s, !IO),
+ io.nl(!IO),
+ list.foldl(do_cast_to_int64_test, int32s, !IO).
+
+:- pred do_cast_from_int64_test(int64::in, io::di, io::uo) is det.
+
+do_cast_from_int64_test(I64, !IO) :-
+ io.format("cast_from_int64(%di64) = %di64\n",
+ [i64(I64), i32(cast_from_int64(I64))], !IO).
+
+:- pred do_cast_to_int64_test(int32::in, io::di, io::uo) is det.
+
+do_cast_to_int64_test(I32, !IO) :-
+ io.format("cast_to_int64(%di32) = %di64\n",
+ [i32(I32), i64(cast_to_int64(I32))], !IO).
+
+:- func int64s = list(int64).
+
+int64s = [
+ -2147483648i64,
+ -2147483647i64,
+ -32768i64,
+ -128i64,
+ -64i64,
+ -32i64
+ -16i64
+ -8i64,
+ -1i64,
+ 0i64,
+ 1i64,
+ 7i64,
+ 8i64,
+ 15i64,
+ 16i64,
+ 31i64,
+ 32i64,
+ 63i64,
+ 64i64,
+ 127i64,
+ 128i64,
+ 32767i64,
+ 2147483647i64
+].
+
+:- func int32s = list(int32).
+
+int32s = [
+ -2147483648i32,
+ -2147483647i32,
+ -32768i32
+ -128i32,
+ -64i32,
+ -32i32,
+ -16i32,
+ -8i32,
+ -1i32,
+ 0i32,
+ 1i32,
+ 7i32,
+ 8i32,
+ 15i32,
+ 16i32,
+ 31i32,
+ 32i32,
+ 63i32,
+ 64i32,
+ 127i32,
+ 128i32,
+ 32767i32,
+ 2147483647i32
+].
+
+%---------------------------------------------------------------------------%
+:- end_module int32_int64_casts.
+%---------------------------------------------------------------------------%
diff --git a/tests/hard_coded/int32_int8_casts.exp b/tests/hard_coded/int32_int8_casts.exp
index e69de29..5ec82b1 100644
--- a/tests/hard_coded/int32_int8_casts.exp
+++ b/tests/hard_coded/int32_int8_casts.exp
@@ -0,0 +1,33 @@
+cast_from_int8(-128i8) = -128i8
+cast_from_int8(-64i8) = -64i8
+cast_from_int8(-56i8) = -56i8
+cast_from_int8(-1i8) = -1i8
+cast_from_int8(0i8) = 0i8
+cast_from_int8(1i8) = 1i8
+cast_from_int8(7i8) = 7i8
+cast_from_int8(8i8) = 8i8
+cast_from_int8(15i8) = 15i8
+cast_from_int8(16i8) = 16i8
+cast_from_int8(31i8) = 31i8
+cast_from_int8(32i8) = 32i8
+cast_from_int8(63i8) = 63i8
+cast_from_int8(64i8) = 64i8
+cast_from_int8(127i8) = 127i8
+
+cast_to_int8(-128i32) = -128i8
+cast_to_int8(-64i32) = -64i8
+cast_to_int8(-32i32) = -32i8
+cast_to_int8(-16i32) = -16i8
+cast_to_int8(-8i32) = -8i8
+cast_to_int8(-1i32) = -1i8
+cast_to_int8(0i32) = 0i8
+cast_to_int8(1i32) = 1i8
+cast_to_int8(7i32) = 7i8
+cast_to_int8(8i32) = 8i8
+cast_to_int8(15i32) = 15i8
+cast_to_int8(16i32) = 16i8
+cast_to_int8(31i32) = 31i8
+cast_to_int8(32i32) = 32i8
+cast_to_int8(63i32) = 63i8
+cast_to_int8(64i32) = 64i8
+cast_to_int8(127i32) = 127i8
diff --git a/tests/hard_coded/int32_int8_casts.m b/tests/hard_coded/int32_int8_casts.m
index e69de29..3d9ad6b 100644
--- a/tests/hard_coded/int32_int8_casts.m
+++ b/tests/hard_coded/int32_int8_casts.m
@@ -0,0 +1,91 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%---------------------------------------------------------------------------%
+%
+% Test casting int32s to/from int8s.
+%
+%---------------------------------------------------------------------------%
+
+:- module int32_int8_casts.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module list.
+:- import_module string.
+:- import_module int32.
+:- import_module int8.
+
+%---------------------------------------------------------------------------%
+
+main(!IO) :-
+ list.foldl(do_cast_from_int8_test, int8s, !IO),
+ io.nl(!IO),
+ list.foldl(do_cast_to_int8_test, int32s, !IO).
+
+:- pred do_cast_from_int8_test(int8::in, io::di, io::uo) is det.
+
+do_cast_from_int8_test(I8, !IO) :-
+ io.format("cast_from_int8(%di8) = %di8\n",
+ [i8(I8), i32(cast_from_int8(I8))], !IO).
+
+:- pred do_cast_to_int8_test(int32::in, io::di, io::uo) is det.
+
+do_cast_to_int8_test(I32, !IO) :-
+ io.format("cast_to_int8(%di32) = %di8\n",
+ [i32(I32), i8(cast_to_int8(I32))], !IO).
+
+:- func int8s = list(int8).
+
+int8s = [
+ -128i8,
+ -64i8,
+ -32i8
+ -16i8
+ -8i8,
+ -1i8,
+ 0i8,
+ 1i8,
+ 7i8,
+ 8i8,
+ 15i8,
+ 16i8,
+ 31i8,
+ 32i8,
+ 63i8,
+ 64i8,
+ 127i8
+].
+
+:- func int32s = list(int32).
+
+int32s = [
+ -128i32,
+ -64i32,
+ -32i32,
+ -16i32,
+ -8i32,
+ -1i32,
+ 0i32,
+ 1i32,
+ 7i32,
+ 8i32,
+ 15i32,
+ 16i32,
+ 31i32,
+ 32i32,
+ 63i32,
+ 64i32,
+ 127i32
+].
+
+%---------------------------------------------------------------------------%
+:- end_module int32_int8_casts.
+%---------------------------------------------------------------------------%
More information about the reviews
mailing list