[m-rev.] for review: add builtin 8, 16 and 32 bit integer types -- Part 2
Julien Fischer
jfischer at opturion.com
Sat Aug 19 22:25:05 AEST 2017
For review by anyone.
----------
Add builtin 8, 16 and 32 bit integer types -- Part 2.
Enable support for literals of the new types.
Begin implementing library support for 8, 16, and 32 bit types.
Update the compiler to use the new types.
library/int8.m:
library/int16.m:
library/int32.m:
library/uint8.m:
library/uint16.m:
library/uint32.m:
Begin filling these modules out.
library/uint.m:
Unrelated change: add the predicates plus/2, minus/2 and
times/2 for uints.
library/integer.m:
Add predicates for converting integer/0 values into values
of the new types.
Add functions for converting values of the new types into
integer/0 values.
library/string.m:
Add functions for converting values of the new types to strings.
library/private_builtin.m:
Replace the placeholder definitions for the builtin unify and compare
predicates for the new types with their actual definitions.
library/erlang_rtti_implementation.m:
library/rtti_implementation.m:
Replace placeholder definitions for the new types with their
actual definitions.
library/io.m:
Add predicates for writing values of the new types to file streams.
library/stream.string_writer.m:
Implement generic write and print for values of the new types.
library/string.to_string.m:
Likewise for string/1.
library/term.m:
library/term_conversion.m:
Add predicates and functions for converting the new types to
and from terms.
compiler/builtin_ops.m:
compiler/elds.m:
compiler/hlds_data.m:
compiler/llds.m:
compiler/mlds.m:
compiler/prog_data.m:
Replace placeholders for the new types with the new types.
compiler/superhomogeneous.m:
Enable literals of the new types.
compiler/mlds_to_cs.m:
Avoid a warning from the C# compiler for bitwise-or operators
with sbyte operands.
compiler/c_util.m:
compiler/elds_to_erlang.m:
compiler/hlds_out_util.m:
compiler/llds_out_data.m:
compiler/lookup_switch.m:
compiler/mlds_to_c.m:
compiler/mlds_to_java.m:
compiler/opt_debug.m:
compiler/parse_tree_out_info.m:
compiler/parse_tree_to_term.m:
compiler/prog_out.m:
compiler/prog_rep.m:
compiler/prog_util.m:
Replace placeholder code for the new types with code that uses the new
types.
tests/invalid/invalid_int.m:
tests/invalid/invalid_int.err_exp2:
Extend this test case to cover the fixed size integer types.
Julien.
diff --git a/compiler/builtin_ops.m b/compiler/builtin_ops.m
index f81552e8e..d09ecf2f4 100644
--- a/compiler/builtin_ops.m
+++ b/compiler/builtin_ops.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
% Copyright (C) 1999-2001, 2003-2006, 2009-2011 The University of Melbourne.
+% Copyright (C) 2014-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.
%-----------------------------------------------------------------------------%
@@ -171,12 +172,12 @@
---> leaf(T)
; int_const(int)
; uint_const(uint)
- ; int8_const(int) % XXX FIXED SIZE INTS
- ; uint8_const(int) % XXX FIXED SIZE INTS
- ; int16_const(int) % XXX FIXED SIZE INTS
- ; uint16_const(int) % XXX FIXED SIZE INTS
- ; int32_const(int) % XXX FIXED SIZE INTS
- ; uint32_const(int) % XXX FIXED SIZE INTS
+ ; int8_const(int8)
+ ; uint8_const(uint8)
+ ; int16_const(int16)
+ ; uint16_const(uint16)
+ ; int32_const(int32)
+ ; uint32_const(uint32)
; float_const(float)
; unary(unary_op, simple_expr(T))
; binary(binary_op, simple_expr(T), simple_expr(T)).
diff --git a/compiler/c_util.m b/compiler/c_util.m
index 48ea69617..052e24c4a 100644
--- a/compiler/c_util.m
+++ b/compiler/c_util.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 1999-2007, 2009-2012 The University of Melbourne.
+% Copyright (C) 2013-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.
%---------------------------------------------------------------------------%
@@ -184,6 +185,42 @@
io::di, io::uo) is det.
:- pred output_uint_expr_cur_stream(uint::in, io::di, io::uo) is det.
+ % Write out an int8 as a C expression.
+ %
+:- pred output_int8_expr(io.text_output_stream::in, int8::in,
+ io::di, io::uo) is det.
+:- pred output_int8_expr_cur_stream(int8::in, io::di, io::uo) is det.
+
+ % Write out a uint8 as a C expression.
+ %
+:- pred output_uint8_expr(io.text_output_stream::in, uint8::in,
+ io::di, io::uo) is det.
+:- pred output_uint8_expr_cur_stream(uint8::in, io::di, io::uo) is det.
+
+ % Write out an int16 as a C expression.
+ %
+:- pred output_int16_expr(io.text_output_stream::in, int16::in,
+ io::di, io::uo) is det.
+:- pred output_int16_expr_cur_stream(int16::in, io::di, io::uo) is det.
+
+ % Write out a uint16 as a C expression.
+ %
+:- pred output_uint16_expr(io.text_output_stream::in, uint16::in,
+ io::di, io::uo) is det.
+:- pred output_uint16_expr_cur_stream(uint16::in, io::di, io::uo) is det.
+
+ % Write out an int32 as a C expression.
+ %
+:- pred output_int32_expr(io.text_output_stream::in, int32::in,
+ io::di, io::uo) is det.
+:- pred output_int32_expr_cur_stream(int32::in, io::di, io::uo) is det.
+
+ % Write out a uint32 as a C expression.
+ %
+:- pred output_uint32_expr(io.text_output_stream::in, uint32::in,
+ io::di, io::uo) is det.
+:- pred output_uint32_expr_cur_stream(uint32::in, io::di, io::uo) is det.
+
%---------------------------------------------------------------------------%
%
% Float literals.
@@ -778,6 +815,65 @@ output_uint_expr_cur_stream(N, !IO) :-
io.output_stream(Stream, !IO),
output_uint_expr(Stream, N, !IO).
+%---------------------------------------------------------------------------%
+%
+% Fixed size integer literals.
+%
+
+output_int8_expr(Stream, N, !IO) :-
+ io.write_string(Stream, "INT8_C(", !IO),
+ io.write_int8(Stream, N, !IO),
+ io.write_string(Stream, ")", !IO).
+
+output_int8_expr_cur_stream(N, !IO) :-
+ io.output_stream(Stream, !IO),
+ output_int8_expr(Stream, N, !IO).
+
+output_uint8_expr(Stream, N, !IO) :-
+ io.write_string(Stream, "UINT8_C(", !IO),
+ io.write_uint8(Stream, N, !IO),
+ io.write_string(Stream, ")", !IO).
+
+output_uint8_expr_cur_stream(N, !IO) :-
+ io.output_stream(Stream, !IO),
+ output_uint8_expr(Stream, N, !IO).
+
+output_int16_expr(Stream, N, !IO) :-
+ io.write_string(Stream, "INT16_C(", !IO),
+ io.write_int16(Stream, N, !IO),
+ io.write_string(Stream, ")", !IO).
+
+output_int16_expr_cur_stream(N, !IO) :-
+ io.output_stream(Stream, !IO),
+ output_int16_expr(Stream, N, !IO).
+
+output_uint16_expr(Stream, N, !IO) :-
+ io.write_string(Stream, "UINT16_C(", !IO),
+ io.write_uint16(Stream, N, !IO),
+ io.write_string(Stream, ")", !IO).
+
+output_uint16_expr_cur_stream(N, !IO) :-
+ io.output_stream(Stream, !IO),
+ output_uint16_expr(Stream, N, !IO).
+
+output_int32_expr(Stream, N, !IO) :-
+ io.write_string(Stream, "INT32_C(", !IO),
+ io.write_int32(Stream, N, !IO),
+ io.write_string(Stream, ")", !IO).
+
+output_int32_expr_cur_stream(N, !IO) :-
+ io.output_stream(Stream, !IO),
+ output_int32_expr(Stream, N, !IO).
+
+output_uint32_expr(Stream, N, !IO) :-
+ io.write_string(Stream, "UINT32_C(", !IO),
+ io.write_uint32(Stream, N, !IO),
+ io.write_string(Stream, ")", !IO).
+
+output_uint32_expr_cur_stream(N, !IO) :-
+ io.output_stream(Stream, !IO),
+ output_uint32_expr(Stream, N, !IO).
+
%---------------------------------------------------------------------------%
%
% Floating point literals.
diff --git a/compiler/elds.m b/compiler/elds.m
index 5248bd6d4..7dccebd0a 100644
--- a/compiler/elds.m
+++ b/compiler/elds.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
% Copyright (C) 2007, 2010-2011 The University of Melbourne.
+% Copyright (C) 2014-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.
%-----------------------------------------------------------------------------%
@@ -215,12 +216,12 @@
---> elds_char(char)
; elds_int(int)
; elds_uint(uint)
- ; elds_int8(int) % XXX FIXED SIZE INT
- ; elds_uint8(int)
- ; elds_int16(int)
- ; elds_uint16(int)
- ; elds_int32(int)
- ; elds_uint32(int)
+ ; elds_int8(int8)
+ ; elds_uint8(uint8)
+ ; elds_int16(int16)
+ ; elds_uint16(uint16)
+ ; elds_int32(int32)
+ ; elds_uint32(uint32)
; elds_float(float)
; elds_binary(string)
diff --git a/compiler/elds_to_erlang.m b/compiler/elds_to_erlang.m
index aea5e3552..6f22fc4d8 100644
--- a/compiler/elds_to_erlang.m
+++ b/compiler/elds_to_erlang.m
@@ -1,7 +1,8 @@
%-----------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
-% Copyright (C) 2007-2011 The University of Melbourne.
+% Copyright (C) 2007-2012 The University of Melbourne.
+% Copyright (C) 2013-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.
%-----------------------------------------------------------------------------%
@@ -782,29 +783,28 @@ output_term(ModuleInfo, VarSet, Indent, Term, !IO) :-
io.write_uint(UInt, !IO),
space(!IO)
;
- % XXX FIXED SIZE INT
Term = elds_int8(Int8),
- io.write_int(Int8, !IO),
+ io.write_int8(Int8, !IO),
space(!IO)
;
Term = elds_uint8(UInt8),
- io.write_int(UInt8, !IO),
+ io.write_uint8(UInt8, !IO),
space(!IO)
;
Term = elds_int16(Int16),
- io.write_int(Int16, !IO),
+ io.write_int16(Int16, !IO),
space(!IO)
;
Term = elds_uint16(UInt16),
- io.write_int(UInt16, !IO),
+ io.write_uint16(UInt16, !IO),
space(!IO)
;
Term = elds_int32(Int32),
- io.write_int(Int32, !IO),
+ io.write_int32(Int32, !IO),
space(!IO)
;
Term = elds_uint32(UInt32),
- io.write_int(UInt32, !IO),
+ io.write_uint32(UInt32, !IO),
space(!IO)
;
Term = elds_float(Float),
diff --git a/compiler/hlds_data.m b/compiler/hlds_data.m
index 8d56dba91..8c46ad77d 100644
--- a/compiler/hlds_data.m
+++ b/compiler/hlds_data.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 1996-2012 The University of Melbourne.
+% Copyright (C) 2014-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.
%---------------------------------------------------------------------------%
@@ -705,13 +706,12 @@ cons_table_optimize(!ConsTable) :-
% the specified unsigned integer value. This is used for uint
% constants.
- % XXX FIXED SIZE INT
- ; int_tag_int8(int)
- ; int_tag_uint8(int)
- ; int_tag_int16(int)
- ; int_tag_uint16(int)
- ; int_tag_int32(int)
- ; int_tag_uint32(int).
+ ; int_tag_int8(int8)
+ ; int_tag_uint8(uint8)
+ ; int_tag_int16(int16)
+ ; int_tag_uint16(uint16)
+ ; int_tag_int32(int32)
+ ; int_tag_uint32(uint32).
:- type reserved_address
---> null_pointer
diff --git a/compiler/hlds_out_util.m b/compiler/hlds_out_util.m
index 0f303fd64..a3e02a57f 100644
--- a/compiler/hlds_out_util.m
+++ b/compiler/hlds_out_util.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
% Copyright (C) 2009-2012 The University of Melbourne.
+% Copyright (C) 2014-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.
%-----------------------------------------------------------------------------%
@@ -681,32 +682,38 @@ functor_cons_id_to_string(ModuleInfo, VarSet, VarNamePrint, ConsId, ArgVars)
;
ConsId = int8_const(Int8),
Str = functor_to_string(VarSet, VarNamePrint,
- term.integer(base_10, integer(Int8), signed, size_8_bit),
+ term.integer(base_10, integer.from_int8(Int8), signed,
+ size_8_bit),
ArgVars)
;
ConsId = uint8_const(UInt8),
Str = functor_to_string(VarSet, VarNamePrint,
- term.integer(base_10, integer(UInt8), unsigned, size_8_bit),
+ term.integer(base_10, integer.from_uint8(UInt8), unsigned,
+ size_8_bit),
ArgVars)
;
ConsId = int16_const(Int16),
Str = functor_to_string(VarSet, VarNamePrint,
- term.integer(base_10, integer(Int16), signed, size_16_bit),
+ term.integer(base_10, integer.from_int16(Int16), signed,
+ size_16_bit),
ArgVars)
;
ConsId = uint16_const(UInt16),
Str = functor_to_string(VarSet, VarNamePrint,
- term.integer(base_10, integer(UInt16), unsigned, size_16_bit),
+ term.integer(base_10, integer.from_uint16(UInt16), unsigned,
+ size_16_bit),
ArgVars)
;
ConsId = int32_const(Int32),
Str = functor_to_string(VarSet, VarNamePrint,
- term.integer(base_10, integer(Int32), signed, size_32_bit),
+ term.integer(base_10, integer.from_int32(Int32), signed,
+ size_32_bit),
ArgVars)
;
ConsId = uint32_const(UInt32),
Str = functor_to_string(VarSet, VarNamePrint,
- term.integer(base_10, integer(UInt32), unsigned, size_32_bit),
+ term.integer(base_10, integer.from_uint32(UInt32), unsigned,
+ size_32_bit),
ArgVars)
;
ConsId = float_const(Float),
@@ -867,22 +874,22 @@ cons_id_and_vars_or_arity_to_string(VarSet, Qual, ConsId, MaybeArgVars)
String = uint_to_string(UInt) ++ "u"
;
ConsId = int8_const(Int8),
- string.int_to_string(Int8, String)
+ String = string.int8_to_string(Int8) ++ "i8"
;
ConsId = uint8_const(UInt8),
- string.int_to_string(UInt8, String)
+ String = string.uint8_to_string(UInt8) ++ "u8"
;
ConsId = int16_const(Int16),
- string.int_to_string(Int16, String)
+ String = string.int16_to_string(Int16) ++ "i16"
;
ConsId = uint16_const(UInt16),
- string.int_to_string(UInt16, String)
+ String = string.uint16_to_string(UInt16) ++ "u16"
;
ConsId = int32_const(Int32),
- string.int_to_string(Int32, String)
+ String = string.int32_to_string(Int32) ++ "i32"
;
ConsId = uint32_const(UInt32),
- string.int_to_string(UInt32, String)
+ String = string.uint32_to_string(UInt32) ++ "u32"
;
ConsId = float_const(Float),
String = float_to_string(Float)
diff --git a/compiler/llds.m b/compiler/llds.m
index 73a3fdec1..b794669e0 100644
--- a/compiler/llds.m
+++ b/compiler/llds.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
% Copyright (C) 1993-2012 The University of Melbourne.
+% Copyright (C) 2014-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.
%-----------------------------------------------------------------------------%
@@ -1201,16 +1202,18 @@
:- type rval_const
---> llconst_true
; llconst_false
+
; llconst_int(int)
; llconst_uint(uint)
- % XXX FIXED SIZE INT
- ; llconst_int8(int)
- ; llconst_uint8(int)
- ; llconst_int16(int)
- ; llconst_uint16(int)
- ; llconst_int32(int)
- ; llconst_uint32(int)
+ ; llconst_int8(int8)
+ ; llconst_uint8(uint8)
+
+ ; llconst_int16(int16)
+ ; llconst_uint16(uint16)
+
+ ; llconst_int32(int32)
+ ; llconst_uint32(uint32)
; llconst_foreign(string, llds_type)
% A constant in the target language.
diff --git a/compiler/llds_out_data.m b/compiler/llds_out_data.m
index dbe8acdaa..0e8342335 100644
--- a/compiler/llds_out_data.m
+++ b/compiler/llds_out_data.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%----------------------------------------------------------------------------%
% Copyright (C) 2009-2012 The University of Melbourne.
+% Copyright (C) 2013-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.
%----------------------------------------------------------------------------%
@@ -1218,22 +1219,22 @@ output_rval_const(Info, Const, !IO) :-
c_util.output_uint_expr_cur_stream(N, !IO)
;
Const = llconst_int8(N),
- c_util.output_int_expr_cur_stream(N, !IO)
+ c_util.output_int8_expr_cur_stream(N, !IO)
;
Const = llconst_uint8(N),
- c_util.output_int_expr_cur_stream(N, !IO)
+ c_util.output_uint8_expr_cur_stream(N, !IO)
;
Const = llconst_int16(N),
- c_util.output_int_expr_cur_stream(N, !IO)
+ c_util.output_int16_expr_cur_stream(N, !IO)
;
Const = llconst_uint16(N),
- c_util.output_int_expr_cur_stream(N, !IO)
+ c_util.output_uint16_expr_cur_stream(N, !IO)
;
Const = llconst_int32(N),
- c_util.output_int_expr_cur_stream(N, !IO)
+ c_util.output_int32_expr_cur_stream(N, !IO)
;
Const = llconst_uint32(N),
- c_util.output_int_expr_cur_stream(N, !IO)
+ c_util.output_uint32_expr_cur_stream(N, !IO)
;
Const = llconst_foreign(Value, Type),
io.write_char('(', !IO),
diff --git a/compiler/lookup_switch.m b/compiler/lookup_switch.m
index 0aba8ef26..62e60c9ed 100644
--- a/compiler/lookup_switch.m
+++ b/compiler/lookup_switch.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
% Copyright (C) 1996-2012 The University of Melbourne.
+% Copyright (C) 2015, 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.
%-----------------------------------------------------------------------------%
@@ -943,6 +944,16 @@ generate_bit_vec_args([Word - Bits | Rest], Count, [Rval | Rvals]) :-
%-----------------------------------------------------------------------------%
+ % XXX FIXED SIZE INTS
+ % These imports can be deleted once support for fixed size integer literals
+ % has bootstrapped.
+:- import_module int8.
+:- import_module uint8.
+:- import_module int16.
+:- import_module uint16.
+:- import_module int32.
+:- import_module uint32.
+
default_value_for_type(lt_bool) = const(llconst_int(0)).
default_value_for_type(lt_int_least8) = const(llconst_int(0)).
default_value_for_type(lt_uint_least8) = const(llconst_int(0)).
@@ -952,13 +963,12 @@ default_value_for_type(lt_int_least32) = const(llconst_int(0)).
default_value_for_type(lt_uint_least32) = const(llconst_int(0)).
default_value_for_type(lt_int(int_type_int)) = const(llconst_int(0)).
default_value_for_type(lt_int(int_type_uint)) = const(llconst_uint(0u)).
-% XXX FIXED SIZE INT.
-default_value_for_type(lt_int(int_type_int8)) = const(llconst_int8(0)).
-default_value_for_type(lt_int(int_type_uint8)) = const(llconst_uint8(0)).
-default_value_for_type(lt_int(int_type_int16)) = const(llconst_int16(0)).
-default_value_for_type(lt_int(int_type_uint16)) = const(llconst_uint16(0)).
-default_value_for_type(lt_int(int_type_int32)) = const(llconst_int32(0)).
-default_value_for_type(lt_int(int_type_uint32)) = const(llconst_uint32(0)).
+default_value_for_type(lt_int(int_type_int8)) = const(llconst_int8(cast_from_int(0))).
+default_value_for_type(lt_int(int_type_uint8)) = const(llconst_uint8(cast_from_int(0))).
+default_value_for_type(lt_int(int_type_int16)) = const(llconst_int16(cast_from_int(0))).
+default_value_for_type(lt_int(int_type_uint16)) = const(llconst_uint16(cast_from_int(0))).
+default_value_for_type(lt_int(int_type_int32)) = const(llconst_int32(cast_from_int(0))).
+default_value_for_type(lt_int(int_type_uint32)) = const(llconst_uint32(cast_from_int(0))).
default_value_for_type(lt_float) = const(llconst_float(0.0)).
default_value_for_type(lt_string) = const(llconst_string("")).
default_value_for_type(lt_data_ptr) = const(llconst_int(0)).
diff --git a/compiler/mlds.m b/compiler/mlds.m
index 42801afa0..002f4e270 100644
--- a/compiler/mlds.m
+++ b/compiler/mlds.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 1999-2011 The University of Melbourne.
+% Copyright (C) 2013-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.
%---------------------------------------------------------------------------%
@@ -1801,12 +1802,12 @@
; mlconst_false
; mlconst_int(int)
; mlconst_uint(uint)
- ; mlconst_int8(int)
- ; mlconst_uint8(int)
- ; mlconst_int16(int)
- ; mlconst_uint16(int)
- ; mlconst_int32(int)
- ; mlconst_uint32(int)
+ ; mlconst_int8(int8)
+ ; mlconst_uint8(uint8)
+ ; mlconst_int16(int16)
+ ; mlconst_uint16(uint16)
+ ; mlconst_int32(int32)
+ ; mlconst_uint32(uint32)
; mlconst_enum(int, mlds_type)
; mlconst_char(int)
; mlconst_float(float)
diff --git a/compiler/mlds_to_c.m b/compiler/mlds_to_c.m
index 4e7f183a3..34c5793e7 100644
--- a/compiler/mlds_to_c.m
+++ b/compiler/mlds_to_c.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 1999-2012 The University of Melbourne.
+% Copyright (C) 2013-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.
%---------------------------------------------------------------------------%
@@ -5204,22 +5205,22 @@ mlds_output_rval_const(_Opts, Const, !IO) :-
c_util.output_uint_expr_cur_stream(U, !IO)
;
Const = mlconst_int8(N),
- c_util.output_int_expr_cur_stream(N, !IO)
+ c_util.output_int8_expr_cur_stream(N, !IO)
;
Const = mlconst_uint8(N),
- c_util.output_int_expr_cur_stream(N, !IO)
+ c_util.output_uint8_expr_cur_stream(N, !IO)
;
Const = mlconst_int16(N),
- c_util.output_int_expr_cur_stream(N, !IO)
+ c_util.output_int16_expr_cur_stream(N, !IO)
;
Const = mlconst_uint16(N),
- c_util.output_int_expr_cur_stream(N, !IO)
+ c_util.output_uint16_expr_cur_stream(N, !IO)
;
Const = mlconst_int32(N),
- c_util.output_int_expr_cur_stream(N, !IO)
+ c_util.output_int32_expr_cur_stream(N, !IO)
;
Const = mlconst_uint32(N),
- c_util.output_int_expr_cur_stream(N, !IO)
+ c_util.output_uint32_expr_cur_stream(N, !IO)
;
Const = mlconst_char(C),
io.write_string("(MR_Char) ", !IO),
diff --git a/compiler/mlds_to_cs.m b/compiler/mlds_to_cs.m
index daea42e7b..f6f60abb8 100644
--- a/compiler/mlds_to_cs.m
+++ b/compiler/mlds_to_cs.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 2010-2012 The University of Melbourne.
+% Copyright (C) 2013-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.
%---------------------------------------------------------------------------%
@@ -3460,7 +3461,6 @@ output_binop_for_csharp(Info, Op, X, Y, !IO) :-
; Op = int_div(int_type_int8)
; Op = int_mod(int_type_int8)
; Op = bitwise_and(int_type_int8)
- ; Op = bitwise_or(int_type_int8)
; Op = bitwise_xor(int_type_int8)
; Op = unchecked_left_shift(int_type_int8)
; Op = unchecked_right_shift(int_type_int8)
@@ -3472,6 +3472,17 @@ output_binop_for_csharp(Info, Op, X, Y, !IO) :-
io.write_string(" ", !IO),
output_rval_for_csharp(Info, Y, !IO),
io.write_string(")", !IO)
+ ;
+ % The special treatment of bitwise-or here is necessary to avoid
+ % warning CS0675 from the C# compiler.
+ Op = bitwise_or(int_type_int8),
+ io.write_string("(sbyte)((byte)", !IO),
+ output_rval_for_csharp(Info, X, !IO),
+ io.write_string(" ", !IO),
+ output_binary_op_for_csharp(Op, !IO),
+ io.write_string(" (byte)", !IO),
+ output_rval_for_csharp(Info, Y, !IO),
+ io.write_string(")", !IO)
;
( Op = int_add(int_type_uint8)
; Op = int_sub(int_type_uint8)
@@ -3607,22 +3618,22 @@ output_rval_const_for_csharp(Info, Const, !IO) :-
output_uint_const_for_csharp(U, !IO)
;
Const = mlconst_int8(N),
- output_int_const_for_csharp(N, !IO)
+ output_int8_const_for_csharp(N, !IO)
;
Const = mlconst_uint8(N),
- output_int_const_for_csharp(N, !IO)
+ output_uint8_const_for_csharp(N, !IO)
;
Const = mlconst_int16(N),
- output_int_const_for_csharp(N, !IO)
+ output_int16_const_for_csharp(N, !IO)
;
Const = mlconst_uint16(N),
- output_int_const_for_csharp(N, !IO)
+ output_uint16_const_for_csharp(N, !IO)
;
Const = mlconst_int32(N),
- output_int_const_for_csharp(N, !IO)
+ output_int32_const_for_csharp(N, !IO)
;
Const = mlconst_uint32(N),
- output_int_const_for_csharp(N, !IO)
+ output_uint32_const_for_csharp(N, !IO)
;
Const = mlconst_char(N),
io.write_string("( ", !IO),
@@ -3730,6 +3741,37 @@ output_uint_const_for_csharp(U, !IO) :-
io.write_uint(U, !IO),
io.write_string("U", !IO).
+:- pred output_int8_const_for_csharp(int8::in, io::di, io::uo) is det.
+
+output_int8_const_for_csharp(I8, !IO) :-
+ io.write_int8(I8, !IO).
+
+:- pred output_uint8_const_for_csharp(uint8::in, io::di, io::uo) is det.
+
+output_uint8_const_for_csharp(U8, !IO) :-
+ io.write_uint8(U8, !IO).
+
+:- pred output_int16_const_for_csharp(int16::in, io::di, io::uo) is det.
+
+output_int16_const_for_csharp(I16, !IO) :-
+ io.write_int16(I16, !IO).
+
+:- pred output_uint16_const_for_csharp(uint16::in, io::di, io::uo) is det.
+
+output_uint16_const_for_csharp(U16, !IO) :-
+ io.write_uint16(U16, !IO).
+
+:- pred output_int32_const_for_csharp(int32::in, io::di, io::uo) is det.
+
+output_int32_const_for_csharp(I32, !IO) :-
+ io.write_int32(I32, !IO).
+
+:- pred output_uint32_const_for_csharp(uint32::in, io::di, io::uo) is det.
+
+output_uint32_const_for_csharp(U32, !IO) :-
+ io.write_uint32(U32, !IO),
+ io.write_string("U", !IO).
+
%---------------------------------------------------------------------------%
:- pred mlds_output_code_addr_for_csharp(csharp_out_info::in,
diff --git a/compiler/mlds_to_java.m b/compiler/mlds_to_java.m
index 525923d53..7f1aac371 100644
--- a/compiler/mlds_to_java.m
+++ b/compiler/mlds_to_java.m
@@ -1,8 +1,8 @@
%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
-% Copyright (C) 2000-2011 The University of Melbourne.
-% Copyright (C) 2013-2016 The Mercury team.
+% Copyright (C) 2000-2012 The University of Melbourne.
+% Copyright (C) 2013-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.
%---------------------------------------------------------------------------%
@@ -119,6 +119,9 @@
:- import_module cord.
:- import_module digraph.
:- import_module int.
+:- import_module int8.
+:- import_module int16.
+:- import_module int32.
:- import_module list.
:- import_module map.
:- import_module maybe.
@@ -4628,22 +4631,22 @@ output_rval_const_for_java(Info, Const, !IO) :-
output_int_const_for_java(uint.cast_to_int(U), !IO)
;
Const = mlconst_int8(I8),
- output_int_const_for_java(I8, !IO)
+ io.write_int8(I8, !IO)
;
Const = mlconst_uint8(U8),
- output_int_const_for_java(U8, !IO)
+ io.write_int8(int8.cast_from_uint8(U8), !IO)
;
Const = mlconst_int16(I16),
- output_int_const_for_java(I16, !IO)
+ io.write_int16(I16, !IO)
;
Const = mlconst_uint16(U16),
- output_int_const_for_java(U16, !IO)
+ io.write_int16(int16.cast_from_uint16(U16), !IO)
;
Const = mlconst_int32(I32),
- output_int_const_for_java(I32, !IO)
+ io.write_int32(I32, !IO)
;
Const = mlconst_uint32(U32),
- output_int_const_for_java(U32, !IO)
+ io.write_int32(int32.cast_from_uint32(U32), !IO)
;
Const = mlconst_char(N),
io.write_string("(", !IO),
diff --git a/compiler/opt_debug.m b/compiler/opt_debug.m
index 6fff4b72e..19c71b1f2 100644
--- a/compiler/opt_debug.m
+++ b/compiler/opt_debug.m
@@ -1,7 +1,8 @@
%-----------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
-% Copyright (C) 1994-2011 The University of Melbourne.
+% Copyright (C) 1994-2012 The University of Melbourne.
+% Copyright (C) 2013-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.
%-----------------------------------------------------------------------------%
@@ -445,22 +446,22 @@ dump_const(MaybeProcLabel, Const) = Str :-
Str = uint_to_string(U)
;
Const = llconst_int8(I8),
- Str = int_to_string(I8)
+ Str = int8_to_string(I8)
;
Const = llconst_uint8(U8),
- Str = int_to_string(U8)
+ Str = uint8_to_string(U8)
;
Const = llconst_int16(I16),
- Str = int_to_string(I16)
+ Str = int16_to_string(I16)
;
Const = llconst_uint16(U16),
- Str = int_to_string(U16)
+ Str = uint16_to_string(U16)
;
Const = llconst_int32(I32),
- Str = int_to_string(I32)
+ Str = int32_to_string(I32)
;
Const = llconst_uint32(U32),
- Str = int_to_string(U32)
+ Str = uint32_to_string(U32)
;
Const = llconst_foreign(F, _),
Str = F
diff --git a/compiler/parse_tree_out_info.m b/compiler/parse_tree_out_info.m
index abd088fc4..78738992f 100644
--- a/compiler/parse_tree_out_info.m
+++ b/compiler/parse_tree_out_info.m
@@ -1,7 +1,7 @@
%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
-% Copyright (C) 2015 The Mercury team.
+% Copyright (C) 2015-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.
%---------------------------------------------------------------------------%
@@ -107,13 +107,12 @@
pred add_char(char::in, U::di, U::uo) is det,
pred add_int(int::in, U::di, U::uo) is det,
pred add_uint(uint::in, U::di, U::uo) is det,
- % XXX FIXED SIZE INT
- pred add_int8(int::in, U::di, U::uo) is det,
- pred add_uint8(int::in, U::di, U::uo) is det,
- pred add_int16(int::in, U::di, U::uo) is det,
- pred add_uint16(int::in, U::di, U::uo) is det,
- pred add_int32(int::in, U::di, U::uo) is det,
- pred add_uint32(int::in, U::di, U::uo) is det,
+ pred add_int8(int8::in, U::di, U::uo) is det,
+ pred add_uint8(uint8::in, U::di, U::uo) is det,
+ pred add_int16(int16::in, U::di, U::uo) is det,
+ pred add_uint16(uint16::in, U::di, U::uo) is det,
+ pred add_int32(int32::in, U::di, U::uo) is det,
+ pred add_uint32(uint32::in, U::di, U::uo) is det,
pred add_float(float::in, U::di, U::uo) is det,
pred add_purity_prefix(purity::in, U::di, U::uo) is det,
pred add_quoted_atom(string::in, U::di, U::uo) is det,
@@ -199,12 +198,12 @@ maybe_unqualify_sym_name(Info, SymName, OutSymName) :-
pred(add_char/3) is io.write_char,
pred(add_int/3) is io.write_int,
pred(add_uint/3) is write_uint_literal,
- pred(add_int8/3) is io.write_int,
- pred(add_uint8/3) is io.write_int,
- pred(add_int16/3) is io.write_int,
- pred(add_uint16/3) is io.write_int,
- pred(add_int32/3) is io.write_int,
- pred(add_uint32/3) is io.write_int,
+ pred(add_int8/3) is write_int8_literal,
+ pred(add_uint8/3) is write_uint8_literal,
+ pred(add_int16/3) is write_int16_literal,
+ pred(add_uint16/3) is write_uint16_literal,
+ pred(add_int32/3) is write_int32_literal,
+ pred(add_uint32/3) is write_uint32_literal,
pred(add_float/3) is io.write_float,
pred(add_purity_prefix/3) is prog_out.write_purity_prefix,
pred(add_quoted_atom/3) is term_io.quote_atom,
@@ -249,6 +248,42 @@ write_uint_literal(UInt, !IO) :-
io.write_uint(UInt, !IO),
io.write_char('u', !IO).
+:- pred write_int8_literal(int8::in, io::di, io::uo) is det.
+
+write_int8_literal(Int8, !IO) :-
+ io.write_int8(Int8, !IO),
+ io.write_string("i8", !IO).
+
+:- pred write_uint8_literal(uint8::in, io::di, io::uo) is det.
+
+write_uint8_literal(UInt8, !IO) :-
+ io.write_uint8(UInt8, !IO),
+ io.write_string("u8", !IO).
+
+:- pred write_int16_literal(int16::in, io::di, io::uo) is det.
+
+write_int16_literal(Int16, !IO) :-
+ io.write_int16(Int16, !IO),
+ io.write_string("i16", !IO).
+
+:- pred write_uint16_literal(uint16::in, io::di, io::uo) is det.
+
+write_uint16_literal(UInt16, !IO) :-
+ io.write_uint16(UInt16, !IO),
+ io.write_string("u16", !IO).
+
+:- pred write_int32_literal(int32::in, io::di, io::uo) is det.
+
+write_int32_literal(Int32, !IO) :-
+ io.write_int32(Int32, !IO),
+ io.write_string("i32", !IO).
+
+:- pred write_uint32_literal(uint32::in, io::di, io::uo) is det.
+
+write_uint32_literal(UInt32, !IO) :-
+ io.write_uint32(UInt32, !IO),
+ io.write_string("u32", !IO).
+
%---------------------------------------------------------------------------%
:- pred write_eval_eval_method(eval_method::in, io::di, io::uo) is det.
@@ -294,41 +329,40 @@ output_uint(U, Str0, Str) :-
S = uint_to_string(U) ++ "u",
string.append(Str0, S, Str).
-% XXX FIXED SIZE INT
-:- pred output_int8(int::in, string::di, string::uo) is det.
+:- pred output_int8(int8::in, string::di, string::uo) is det.
-output_int8(I, Str0, Str) :-
- string.int_to_string(I, S),
+output_int8(I8, Str0, Str) :-
+ S = string.int8_to_string(I8),
string.append(Str0, S, Str).
-:- pred output_uint8(int::in, string::di, string::uo) is det.
+:- pred output_uint8(uint8::in, string::di, string::uo) is det.
-output_uint8(I, Str0, Str) :-
- string.int_to_string(I, S),
+output_uint8(U8, Str0, Str) :-
+ S = string.uint8_to_string(U8),
string.append(Str0, S, Str).
-:- pred output_int16(int::in, string::di, string::uo) is det.
+:- pred output_int16(int16::in, string::di, string::uo) is det.
-output_int16(I, Str0, Str) :-
- string.int_to_string(I, S),
+output_int16(I16, Str0, Str) :-
+ S = string.int16_to_string(I16),
string.append(Str0, S, Str).
-:- pred output_uint16(int::in, string::di, string::uo) is det.
+:- pred output_uint16(uint16::in, string::di, string::uo) is det.
-output_uint16(I, Str0, Str) :-
- string.int_to_string(I, S),
+output_uint16(U16, Str0, Str) :-
+ S = string.uint16_to_string(U16),
string.append(Str0, S, Str).
-:- pred output_int32(int::in, string::di, string::uo) is det.
+:- pred output_int32(int32::in, string::di, string::uo) is det.
-output_int32(I, Str0, Str) :-
- string.int_to_string(I, S),
+output_int32(I32, Str0, Str) :-
+ S = string.int32_to_string(I32),
string.append(Str0, S, Str).
-:- pred output_uint32(int::in, string::di, string::uo) is det.
+:- pred output_uint32(uint32::in, string::di, string::uo) is det.
-output_uint32(I, Str0, Str) :-
- string.int_to_string(I, S),
+output_uint32(U32, Str0, Str) :-
+ S = string.uint32_to_string(U32),
string.append(Str0, S, Str).
:- pred output_float(float::in, string::di, string::uo) is det.
diff --git a/compiler/parse_tree_to_term.m b/compiler/parse_tree_to_term.m
index 8cfb45ec7..a24357a29 100644
--- a/compiler/parse_tree_to_term.m
+++ b/compiler/parse_tree_to_term.m
@@ -2,7 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 2009-2012 The University of Melbourne.
-% Copyright (C) 2015-2016 The Mercury team.
+% Copyright (C) 2015-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.
%---------------------------------------------------------------------------%
@@ -654,27 +654,27 @@ cons_id_and_args_to_term_full(ConsId, ArgTerms, Term) :-
;
ConsId = int8_const(Int8),
term.context_init(Context),
- Term = int_to_decimal_term(Int8, Context)
+ Term = int8_to_decimal_term(Int8, Context)
;
ConsId = uint8_const(UInt8),
term.context_init(Context),
- Term = int_to_decimal_term(UInt8, Context)
+ Term = uint8_to_decimal_term(UInt8, Context)
;
ConsId = int16_const(Int16),
term.context_init(Context),
- Term = int_to_decimal_term(Int16, Context)
+ Term = int16_to_decimal_term(Int16, Context)
;
ConsId = uint16_const(UInt16),
term.context_init(Context),
- Term = int_to_decimal_term(UInt16, Context)
+ Term = uint16_to_decimal_term(UInt16, Context)
;
ConsId = int32_const(Int32),
term.context_init(Context),
- Term = int_to_decimal_term(Int32, Context)
+ Term = int32_to_decimal_term(Int32, Context)
;
ConsId = uint32_const(UInt32),
term.context_init(Context),
- Term = int_to_decimal_term(UInt32, Context)
+ Term = uint32_to_decimal_term(UInt32, Context)
;
ConsId = float_const(Float),
term.context_init(Context),
diff --git a/compiler/prog_data.m b/compiler/prog_data.m
index dd62cfb7b..db44d2ef7 100644
--- a/compiler/prog_data.m
+++ b/compiler/prog_data.m
@@ -2,7 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 1996-2012 The University of Melbourne.
-% Copyright (C) 2015 The Mercury team.
+% Copyright (C) 2014-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.
%---------------------------------------------------------------------------%
@@ -107,12 +107,12 @@
; int_const(int)
; uint_const(uint)
- ; int8_const(int) % XXX FIXED SIZE INT
- ; uint8_const(int) % XXX FIXED SIZE INT
- ; int16_const(int) % XXX FIXED SIZE INT
- ; uint16_const(int) % XXX FIXED SIZE INT
- ; int32_const(int) % XXX FIXED SIZE INT
- ; uint32_const(int) % XXX FIXED SIZE INT
+ ; int8_const(int8)
+ ; uint8_const(uint8)
+ ; int16_const(int16)
+ ; uint16_const(uint16)
+ ; int32_const(int32)
+ ; uint32_const(uint32)
; float_const(float)
; char_const(char)
; string_const(string)
diff --git a/compiler/prog_out.m b/compiler/prog_out.m
index 923ff5908..1443147ff 100644
--- a/compiler/prog_out.m
+++ b/compiler/prog_out.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
% Copyright (C) 1993-2011 The University of Melbourne.
+% Copyright (C) 2014-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.
%-----------------------------------------------------------------------------%
@@ -371,29 +372,23 @@ cons_id_and_arity_to_string_maybe_quoted(MangleCons, QuoteCons, ConsId)
ConsId = uint_const(UInt),
String = uint_to_string(UInt)
;
- % XXX FIXED SIZE INT
ConsId = int8_const(Int8),
- string.int_to_string(Int8, String)
+ String = string.int8_to_string(Int8)
;
- % XXX FIXED SIZE INT
ConsId = uint8_const(UInt8),
- string.int_to_string(UInt8, String)
+ String = string.uint8_to_string(UInt8)
;
- % XXX FIXED SIZE INT
ConsId = int16_const(Int16),
- string.int_to_string(Int16, String)
+ String = string.int16_to_string(Int16)
;
- % XXX FIXED SIZE INT
ConsId = uint16_const(UInt16),
- string.int_to_string(UInt16, String)
+ String = string.uint16_to_string(UInt16)
;
- % XXX FIXED SIZE INT
ConsId = int32_const(Int32),
- string.int_to_string(Int32, String)
+ String = string.int32_to_string(Int32)
;
- % XXX FIXED SIZE INT
ConsId = uint32_const(UInt32),
- string.int_to_string(UInt32, String)
+ String = string.uint32_to_string(UInt32)
;
ConsId = float_const(Float),
String = float_to_string(Float)
diff --git a/compiler/prog_rep.m b/compiler/prog_rep.m
index 46758c9bb..50c2ffcae 100644
--- a/compiler/prog_rep.m
+++ b/compiler/prog_rep.m
@@ -2,7 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 2000-2012 University of Melbourne.
-% Copyright (C) 2015 The Mercury team.
+% Copyright (C) 2015-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.
%-----------------------------------------------------------------------------%
@@ -868,12 +868,12 @@ cons_id_rep(cons(SymName, _, _)) =
cons_id_rep(tuple_cons(_)) = "{}".
cons_id_rep(int_const(Int)) = string.int_to_string(Int).
cons_id_rep(uint_const(UInt)) = string.uint_to_string(UInt).
-cons_id_rep(int8_const(Int8)) = string.int_to_string(Int8).
-cons_id_rep(uint8_const(UInt8)) = string.int_to_string(UInt8).
-cons_id_rep(int16_const(Int16)) = string.int_to_string(Int16).
-cons_id_rep(uint16_const(UInt16)) = string.int_to_string(UInt16).
-cons_id_rep(int32_const(Int32)) = string.int_to_string(Int32).
-cons_id_rep(uint32_const(UInt32)) = string.int_to_string(UInt32).
+cons_id_rep(int8_const(Int8)) = string.int8_to_string(Int8).
+cons_id_rep(uint8_const(UInt8)) = string.uint8_to_string(UInt8).
+cons_id_rep(int16_const(Int16)) = string.int16_to_string(Int16).
+cons_id_rep(uint16_const(UInt16)) = string.uint16_to_string(UInt16).
+cons_id_rep(int32_const(Int32)) = string.int32_to_string(Int32).
+cons_id_rep(uint32_const(UInt32)) = string.uint32_to_string(UInt32).
cons_id_rep(float_const(Float)) = string.float_to_string(Float).
cons_id_rep(char_const(Char)) = string.char_to_string(Char).
cons_id_rep(string_const(String)) = """" ++ String ++ """".
diff --git a/compiler/prog_util.m b/compiler/prog_util.m
index ca74d6350..fd3512e3e 100644
--- a/compiler/prog_util.m
+++ b/compiler/prog_util.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
% Copyright (C) 1994-2001, 2003-2012 The University of Melbourne.
+% Copyright (C) 2014-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.
%-----------------------------------------------------------------------------%
@@ -728,15 +729,45 @@ make_functor_cons_id(Functor, Arity, ConsId) :-
Functor = term.atom(Name),
ConsId = cons(unqualified(Name), Arity, cons_id_dummy_type_ctor)
;
- Functor = term.integer(Base, Integer, Signedness, size_word),
+ Functor = term.integer(Base, Integer, Signedness, Size),
(
Signedness = signed,
- source_integer_to_int(Base, Integer, Int),
- ConsId = int_const(Int)
+ (
+ Size = size_word,
+ source_integer_to_int(Base, Integer, Int),
+ ConsId = int_const(Int)
+ ;
+ Size = size_8_bit,
+ integer.to_int8(Integer, Int8),
+ ConsId = int8_const(Int8)
+ ;
+ Size = size_16_bit,
+ integer.to_int16(Integer, Int16),
+ ConsId = int16_const(Int16)
+ ;
+ Size = size_32_bit,
+ integer.to_int32(Integer, Int32),
+ ConsId = int32_const(Int32)
+ )
;
Signedness = unsigned,
- integer.to_uint(Integer, UInt),
- ConsId = uint_const(UInt)
+ (
+ Size = size_word,
+ integer.to_uint(Integer, UInt),
+ ConsId = uint_const(UInt)
+ ;
+ Size = size_8_bit,
+ integer.to_uint8(Integer, UInt8),
+ ConsId = uint8_const(UInt8)
+ ;
+ Size = size_16_bit,
+ integer.to_uint16(Integer, UInt16),
+ ConsId = uint16_const(UInt16)
+ ;
+ Size = size_32_bit,
+ integer.to_uint32(Integer, UInt32),
+ ConsId = uint32_const(UInt32)
+ )
)
;
Functor = term.string(String),
diff --git a/compiler/superhomogeneous.m b/compiler/superhomogeneous.m
index 79533007d..9dfa15a4f 100644
--- a/compiler/superhomogeneous.m
+++ b/compiler/superhomogeneous.m
@@ -1,7 +1,8 @@
%-----------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
-% Copyright (C) 2005-2012,2014 The University of Melbourne.
+% Copyright (C) 2005-2012 The University of Melbourne.
+% Copyright (C) 2014-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.
%-----------------------------------------------------------------------------%
@@ -739,50 +740,57 @@ parse_ordinary_cons_id(Functor, ArgTerms, Context, ConsId, !Specs) :-
Size = size_word,
(
Signedness = signed,
- ( if source_integer_to_int(Base, Integer, Int) then
- ConsId = int_const(Int)
- else
- BasePrefix = integer_base_prefix(Base),
- IntString = integer.to_base_string(Integer,
- integer_base_int(Base)),
- Pieces = [words("Error: the integer literal"),
- quote(BasePrefix ++ IntString),
- words("is too big to be represented on this machine."),
- nl],
- Msg = simple_msg(Context, [always(Pieces)]),
- Spec = error_spec(severity_error, phase_parse_tree_to_hlds,
- [Msg]),
- !:Specs = [Spec | !.Specs],
- % This is a dummy.
- ConsId = int_const(0)
- )
+ parse_integer_cons_id(Context, Base, Integer, "", "",
+ source_integer_to_int(Base), (func(I) = int_const(I)),
+ ConsId, !Specs)
;
Signedness = unsigned,
- ( if integer.to_uint(Integer, UInt) then
- ConsId = uint_const(UInt)
- else
- BasePrefix = integer_base_prefix(Base),
- IntString = integer.to_base_string(Integer,
- integer_base_int(Base)),
- Pieces = [words("Error: the unsigned integer literal"),
- quote(BasePrefix ++ IntString ++ "u"),
- words("is too big to be represented on this machine."),
- nl],
- Msg = simple_msg(Context, [always(Pieces)]),
- Spec = error_spec(severity_error, phase_parse_tree_to_hlds,
- [Msg]),
- !:Specs = [Spec | !.Specs],
- % This is a dummy.
- ConsId = int_const(0)
- )
+ parse_integer_cons_id(Context, Base, Integer, "unsigned", "u",
+ integer.to_uint, (func(I) = uint_const(I)),
+ ConsId, !Specs)
)
;
- ( Size = size_8_bit
- ; Size = size_16_bit
- ; Size = size_32_bit
- ; Size = size_64_bit
- ),
- Pieces = [words("Error: fixed size integers"),
+ Size = size_8_bit,
+ (
+ Signedness = signed,
+ parse_integer_cons_id(Context, Base, Integer, "8-bit", "i8",
+ integer.to_int8, (func(I) = int8_const(I)),
+ ConsId, !Specs)
+ ;
+ Signedness = unsigned,
+ parse_integer_cons_id(Context, Base, Integer, "unsigned 8-bit",
+ "u8", integer.to_uint8, (func(I) = uint8_const(I)),
+ ConsId, !Specs)
+ )
+ ;
+ Size = size_16_bit,
+ (
+ Signedness = signed,
+ parse_integer_cons_id(Context, Base, Integer, "16-bit", "i16",
+ integer.to_int16, (func(I) = int16_const(I)),
+ ConsId, !Specs)
+ ;
+ Signedness = unsigned,
+ parse_integer_cons_id(Context, Base, Integer, "unsigned 16-bit",
+ "u16", integer.to_uint16, (func(I) = uint16_const(I)),
+ ConsId, !Specs)
+ )
+ ;
+ Size = size_32_bit,
+ (
+ Signedness = signed,
+ parse_integer_cons_id(Context, Base, Integer, "32-bit", "i32",
+ integer.to_int32, (func(I) = int32_const(I)),
+ ConsId, !Specs)
+ ;
+ Signedness = unsigned,
+ parse_integer_cons_id(Context, Base, Integer, "unsigned 32-bit",
+ "u32", integer.to_uint32, (func(I) = uint32_const(I)),
+ ConsId, !Specs)
+ )
+ ;
+ Size = size_64_bit,
+ Pieces = [words("Error: 64-bit integer types"),
words("are not (yet) supported.")],
Msg = simple_msg(Context, [always(Pieces)]),
Spec = error_spec(severity_error, phase_parse_tree_to_hlds,
@@ -802,6 +810,31 @@ parse_ordinary_cons_id(Functor, ArgTerms, Context, ConsId, !Specs) :-
ConsId = impl_defined_const(Name)
).
+:- pred parse_integer_cons_id(term.context::in, integer_base::in, integer::in, string::in,
+ string::in, pred(integer, T)::in(pred(in, out) is semidet),
+ (func(T) = cons_id)::in, cons_id::out,
+ list(error_spec)::in, list(error_spec)::out) is det.
+
+parse_integer_cons_id(Context, Base, Integer, IntDesc, IntSuffixStr, ConvPred,
+ ToConsIdPred, ConsId, !Specs) :-
+ ( if ConvPred(Integer, Int) then
+ ConsId = ToConsIdPred(Int)
+ else
+ BasePrefix = integer_base_prefix(Base),
+ IntString = integer.to_base_string(Integer,
+ integer_base_int(Base)),
+ Pieces = [words("Error: the"), words(IntDesc), words("integer literal"),
+ quote(BasePrefix ++ IntString ++ IntSuffixStr),
+ words("is outside the range of that type."),
+ nl],
+ Msg = simple_msg(Context, [always(Pieces)]),
+ Spec = error_spec(severity_error, phase_parse_tree_to_hlds,
+ [Msg]),
+ !:Specs = [Spec | !.Specs],
+ % This is a dummy.
+ ConsId = int_const(0)
+ ).
+
% See whether Atom indicates a term with special syntax.
%
:- pred maybe_unravel_special_var_functor_unification(prog_var::in,
diff --git a/library/erlang_rtti_implementation.m b/library/erlang_rtti_implementation.m
index db60cad76..ac8652f09 100644
--- a/library/erlang_rtti_implementation.m
+++ b/library/erlang_rtti_implementation.m
@@ -1,7 +1,8 @@
%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
%---------------------------------------------------------------------------%
-% Copyright (C) 2007, 2011 The University of Melbourne.
+% Copyright (C) 2007, 2009-2012 The University of Melbourne.
+% Copyright (C) 2014-2017 The Mercury team.
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%---------------------------------------------------------------------------%
@@ -843,37 +844,43 @@ deconstruct_2(Term, TypeInfo, TypeCtorInfo, TypeCtorRep, NonCanon,
Arguments = []
;
TypeCtorRep = etcr_int8,
- Functor = "<<int8>>", % XXX FIXED SIZE INT
+ det_dynamic_cast(Term, Int8),
+ Functor = string.int8_to_string(Int8) ++ "i8",
FunctorNumber = 0,
Arity = 0,
Arguments = []
;
TypeCtorRep = etcr_uint8,
- Functor = "<<uint8>>", % XXX FIXED SIZE INT
+ det_dynamic_cast(Term, UInt8),
+ Functor = string.uint8_to_string(UInt8) ++ "u8",
FunctorNumber = 0,
Arity = 0,
Arguments = []
;
TypeCtorRep = etcr_int16,
- Functor = "<<int16>>", % XXX FIXED SIZE INT
+ det_dynamic_cast(Term, Int16),
+ Functor = string.int16_to_string(Int16) ++ "i16",
FunctorNumber = 0,
Arity = 0,
Arguments = []
;
TypeCtorRep = etcr_uint16,
- Functor = "<<uint16>>", % XXX FIXED SIZE INT
+ det_dynamic_cast(Term, UInt16),
+ Functor = string.uint16_to_string(UInt16) ++ "u16",
FunctorNumber = 0,
Arity = 0,
Arguments = []
;
TypeCtorRep = etcr_int32,
- Functor = "<<int32>>", % XXX FIXED SIZE INT
+ det_dynamic_cast(Term, Int32),
+ Functor = string.int32_to_string(Int32) ++ "i32",
FunctorNumber = 0,
Arity = 0,
Arguments = []
;
TypeCtorRep = etcr_uint32,
- Functor = "<<uint32>>", % XXX FIXED SIZE INT
+ det_dynamic_cast(Term, UInt32),
+ Functor = string.uint32_to_string(UInt32) ++ "u32",
FunctorNumber = 0,
Arity = 0,
Arguments = []
diff --git a/library/int16.m b/library/int16.m
index a0e1499f8..4325c9c02 100644
--- a/library/int16.m
+++ b/library/int16.m
@@ -5,16 +5,391 @@
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%---------------------------------------------------------------------------%
+%
+% File: int16.m
+% Main author: juliensf
+% Stability: low.
+%
+% Predicates and functions for dealing with signed 16-bit integer numbers.
+%
+%---------------------------------------------------------------------------%
:- module int16.
:- interface.
- % int16s are NYI -- this module is just a placeholder for their
- % library support.
+:- import_module pretty_printer.
+
+%---------------------------------------------------------------------------%
+
+ % from_int(I, I16):
+ % Convert an int to an int16.
+ % Fails if I is not in [-32768, 32767].
%
-:- type placeholder_int16 ---> placeholder_int16.
+:- pred from_int(int::in, int16::out) is semidet.
+
+ % As above, but throw an exception instead of failing.
+ %
+:- func det_from_int(int) = int16.
+
+:- func cast_from_int(int) = int16.
+
+:- func cast_from_uint16(uint16) = int16.
+
+:- func to_int(int16) = int.
%---------------------------------------------------------------------------%
-:- end_module int16.
+
+ % Less than.
+ %
+:- pred (int16::in) < (int16::in) is semidet.
+
+ % Greater than.
+ %
+:- pred (int16::in) > (int16::in) is semidet.
+
+ % Less than or equal.
+ %
+:- pred (int16::in) =< (int16::in) is semidet.
+
+ % Greater than or equal.
+ %
+:- pred (int16::in) >= (int16::in) is semidet.
+
+%---------------------------------------------------------------------------%
+
+ % Maximum.
+ %
+:- func max(int16, int16) = int16.
+
+ % Minimum.
+ %
+:- func min(int16, int16) = int16.
+
+%---------------------------------------------------------------------------%
+
+ % Unary plus.
+ %
+:- func + (int16::in) = (int16::uo) is det.
+
+ % Unary minus.
+ %
+:- func - (int16::in) = (int16::uo) is det.
+
+ % Addition.
+ %
+:- func int16 + int16 = int16.
+:- mode in + in = uo is det.
+:- mode uo + in = in is det.
+:- mode in + uo = in is det.
+
+:- func plus(int16, int16) = int16.
+
+ % Subtraction.
+ %
+:- func int16 - int16 = int16.
+:- mode in - in = uo is det.
+:- mode uo - in = in is det.
+:- mode in - uo = in is det.
+
+:- func minus(int16, int16) = int16.
+
+ % Multiplication.
+ %
+:- func (int16::in) * (int16::in) = (int16::uo) is det.
+:- func times(int16, int16) = int16.
+
+ % Flooring integer division.
+ % Truncates towards minus infinity, e.g. (-10_i16) div 3_i16 = (-4_i16).
+ %
+ % Throws a `math.domain_error' exception if the right operand is zero.
+ %
+:- func (int16::in) div (int16::in) = (int16::uo) is det.
+
+ % Truncating integer division.
+ % Truncates towards zero, e.g. (-10_i16) // 3_i16 = (-3_i16).
+ % `div' has nicer mathematical properties for negative operands,
+ % but `//' is typically more efficient.
+ %
+ % Throws a `math.domain_error' exception if the right operand is zero.
+ %
+:- func (int16::in) // (int16::in) = (int16::uo) is det.
+
+ % (/)/2 is a synonym for (//)/2.
+ %
+:- func (int16::in) / (int16::in) = (int16::uo) is det.
+
+ % unchecked_quotient(X, Y) is the same as X // Y, but the behaviour
+ % is undefined if the right operand is zero.
+ %
+:- func unchecked_quotient(int16::in, int16::in) = (int16::uo) is det.
+
+ % Modulus.
+ % X mod Y = X - (X div Y) * Y
+ %
+ % Throws a `math.domain_error' exception if the right operand is zero.
+ %
+:- func (int16::in) mod (int16::in) = (int16::uo) is det.
+
+ % Remainder.
+ % X rem Y = X - (X // Y) * Y.
+ %
+ % Throws a `math.domain_error/` exception if the right operand is zero.
+ %
+:- func (int16::in) rem (int16::in) = (int16::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(int16::in, int16::in) = (int16::uo) is det.
+
+ % Left shift.
+ % X << Y returns X "left shifted" by Y bits.
+ % The bit positions vacated by the shift are filled by zeros.
+ % Throws an exception if Y is not in [0, 16).
+ %
+:- func (int16::in) << (int::in) = (int16::uo) is det.
+
+ % unchecked_lift_shift(X, Y) is the same as X << Y except that the
+ % behaviour is undefined if Y is not in [0, 16).
+ % It will typically be be implemented more efficiently than X << Y.
+ %
+:- func unchecked_left_shift(int16::in, int::in) = (int16::uo) is det.
+
+ % Right shift.
+ % X >> Y returns X "right shifted" by Y bits.
+ % The bit positions vacated by the shift are filled by the sign bit.
+ % Throws an exception if Y is not in [0, 16).
+ %
+:- func (int16::in) >> (int::in) = (int16::uo) is det.
+
+ % unchecked_right_shift(X, Y) is the same as X >> Y except that the
+ % behaviour is undefined if Y is not in [0, 16).
+ % It will typically be implemented more efficiently than X >> Y.
+ %
+:- func unchecked_right_shift(int16::in, int::in) = (int16::uo) is det.
+
+ % even(X) is equivalent to (X mod 2i16 = 0i16).
+ %
+:- pred even(int16::in) is semidet.
+
+ % odd(X) is equivalent to (not even(X)), i.e. (X mod 2i16 = 1i16).
+ %
+:- pred odd(int16::in) is semidet.
+
+ % Bitwise and.
+ %
+:- func (int16::in) /\ (int16::in) = (int16::uo) is det.
+
+ % Bitwise or.
+ %
+:- func (int16::in) \/ (int16::in) = (int16::uo) is det.
+
+ % Bitwise exclusive or (xor).
+ %
+:- func xor(int16, int16) = int16.
+:- mode xor(in, in) = uo is det.
+:- mode xor(in, uo) = in is det.
+:- mode xor(uo, in) = in is det.
+
+ % Bitwise complement.
+ %
+:- func \ (int16::in) = (int16::uo) is det.
+
+:- func min_int16 = int16.
+
+:- func max_int16 = int16.
+
+ % Convert an int16 to a pretty_printer.doc for formatting.
+ %
+:- func int16_to_doc(int16) = pretty_printer.doc.
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module exception.
+:- import_module int.
+:- import_module math.
+:- import_module require.
+:- import_module string.
+:- import_module uint.
+
%---------------------------------------------------------------------------%
+from_int(I, I16) :-
+ I >= -32_768,
+ I =< 32_767,
+ I16 = cast_from_int(I).
+
+det_from_int(I) = I16 :-
+ ( if from_int(I, I16Prime) then
+ I16 = I16Prime
+ else
+ error("int16.det_from_int: cannot convert int to int16")
+ ).
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ cast_from_int(I::in) = (I16::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
+ does_not_affect_liveness],
+"
+ I16 = (int16_t) I;
+").
+
+:- pragma foreign_proc("C#",
+ cast_from_int(I::in) = (I16::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I16 = (short) I;
+").
+
+:- pragma foreign_proc("Java",
+ cast_from_int(I::in) = (I16::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I16 = (short) I;
+").
+
+:- pragma no_determinism_warning(cast_from_int/1).
+cast_from_int(_) = _ :-
+ sorry($module, "int16.cast_from_int/1 NYI for Erlang").
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ cast_from_uint16(U16::in) = (I16::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
+ does_not_affect_liveness],
+"
+ I16 = U16;
+").
+
+:- pragma foreign_proc("C#",
+ cast_from_uint16(U16::in) = (I16::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I16 = (short) U16;
+").
+
+:- pragma foreign_proc("Java",
+ cast_from_uint16(U16::in) = (I16::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I16 = U16;
+").
+
+:- pragma no_determinism_warning(cast_from_uint16/1).
+cast_from_uint16(_) = _ :-
+ sorry($module, "int16.cast_from_uint16/1 NYI for Erlang").
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ to_int(I16::in) = (I::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+ I = I16;
+").
+
+:- pragma foreign_proc("C#",
+ to_int(I16::in) = (I::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I = I16;
+").
+
+:- pragma foreign_proc("Java",
+ to_int(I16::in) = (I::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I = I16;
+").
+
+%---------------------------------------------------------------------------%
+
+max(X, Y) =
+ ( if X > Y then X else Y ).
+
+min(X, Y) =
+ ( if X < Y then X else Y ).
+
+%---------------------------------------------------------------------------%
+
+X div Y = Div :-
+ Trunc = X // Y,
+ ( if
+ ( X >= cast_from_int(0), Y >= cast_from_int(0)
+ ; X < cast_from_int(0), Y < cast_from_int(0)
+ ; X rem Y = cast_from_int(0)
+ )
+ then
+ Div = Trunc
+ else
+ Div = Trunc - cast_from_int(1)
+ ).
+
+:- pragma inline('//'/2).
+X // Y = Div :-
+ ( if Y = cast_from_int(0) then
+ throw(math.domain_error("int16.'//': division by zero"))
+ else
+ Div = unchecked_quotient(X, Y)
+ ).
+
+:- pragma inline('/'/2).
+X / Y = X // Y.
+
+X mod Y = X - (X div Y) * Y.
+
+:- pragma inline(rem/2).
+X rem Y = Rem :-
+ ( if Y = cast_from_int(0) then
+ throw(math.domain_error("int16.rem: division by zero"))
+ else
+ Rem = unchecked_rem(X, Y)
+ ).
+
+%---------------------------------------------------------------------------%
+
+X << Y = Result :-
+ ( if cast_from_int(Y) < 16u then
+ Result = unchecked_left_shift(X, Y)
+ else
+ Msg = "int16.(<<): second operand is out of range",
+ throw(math.domain_error(Msg))
+ ).
+
+X >> Y = Result :-
+ ( if cast_from_int(Y) < 16u then
+ Result = unchecked_right_shift(X, Y)
+ else
+ Msg = "int16.(>>): second operand is out of range",
+ throw(math.domain_error(Msg))
+ ).
+
+%---------------------------------------------------------------------------%
+
+:- pragma inline(even/1).
+even(X) :-
+ (X /\ cast_from_int(1)) = cast_from_int(0).
+
+:- pragma inline(odd/1).
+odd(X) :-
+ (X /\ cast_from_int(1)) \= cast_from_int(0).
+
+%---------------------------------------------------------------------------%
+
+min_int16 = cast_from_int(-32_768).
+
+max_int16 = cast_from_int(32_767).
+
+%---------------------------------------------------------------------------%
+
+int16_to_doc(X) = str(string.int16_to_string(X)).
+
+%---------------------------------------------------------------------------%
+:- end_module int16.
+%---------------------------------------------------------------------------%
diff --git a/library/int32.m b/library/int32.m
index da40d0290..84a072b19 100644
--- a/library/int32.m
+++ b/library/int32.m
@@ -5,16 +5,407 @@
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%---------------------------------------------------------------------------%
+%
+% File: int32.m
+% Main author: juliensf
+% Stability: low.
+%
+% Predicates and functions for dealing with signed 32-bit integer numbers.
+%
+%---------------------------------------------------------------------------%
:- module int32.
:- interface.
- % int32s are NYI -- this module is just a placeholder for their
- % library support.
+:- import_module pretty_printer.
+
+%---------------------------------------------------------------------------%
+
+ % from_int(I, I32):
+ % Convert an int to an int32.
+ % Fails if not in [-2147483648, 2147483647].
%
-:- type placeholder_int32 ---> placeholder_int32.
+:- pred from_int(int::in, int32::out) is semidet.
+
+ % As above, but throw an exception instead of failing.
+ %
+:- func det_from_int(int) = int32.
+
+:- func cast_from_int(int) = int32.
+
+:- func cast_from_uint32(uint32) = int32.
+
+:- func to_int(int32) = int.
%---------------------------------------------------------------------------%
-:- end_module int32.
+
+ % Less than.
+ %
+:- pred (int32::in) < (int32::in) is semidet.
+
+ % Greater than.
+ %
+:- pred (int32::in) > (int32::in) is semidet.
+
+ % Less than or equal.
+ %
+:- pred (int32::in) =< (int32::in) is semidet.
+
+ % Greater than or equal.
+ %
+:- pred (int32::in) >= (int32::in) is semidet.
+
%---------------------------------------------------------------------------%
+ % Unary plus.
+ %
+:- func + (int32::in) = (int32::uo) is det.
+
+ % Unary minus.
+ %
+:- func - (int32::in) = (int32::uo) is det.
+
+ % Addition.
+ %
+:- func int32 + int32 = int32.
+:- mode in + in = uo is det.
+:- mode uo + in = in is det.
+:- mode in + uo = in is det.
+
+:- func plus(int32, int32) = int32.
+
+ % Subtraction.
+ %
+:- func int32 - int32 = int32.
+:- mode in - in = uo is det.
+:- mode uo - in = in is det.
+:- mode in - uo = in is det.
+
+:- func minus(int32, int32) = int32.
+
+ % Multiplication.
+ %
+:- func (int32::in) * (int32::in) = (int32::uo) is det.
+:- func times(int32, int32) = int32.
+
+ % Maximum.
+ %
+:- func max(int32, int32) = int32.
+
+ % Minimum.
+ %
+:- func min(int32, int32) = int32.
+
+ % Flooring integer division.
+ % Truncates towards minus infinity, e.g. (-10_i32) div 3_i32 = (-4_i32).
+ %
+ % Throws a `math.domain_error' exception if the right operand is zero.
+ %
+:- func (int32::in) div (int32::in) = (int32::uo) is det.
+
+ % Truncating integer division.
+ % Truncates towards zero, e.g. (-10_i32) // 3_i32 = (-3_i32).
+ % `div' has nicer mathematical properties for negative operands,
+ % but `//' is typically more efficient.
+ %
+ % Throws a `math.domain_error' exception if the right operand is zero.
+ %
+:- func (int32::in) // (int32::in) = (int32::uo) is det.
+
+ % (/)/2 is a synonym for (//)/2.
+ %
+:- func (int32::in) / (int32::in) = (int32::uo) is det.
+
+ % unchecked_quotient(X, Y) is the same as X // Y, but the behaviour
+ % is undefined if the right operand is zero.
+ %
+:- func unchecked_quotient(int32::in, int32::in) = (int32::uo) is det.
+
+ % Modulus.
+ % X mod Y = X - (X div Y) * Y
+ %
+ % Throws a `math.domain_error' exception if the right operand is zero.
+ %
+:- func (int32::in) mod (int32::in) = (int32::uo) is det.
+
+ % Remainder.
+ % X rem Y = X - (X // Y) * Y.
+ %
+ % Throws a `math.domain_error/` exception if the right operand is zero.
+ %
+:- func (int32::in) rem (int32::in) = (int32::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(int32::in, int32::in) = (int32::uo) is det.
+
+ % Left shift.
+ % X << Y returns X "left shifted" by Y bits.
+ % The bit positions vacated by the shift are filled by zeros.
+ % Throws an exception if Y is not in [0, 32).
+ %
+:- func (int32::in) << (int::in) = (int32::uo) is det.
+
+ % unchecked_lift_shift(X, Y) is the same as X << Y except that the
+ % behaviour is undefined if Y is not in [0, 32).
+ % It will typically be be implemented more efficiently than X << Y.
+ %
+:- func unchecked_left_shift(int32::in, int::in) = (int32::uo) is det.
+
+ % Right shift.
+ % X >> Y returns X "right shifted" by Y bits.
+ % The bit positions vacated by the shift are filled by the sign bit.
+ % Throws an exception if Y is not in [0, 32).
+ %
+:- func (int32::in) >> (int::in) = (int32::uo) is det.
+
+ % unchecked_right_shift(X, Y) is the same as X >> Y except that the
+ % behaviour is undefined if Y is not in [0, bits_per_int32).
+ % It will typically be implemented more efficiently than X >> Y.
+ %
+:- func unchecked_right_shift(int32::in, int::in) = (int32::uo) is det.
+
+ % even(X) is equivalent to (X mod 2 = 0).
+ %
+:- pred even(int32::in) is semidet.
+
+ % odd(X) is equivalent to (not even(X)), i.e. (X mod 2 = 1).
+ %
+:- pred odd(int32::in) is semidet.
+
+ % Bitwise and.
+ %
+:- func (int32::in) /\ (int32::in) = (int32::uo) is det.
+
+ % Bitwise or.
+ %
+:- func (int32::in) \/ (int32::in) = (int32::uo) is det.
+
+ % Bitwise exclusive or (xor).
+ %
+:- func xor(int32, int32) = int32.
+:- mode xor(in, in) = uo is det.
+:- mode xor(in, uo) = in is det.
+:- mode xor(uo, in) = in is det.
+
+ % Bitwise complement.
+ %
+:- func \ (int32::in) = (int32::uo) is det.
+
+ % Convert a int32 to a pretty_printer.doc for formatting.
+ %
+:- func int32_to_doc(int32) = pretty_printer.doc.
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module exception.
+:- import_module math.
+:- import_module require.
+:- import_module string.
+:- import_module uint.
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ from_int(A::in, B::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+ if (A > (MR_Integer) INT32_MAX) {
+ SUCCESS_INDICATOR = MR_FALSE;
+ } else if (A < (MR_Integer) INT32_MIN) {
+ SUCCESS_INDICATOR = MR_FALSE;
+ } else {
+ B = (int32_t) A;
+ SUCCESS_INDICATOR = MR_TRUE;
+ }
+").
+
+:- pragma foreign_proc("C#",
+ from_int(A::in, B::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ B = A; // Mercury's 'int' type in the C# grade is 32-bits.
+ SUCCESS_INDICATOR = true;
+").
+
+:- pragma foreign_proc("Java",
+ from_int(A::in, B::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ B = A; // Mercury's 'int' type in the Java grade is 32-bits.
+ SUCCESS_INDICATOR = true;
+").
+
+det_from_int(I) = U :-
+ ( if from_int(I, U0) then
+ U = U0
+ else
+ error("int32.det_from_int: cannot convert int to int32")
+ ).
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ cast_from_int(I::in) = (I32::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
+ does_not_affect_liveness],
+"
+ I32 = (int32_t) I;
+").
+
+:- pragma foreign_proc("C#",
+ cast_from_int(I::in) = (I32::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I32 = I;
+").
+
+:- pragma foreign_proc("Java",
+ cast_from_int(I::in) = (I32::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I32 = I;
+").
+
+:- pragma no_determinism_warning(cast_from_int/1).
+cast_from_int(_) = _ :-
+ sorry($module, "int32.cast_from_int/1 NYI for Erlang").
+
+%---------------------------------------------------------------------------%
+
+:- 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],
+"
+ I32 = U32;
+").
+
+:- pragma foreign_proc("C#",
+ cast_from_uint32(U32::in) = (I32::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I32 = (int) U32;
+").
+
+:- pragma foreign_proc("Java",
+ cast_from_uint32(U32::in) = (I32::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I32 = U32;
+").
+
+:- pragma no_determinism_warning(cast_from_uint32/1).
+cast_from_uint32(_) = _ :-
+ sorry($module, "int32.cast_from_uint32/1 NYI for Erlang").
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ to_int(I32::in) = (I::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+ I = I32;
+").
+
+:- pragma foreign_proc("C#",
+ to_int(I32::in) = (I::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I = I32;
+").
+
+:- pragma foreign_proc("Java",
+ to_int(I32::in) = (I::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I = I32;
+").
+
+:- pragma no_determinism_warning(to_int/1).
+to_int(_) = _ :-
+ sorry($module, "int32.to_int/1 NYI for Erlang").
+
+%---------------------------------------------------------------------------%
+
+X div Y = Div :-
+ Trunc = X // Y,
+ ( if
+ ( X >= cast_from_int(0), Y >= cast_from_int(0)
+ ; X < cast_from_int(0), Y < cast_from_int(0)
+ ; X rem Y = cast_from_int(0)
+ )
+ then
+ Div = Trunc
+ else
+ Div = Trunc - cast_from_int(1)
+ ).
+
+:- pragma inline('//'/2).
+X // Y = Div :-
+ ( if Y = cast_from_int(0) then
+ throw(math.domain_error("int32.'//': division by zero"))
+ else
+ Div = unchecked_quotient(X, Y)
+ ).
+
+:- pragma inline('/'/2).
+X / Y = X // Y.
+
+X mod Y = X - (X div Y) * Y.
+
+:- pragma inline(rem/2).
+X rem Y = Rem :-
+ ( if Y = cast_from_int(0) then
+ throw(math.domain_error("int32.rem: division by zero"))
+ else
+ Rem = unchecked_rem(X, Y)
+ ).
+
+%---------------------------------------------------------------------------%
+
+X << Y = Result :-
+ ( if cast_from_int(Y) < 32u then
+ Result = unchecked_left_shift(X, Y)
+ else
+ Msg = "uint.(<<): second operand is out of range",
+ throw(math.domain_error(Msg))
+ ).
+
+X >> Y = Result :-
+ ( if cast_from_int(Y) < 32u then
+ Result = unchecked_right_shift(X, Y)
+ else
+ Msg = "uint.(>>): second operand is out of range",
+ throw(math.domain_error(Msg))
+ ).
+
+%---------------------------------------------------------------------------%
+
+max(X, Y) =
+ ( if X > Y then X else Y ).
+
+min(X, Y) =
+ ( if X < Y then X else Y ).
+
+%---------------------------------------------------------------------------%
+
+:- pragma inline(even/1).
+even(X) :-
+ (X /\ cast_from_int(1)) = cast_from_int(0).
+
+:- pragma inline(odd/1).
+odd(X) :-
+ (X /\ cast_from_int(1)) \= cast_from_int(0).
+
+%---------------------------------------------------------------------------%
+
+int32_to_doc(X) = str(string.int32_to_string(X)).
+
+%---------------------------------------------------------------------------%
+:- end_module int32.
+%---------------------------------------------------------------------------%
diff --git a/library/int8.m b/library/int8.m
index 4144652ca..292cce277 100644
--- a/library/int8.m
+++ b/library/int8.m
@@ -5,16 +5,396 @@
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%---------------------------------------------------------------------------%
+%
+% File: int8.m
+% Main author: juliensf
+% Stability: low.
+%
+% Predicates and functions for dealing with signed 8-bit integer numbers.
+%
+%---------------------------------------------------------------------------%
:- module int8.
:- interface.
- % int8s are NYI -- this module is just a placeholder for their
- % library support.
+:- import_module pretty_printer.
+
+%---------------------------------------------------------------------------%
+
+ % from_int(I, I8):
+ % Convert an int to an int8.
+ % Fails if I is not in [-128, 127].
%
-:- type placeholder_int8 ---> placeholder_int8.
+:- pred from_int(int::in, int8::out) is semidet.
+
+ % As above, but throw an exception instead of failing.
+ %
+:- func det_from_int(int) = int8.
+
+:- func cast_from_int(int) = int8.
+:- func cast_from_uint8(uint8) = int8.
+
+:- func to_int(int8) = int.
%---------------------------------------------------------------------------%
-:- end_module int8.
+
+ % Less than.
+ %
+:- pred (int8::in) < (int8::in) is semidet.
+
+ % Greater than.
+ %
+:- pred (int8::in) > (int8::in) is semidet.
+
+ % Less than or equal.
+ %
+:- pred (int8::in) =< (int8::in) is semidet.
+
+ % Greater than or equal.
+ %
+:- pred (int8::in) >= (int8::in) is semidet.
+
+%---------------------------------------------------------------------------%
+
+ % Maximum.
+ %
+:- func max(int8, int8) = int8.
+
+ % Minimum.
+ %
+:- func min(int8, int8) = int8.
+
+%---------------------------------------------------------------------------%
+
+ % Unary plus.
+ %
+:- func + (int8::in) = (int8::uo) is det.
+
+ % Unary minus.
+ %
+:- func - (int8::in) = (int8::uo) is det.
+
+ % Addition.
+ %
+:- func int8 + int8 = int8.
+:- mode in + in = uo is det.
+:- mode uo + in = in is det.
+:- mode in + uo = in is det.
+
+:- func plus(int8, int8) = int8.
+
+ % Subtraction.
+ %
+:- func int8 - int8 = int8.
+:- mode in - in = uo is det.
+:- mode uo - in = in is det.
+:- mode in - uo = in is det.
+
+:- func minus(int8, int8) = int8.
+
+ % Multiplication.
+ %
+:- func (int8::in) * (int8::in) = (int8::uo) is det.
+:- func times(int8, int8) = int8.
+
+ % Flooring integer division.
+ % Truncates towards minus infinity, e.g. (-10_i8) div 3_i8 = (-4_i8).
+ %
+ % Throws a `math.domain_error' exception if the right operand is zero.
+ %
+:- func (int8::in) div (int8::in) = (int8::uo) is det.
+
+ % Truncating integer division.
+ % Truncates towards zero, e.g. (-10_i8) // 3_i8 = (-3_i8).
+ % `div' has nicer mathematical properties for negative operands,
+ % but `//' is typically more efficient.
+ %
+ % Throws a `math.domain_error' exception if the right operand is zero.
+ %
+:- func (int8::in) // (int8::in) = (int8::uo) is det.
+
+ % (/)/2 is a synonym for (//)/2.
+ %
+:- func (int8::in) / (int8::in) = (int8::uo) is det.
+
+ % unchecked_quotient(X, Y) is the same as X // Y, but the behaviour
+ % is undefined if the right operand is zero.
+ %
+:- func unchecked_quotient(int8::in, int8::in) = (int8::uo) is det.
+
+ % Modulus.
+ % X mod Y = X - (X div Y) * Y
+ %
+ % Throws a `math.domain_error' exception if the right operand is zero.
+ %
+:- func (int8::in) mod (int8::in) = (int8::uo) is det.
+
+ % Remainder.
+ % X rem Y = X - (X // Y) * Y.
+ %
+ % Throws a `math.domain_error/` exception if the right operand is zero.
+ %
+:- func (int8::in) rem (int8::in) = (int8::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(int8::in, int8::in) = (int8::uo) is det.
+
+ % Left shift.
+ % X << Y returns X "left shifted" by Y bits.
+ % The bit positions vacated by the shift are filled by zeros.
+ % Throws an exception if Y is not in [0, 8).
+ %
+:- func (int8::in) << (int::in) = (int8::uo) is det.
+
+ % unchecked_lift_shift(X, Y) is the same as X << Y except that the
+ % behaviour is undefined if Y is not in [0, 8).
+ % It will typically be be implemented more efficiently than X << Y.
+ %
+:- func unchecked_left_shift(int8::in, int::in) = (int8::uo) is det.
+
+ % Right shift.
+ % X >> Y returns X "right shifted" by Y bits.
+ % The bit positions vacated by the shift are filled by the sign bit.
+ % Throws an exception if Y is not in [0, 8).
+ %
+:- func (int8::in) >> (int::in) = (int8::uo) is det.
+
+ % unchecked_right_shift(X, Y) is the same as X >> Y except that the
+ % behaviour is undefined if Y is not in [0, 8).
+ % It will typically be implemented more efficiently than X >> Y.
+ %
+:- func unchecked_right_shift(int8::in, int::in) = (int8::uo) is det.
+
+ % even(X) is equivalent to (X mod 2i8 = 0i8).
+ %
+:- pred even(int8::in) is semidet.
+
+ % odd(X) is equivalent to (not even(X)), i.e. (X mod 2i8 = 1i8).
+ %
+:- pred odd(int8::in) is semidet.
+
%---------------------------------------------------------------------------%
+ % Bitwise complement.
+ %
+:- func \ (int8::in) = (int8::uo) is det.
+
+ % Bitwise and.
+ %
+:- func (int8::in) /\ (int8::in) = (int8::uo) is det.
+
+ % Bitwise or.
+ %
+:- func (int8::in) \/ (int8::in) = (int8::uo) is det.
+
+ % Bitwise exclusive or (xor).
+ %
+:- func xor(int8, int8) = int8.
+:- mode xor(in, in) = uo is det.
+:- mode xor(in, uo) = in is det.
+:- mode xor(uo, in) = in is det.
+
+%---------------------------------------------------------------------------%
+
+:- func min_int8 = int8.
+
+:- func max_int8 = int8.
+
+%---------------------------------------------------------------------------%
+
+ % Convert an int8 to a pretty_printer.doc for formatting.
+ %
+:- func int8_to_doc(int8) = pretty_printer.doc.
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module exception.
+:- import_module int.
+:- import_module math.
+:- import_module require.
+:- import_module string.
+:- import_module uint.
+
+%---------------------------------------------------------------------------%
+
+from_int(I, I8) :-
+ I >= -128,
+ I =< 127,
+ I8 = cast_from_int(I).
+
+det_from_int(I) = I8 :-
+ ( if from_int(I, I8Prime) then
+ I8 = I8Prime
+ else
+ error("int8.det_from_int: cannot convert int to int8")
+ ).
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ cast_from_int(I::in) = (I8::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
+ does_not_affect_liveness],
+"
+ I8 = (int8_t) I;
+").
+
+:- pragma foreign_proc("C#",
+ cast_from_int(I::in) = (I8::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I8 = (sbyte) I;
+").
+
+:- pragma foreign_proc("Java",
+ cast_from_int(I::in) = (I8::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I8 = (byte) I;
+").
+
+:- pragma no_determinism_warning(cast_from_int/1).
+cast_from_int(_) = _ :-
+ sorry($module, "int8.cast_from_int/1 NYI for Erlang").
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ cast_from_uint8(U8::in) = (I8::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
+ does_not_affect_liveness],
+"
+ I8 = U8;
+").
+
+:- pragma foreign_proc("C#",
+ cast_from_uint8(U8::in) = (I8::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I8 = (sbyte) U8;
+").
+
+:- pragma foreign_proc("Java",
+ cast_from_uint8(U8::in) = (I8::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I8 = U8;
+").
+
+:- pragma no_determinism_warning(cast_from_uint8/1).
+cast_from_uint8(_) = _ :-
+ sorry($module, "int8.cast_from_uint8/1 NYI for Erlang").
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ to_int(I8::in) = (I::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+ I = I8;
+").
+
+:- pragma foreign_proc("C#",
+ to_int(I8::in) = (I::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I = I8;
+").
+
+:- pragma foreign_proc("Java",
+ to_int(I8::in) = (I::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I = I8;
+").
+
+%---------------------------------------------------------------------------%
+
+X div Y = Div :-
+ Trunc = X // Y,
+ ( if
+ ( X >= cast_from_int(0), Y >= cast_from_int(0)
+ ; X < cast_from_int(0), Y < cast_from_int(0)
+ ; X rem Y = cast_from_int(0)
+ )
+ then
+ Div = Trunc
+ else
+ Div = Trunc - cast_from_int(1)
+ ).
+
+:- pragma inline('//'/2).
+X // Y = Div :-
+ ( if Y = cast_from_int(0) then
+ throw(math.domain_error("int8.'//': division by zero"))
+ else
+ Div = unchecked_quotient(X, Y)
+ ).
+
+:- pragma inline('/'/2).
+X / Y = X // Y.
+
+X mod Y = X - (X div Y) * Y.
+
+:- pragma inline(rem/2).
+X rem Y = Rem :-
+ ( if Y = cast_from_int(0) then
+ throw(math.domain_error("int8.rem: division by zero"))
+ else
+ Rem = unchecked_rem(X, Y)
+ ).
+
+%---------------------------------------------------------------------------%
+
+X << Y = Result :-
+ ( if cast_from_int(Y) < 8u then
+ Result = unchecked_left_shift(X, Y)
+ else
+ Msg = "int8.(<<): second operand is out of range",
+ throw(math.domain_error(Msg))
+ ).
+
+X >> Y = Result :-
+ ( if cast_from_int(Y) < 8u then
+ Result = unchecked_right_shift(X, Y)
+ else
+ Msg = "int8.(>>): second operand is out of range",
+ throw(math.domain_error(Msg))
+ ).
+
+%---------------------------------------------------------------------------%
+
+max(X, Y) =
+ ( if X > Y then X else Y ).
+
+min(X, Y) =
+ ( if X < Y then X else Y ).
+
+%---------------------------------------------------------------------------%
+
+:- pragma inline(even/1).
+even(X) :-
+ (X /\ cast_from_int(1)) = cast_from_int(0).
+
+:- pragma inline(odd/1).
+odd(X) :-
+ (X /\ cast_from_int(1)) \= cast_from_int(0).
+
+%---------------------------------------------------------------------------%
+
+min_int8 = cast_from_int(-128).
+
+max_int8 = cast_from_int(127).
+
+%---------------------------------------------------------------------------%
+
+int8_to_doc(X) = str(string.int8_to_string(X)).
+
+%---------------------------------------------------------------------------%
+:- end_module int8.
+%---------------------------------------------------------------------------%
diff --git a/library/integer.m b/library/integer.m
index 630067a1f..5209fab61 100644
--- a/library/integer.m
+++ b/library/integer.m
@@ -191,6 +191,60 @@
%
:- func det_to_uint(integer) = uint.
+ % Convert an integer to an int8.
+ % Fails if the integer is not in the range [-128, 127].
+ %
+:- pred to_int8(integer::in, int8::out) is semidet.
+
+ % As above, but throws an exception rather than failing.
+ %
+:- func det_to_int8(integer) = int8.
+
+ % Convert an integer to a uint8.
+ % Fails if the integer is not in the range [0, 255].
+ %
+:- pred to_uint8(integer::in, uint8::out) is semidet.
+
+ % As above, but throws an exception rather than failing.
+ %
+:- func det_to_uint8(integer) = uint8.
+
+ % Convert an integer to an int16.
+ % Fails if the integer is not in the range [-32768, 32767].
+ %
+:- pred to_int16(integer::in, int16::out) is semidet.
+
+ % As above, but throws an exception rather than failing.
+ %
+:- func det_to_int16(integer) = int16.
+
+ % Convert an integer to a uint16.
+ % Fails if the integer is not in the range [0, 65535].
+ %
+:- pred to_uint16(integer::in, uint16::out) is semidet.
+
+ % As above, but throws an exception rather than failing.
+ %
+:- func det_to_uint16(integer) = uint16.
+
+ % Convert an integer to an int32.
+ % Fails if the integer is not in the range [-2147483648, 2147483647].
+ %
+:- pred to_int32(integer::in, int32::out) is semidet.
+
+ % As above, but throws an exception rather than failing.
+ %
+:- func det_to_int32(integer) = int32.
+
+ % Convert an integer to a uint32.
+ % Fails if the integer is not in range [0, 4294967295].
+ %
+:- pred to_uint32(integer::in, uint32::out) is semidet.
+
+ % As above, but throws an exception rather than failing.
+ %
+:- func det_to_uint32(integer) = uint32.
+
%---------------------%
% Convert an integer to a float.
@@ -214,7 +268,7 @@
%---------------------------------------------------------------------------%
- % Convert int to integer.
+ % Convert an int to integer.
%
:- func integer(int) = integer.
@@ -222,6 +276,30 @@
%
:- func from_uint(uint) = integer.
+ % Convert an int8 to an integer.
+ %
+:- func from_int8(int8) = integer.
+
+ % Convert a uint8 to an integer.
+ %
+:- func from_uint8(uint8) = integer.
+
+ % Convert an int16 to an integer.
+ %
+:- func from_int16(int16) = integer.
+
+ % Convert a uint16 to an integer.
+ %
+:- func from_uint16(uint16) = integer.
+
+ % Convert an int32 to an integer.
+ %
+:- func from_int32(int32) = integer.
+
+ % Convert a uint32 to an integer.
+ %
+:- func from_uint32(uint32) = integer.
+
% Convert a string to an integer. The string must contain only digits
% [0-9], optionally preceded by a plus or minus sign. If the string does
% not match this syntax, then the predicate fails.
@@ -257,11 +335,17 @@
:- import_module exception.
:- import_module float.
:- import_module int.
+:- import_module int8.
+:- import_module int16.
+:- import_module int32.
:- import_module list.
:- import_module math.
:- import_module require.
:- import_module string.
:- import_module uint.
+:- import_module uint8.
+:- import_module uint16.
+:- import_module uint32.
%---------------------------------------------------------------------------%
@@ -406,6 +490,13 @@ chop_uint(N, Div, Mod) :-
Div = N `uint.unchecked_right_shift` log2base,
Mod = N /\ cast_from_int(basemask).
+:- pred chop_uint32(uint32::in, uint32::out, uint32::out) is det.
+
+chop_uint32(N, Div, Mod) :-
+ % See the comments in chop/3.
+ Div = N `uint32.unchecked_right_shift` log2base,
+ Mod = N /\ cast_from_int(basemask).
+
%---------------------%
:- func det_first(integer) = digit.
@@ -1320,6 +1411,98 @@ det_to_uint(Integer) = UInt :-
%---------------------------------------------------------------------------%
+to_int8(Integer, Int8) :-
+ Integer = i(_Sign, [Digit]),
+ int8.from_int(Digit, Int8).
+
+det_to_int8(Integer) = Int8 :-
+ ( if integer.to_int8(Integer, Int8Prime) then
+ Int8 = Int8Prime
+ else
+ throw(math.domain_error(
+ "integer.det_to_int8: domain error (conversion would overflow)"))
+ ).
+
+%---------------------------------------------------------------------------%
+
+to_uint8(Integer, UInt8) :-
+ Integer = i(_Sign, [Digit]),
+ uint8.from_int(Digit, UInt8).
+
+det_to_uint8(Integer) = UInt8 :-
+ ( if integer.to_uint8(Integer, UInt8Prime) then
+ UInt8 = UInt8Prime
+ else
+ throw(math.domain_error(
+ "integer.det_to_uint8: domain error (conversion would overflow)"))
+ ).
+
+%---------------------------------------------------------------------------%
+
+to_int16(Integer, Int16) :-
+ integer.to_int(Integer, Int),
+ int16.from_int(Int, Int16).
+
+det_to_int16(Integer) = Int16 :-
+ ( if integer.to_int16(Integer, Int16Prime) then
+ Int16 = Int16Prime
+ else
+ throw(math.domain_error(
+ "integer.det_to_int16: domain error (conversion would overflow)"))
+ ).
+
+%---------------------------------------------------------------------------%
+
+to_uint16(Integer, UInt16) :-
+ integer.to_int(Integer, Int),
+ uint16.from_int(Int, UInt16).
+
+det_to_uint16(Integer) = UInt16 :-
+ ( if integer.to_uint16(Integer, UInt16Prime) then
+ UInt16 = UInt16Prime
+ else
+ throw(math.domain_error(
+ "integer.det_to_uint16: domain error (conversion would overflow)"))
+ ).
+
+%---------------------------------------------------------------------------%
+
+to_int32(Integer, Int32) :-
+ integer.to_int(Integer, Int),
+ int32.from_int(Int, Int32).
+
+det_to_int32(Integer) = Int32 :-
+ ( if integer.to_int32(Integer, Int32Prime) then
+ Int32 = Int32Prime
+ else
+ throw(math.domain_error(
+ "integer.det_to_int32: domain error (conversion would overflow"))
+ ).
+
+%---------------------------------------------------------------------------%
+
+to_uint32(Integer, UInt32) :-
+ Integer >= integer.zero,
+ Integer =< integer.from_uint32(uint32.max_uint32),
+ Integer = i(_Sign, Digits),
+ UInt32 = uint32_list(Digits, uint32.cast_from_int(0)).
+
+:- func uint32_list(list(int), uint32) = uint32.
+
+uint32_list([], Accum) = Accum.
+uint32_list([H | T], Accum) =
+ uint32_list(T, Accum * cast_from_int(base) + cast_from_int(H)).
+
+det_to_uint32(Integer) = UInt32 :-
+ ( if integer.to_uint32(Integer, UInt32Prime) then
+ UInt32 = UInt32Prime
+ else
+ throw(math.domain_error(
+ "integer.det_to_uint32: domain error (conversion would overflow"))
+ ).
+
+%---------------------------------------------------------------------------%
+
float(i(_, List)) = float_list(float.float(base), 0.0, List).
:- func float_list(float, float, list(int)) = float.
@@ -1588,6 +1771,53 @@ uint_to_digits_2(U, Tail) = Result :-
i(Length + 1, [cast_to_int(Mod) | Digits]))
).
+%---------------------------------------------------------------------------%
+
+from_int8(I8) = Integer :-
+ I = int8.to_int(I8),
+ Integer = integer(I).
+
+from_uint8(U8) = Integer :-
+ I = uint8.to_int(U8),
+ Integer = integer(I).
+
+from_int16(I16) = Integer :-
+ I = int16.to_int(I16),
+ Integer = integer(I).
+
+from_uint16(U16) = Integer :-
+ I = uint16.to_int(U16),
+ Integer = integer(I).
+
+from_int32(I32) = Integer :-
+ I = int32.to_int(I32),
+ Integer = integer(I).
+
+from_uint32(U32) = Integer :-
+ ( if U32 = cast_from_int(0) then
+ Integer = integer.zero
+ else if U32 < cast_from_int(base) then
+ Integer = i(1, [cast_to_int(U32)])
+ else
+ Integer = uint32_to_digits(U32)
+ ).
+
+:- func uint32_to_digits(uint32) = integer.
+
+uint32_to_digits(U) = uint32_to_digits_2(U, integer.zero).
+
+:- func uint32_to_digits_2(uint32, integer) = integer.
+
+uint32_to_digits_2(U, Tail) = Result :-
+ ( if U = cast_from_int(0) then
+ Result = Tail
+ else
+ Tail = i(Length, Digits),
+ chop_uint32(U, Div, Mod),
+ Result = uint32_to_digits_2(Div,
+ i(Length + 1, [cast_to_int(Mod) | Digits]))
+ ).
+
%---------------------------------------------------------------------------%
%
% Converting strings to integers.
diff --git a/library/io.m b/library/io.m
index 243b611ac..51260413c 100644
--- a/library/io.m
+++ b/library/io.m
@@ -2,7 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 1993-2012 The University of Melbourne.
-% Copyright (C) 2013-2016 The Mercury team.
+% Copyright (C) 2013-2017 The Mercury team.
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%---------------------------------------------------------------------------%
@@ -498,12 +498,30 @@
:- pred write_int(int::in, io::di, io::uo) is det.
:- pred write_int(io.text_output_stream::in, int::in, io::di, io::uo) is det.
+:- pred write_int8(int8::in, io::di, io::uo) is det.
+:- pred write_int8(io.text_output_stream::in, int8::in, io::di, io::uo) is det.
+
+:- pred write_int16(int16::in, io::di, io::uo) is det.
+:- pred write_int16(io.text_output_stream::in, int16::in, io::di, io::uo) is det.
+
+:- pred write_int32(int32::in, io::di, io::uo) is det.
+:- pred write_int32(io.text_output_stream::in, int32::in, io::di, io::uo) is det.
+
% Writes an unsigned integer to the current output stream
% or to the specified output stream.
%
:- pred write_uint(uint::in, io::di, io::uo) is det.
:- pred write_uint(io.text_output_stream::in, uint::in, io::di, io::uo) is det.
+:- pred write_uint8(uint8::in, io::di, io::uo) is det.
+:- pred write_uint8(io.text_output_stream::in, uint8::in, io::di, io::uo) is det.
+
+:- pred write_uint16(uint16::in, io::di, io::uo) is det.
+:- pred write_uint16(io.text_output_stream::in, uint16::in, io::di, io::uo) is det.
+
+:- pred write_uint32(uint32::in, io::di, io::uo) is det.
+:- pred write_uint32(io.text_output_stream::in, uint32::in, io::di, io::uo) is det.
+
% Writes a floating point number to the current output stream
% or to the specified output stream.
%
@@ -1523,7 +1541,13 @@
:- instance stream.writer(text_output_stream, char, io).
:- instance stream.writer(text_output_stream, float, io).
:- instance stream.writer(text_output_stream, int, io).
+:- instance stream.writer(text_output_stream, int8, io).
+:- instance stream.writer(text_output_stream, int16, io).
+:- instance stream.writer(text_output_stream, int32, io).
:- instance stream.writer(text_output_stream, uint, io).
+:- instance stream.writer(text_output_stream, uint8, io).
+:- instance stream.writer(text_output_stream, uint16, io).
+:- instance stream.writer(text_output_stream, uint8, io).
:- instance stream.writer(text_output_stream, string, io).
:- instance stream.writer(text_output_stream, univ, io).
:- instance stream.line_oriented(text_output_stream, io).
@@ -7762,10 +7786,34 @@ write_int(Val, !IO) :-
output_stream(Stream, !IO),
write_int(Stream, Val, !IO).
+write_int8(Val, !IO) :-
+ output_stream(Stream, !IO),
+ write_int8(Stream, Val, !IO).
+
+write_int16(Val, !IO) :-
+ output_stream(Stream, !IO),
+ write_int16(Stream, Val, !IO).
+
+write_int32(Val, !IO) :-
+ output_stream(Stream, !IO),
+ write_int32(Stream, Val, !IO).
+
write_uint(Val, !IO) :-
output_stream(Stream, !IO),
write_uint(Stream, Val, !IO).
+write_uint8(Val, !IO) :-
+ output_stream(Stream, !IO),
+ write_uint8(Stream, Val, !IO).
+
+write_uint16(Val, !IO) :-
+ output_stream(Stream, !IO),
+ write_uint16(Stream, Val, !IO).
+
+write_uint32(Val, !IO) :-
+ output_stream(Stream, !IO),
+ write_uint32(Stream, Val, !IO).
+
write_float(Val, !IO) :-
output_stream(Stream, !IO),
write_float(Stream, Val, !IO).
@@ -7942,6 +7990,60 @@ write_int(output_stream(Stream), Val, !IO) :-
}
").
+write_int8(output_stream(Stream), Val, !IO) :-
+ write_int8_2(Stream, Val, Error, !IO),
+ throw_on_output_error(Error, !IO).
+
+:- pred write_int8_2(stream::in, int8::in, system_error::out, io::di, io::uo)
+ is det.
+:- pragma foreign_proc("C",
+ write_int8_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe,
+ does_not_affect_liveness, no_sharing],
+"
+ if (ML_fprintf(Stream, ""%d"", Val) < 0) {
+ Error = errno;
+ } else {
+ Error = 0;
+ }
+").
+
+write_int16(output_stream(Stream), Val, !IO) :-
+ write_int16_2(Stream, Val, Error, !IO),
+ throw_on_output_error(Error, !IO).
+
+:- pred write_int16_2(stream::in, int16::in, system_error::out, io::di, io::uo)
+ is det.
+:- pragma foreign_proc("C",
+ write_int16_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe,
+ does_not_affect_liveness, no_sharing],
+"
+ if (ML_fprintf(Stream, ""%d"", Val) < 0) {
+ Error = errno;
+ } else {
+ Error = 0;
+ }
+").
+
+write_int32(output_stream(Stream), Val, !IO) :-
+ write_int32_2(Stream, Val, Error, !IO),
+ throw_on_output_error(Error, !IO).
+
+:- pred write_int32_2(stream::in, int32::in, system_error::out, io::di, io::uo)
+ is det.
+:- pragma foreign_proc("C",
+ write_int32_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe,
+ does_not_affect_liveness, no_sharing],
+"
+ if (ML_fprintf(Stream, ""%d"", Val) < 0) {
+ Error = errno;
+ } else {
+ Error = 0;
+ }
+").
+
write_uint(output_stream(Stream), Val, !IO) :-
write_uint_2(Stream, Val, Error, !IO),
throw_on_output_error(Error, !IO).
@@ -7960,6 +8062,60 @@ write_uint(output_stream(Stream), Val, !IO) :-
}
").
+write_uint8(output_stream(Stream), Val, !IO) :-
+ write_uint8_2(Stream, Val, Error, !IO),
+ throw_on_output_error(Error, !IO).
+
+:- pred write_uint8_2(stream::in, uint8::in, system_error::out, io::di, io::uo)
+ is det.
+:- pragma foreign_proc("C",
+ write_uint8_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe,
+ does_not_affect_liveness, no_sharing],
+"
+ if (ML_fprintf(Stream, ""%u"", Val) < 0) {
+ Error = errno;
+ } else {
+ Error = 0;
+ }
+").
+
+write_uint16(output_stream(Stream), Val, !IO) :-
+ write_uint16_2(Stream, Val, Error, !IO),
+ throw_on_output_error(Error, !IO).
+
+:- pred write_uint16_2(stream::in, uint16::in, system_error::out, io::di, io::uo)
+ is det.
+:- pragma foreign_proc("C",
+ write_uint16_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe,
+ does_not_affect_liveness, no_sharing],
+"
+ if (ML_fprintf(Stream, ""%u"", Val) < 0) {
+ Error = errno;
+ } else {
+ Error = 0;
+ }
+").
+
+write_uint32(output_stream(Stream), Val, !IO) :-
+ write_uint32_2(Stream, Val, Error, !IO),
+ throw_on_output_error(Error, !IO).
+
+:- pred write_uint32_2(stream::in, uint32::in, system_error::out, io::di, io::uo)
+ is det.
+:- pragma foreign_proc("C",
+ write_uint32_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe,
+ does_not_affect_liveness, no_sharing],
+"
+ if (ML_fprintf(Stream, ""%u"", Val) < 0) {
+ Error = errno;
+ } else {
+ Error = 0;
+ }
+").
+
write_float(output_stream(Stream), Val, !IO) :-
write_float_2(Stream, Val, Error, !IO),
throw_on_output_error(Error, !IO).
@@ -8189,6 +8345,78 @@ flush_binary_output(binary_output_stream(Stream), !IO) :-
}
").
+:- pragma foreign_proc("C#",
+ write_int8_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ try {
+ io.mercury_print_string(Stream, Val.ToString());
+ Error = null;
+ } catch (System.SystemException e) {
+ Error = e;
+ }
+").
+
+:- pragma foreign_proc("C#",
+ write_int16_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ try {
+ io.mercury_print_string(Stream, Val.ToString());
+ Error = null;
+ } catch (System.SystemException e) {
+ Error = e;
+ }
+").
+
+:- pragma foreign_proc("C#",
+ write_int32_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ try {
+ io.mercury_print_string(Stream, Val.ToString());
+ Error = null;
+ } catch (System.SystemException e) {
+ Error = e;
+ }
+").
+
+:- pragma foreign_proc("C#",
+ write_uint8_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ try {
+ io.mercury_print_string(Stream, Val.ToString());
+ Error = null;
+ } catch (System.SystemException e) {
+ Error = e;
+ }
+").
+
+:- pragma foreign_proc("C#",
+ write_uint16_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ try {
+ io.mercury_print_string(Stream, Val.ToString());
+ Error = null;
+ } catch (System.SystemException e) {
+ Error = e;
+ }
+").
+
+:- pragma foreign_proc("C#",
+ write_uint32_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ try {
+ io.mercury_print_string(Stream, Val.ToString());
+ Error = null;
+ } catch (System.SystemException e) {
+ Error = e;
+ }
+").
+
:- pragma foreign_proc("C#",
write_byte_2(Stream::in, Byte::in, Error::out, _IO0::di, _IO::uo),
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
@@ -8292,7 +8520,69 @@ flush_binary_output(binary_output_stream(Stream), !IO) :-
").
:- pragma foreign_proc("Java",
- write_uint_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ write_int8_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ try {
+ ((io.MR_TextOutputFile) Stream).write(String.valueOf(Val));
+ Error = null;
+ } catch (java.io.IOException e) {
+ Error = e;
+ }
+").
+
+:- pragma foreign_proc("Java",
+ write_int16_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ try {
+ ((io.MR_TextOutputFile) Stream).write(String.valueOf(Val));
+ Error = null;
+ } catch (java.io.IOException e) {
+ Error = e;
+ }
+").
+
+:- pragma foreign_proc("Java",
+ write_int32_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ try {
+ ((io.MR_TextOutputFile) Stream).write(String.valueOf(Val));
+ Error = null;
+ } catch (java.io.IOException e) {
+ Error = e;
+ }
+").
+
+:- pragma foreign_proc("Java",
+ write_uint8_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ try {
+ ((io.MR_TextOutputFile) Stream).write(
+ java.lang.Integer.toString(Val & 0xff));
+ Error = null;
+ } catch (java.io.IOException e) {
+ Error = e;
+ }
+").
+
+:- pragma foreign_proc("Java",
+ write_uint16_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ try {
+ ((io.MR_TextOutputFile) Stream).write(
+ java.lang.Integer.toString(Val & 0xffff));
+ Error = null;
+ } catch (java.io.IOException e) {
+ Error = e;
+ }
+").
+
+:- pragma foreign_proc("Java",
+ write_uint32_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
[will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
"
try {
@@ -8424,6 +8714,60 @@ flush_binary_output(binary_output_stream(Stream), !IO) :-
Error = ok
").
+:- pragma foreign_proc("Erlang",
+ write_int8_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ mercury__io:mercury_write_int(Stream, Val),
+ % mercury_write_int does not return errors yet.
+ Error = ok
+").
+
+:- pragma foreign_proc("Erlang",
+ write_int16_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ mercury__io:mercury_write_int(Stream, Val),
+ % mercury_write_int does not return errors yet.
+ Error = ok
+").
+
+:- pragma foreign_proc("Erlang",
+ write_int32_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ mercury__io:mercury_write_int(Stream, Val),
+ % mercury_write_int does not return errors yet.
+ Error = ok
+").
+
+:- pragma foreign_proc("Erlang",
+ write_uint8_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ mercury__io:mercury_write_int(Stream, Val),
+ % mercury_write_int does not return errors yet.
+ Error = ok
+").
+
+:- pragma foreign_proc("Erlang",
+ write_uint16_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ mercury__io:mercury_write_int(Stream, Val),
+ % mercury_write_int does not return errors yet.
+ Error = ok
+").
+
+:- pragma foreign_proc("Erlang",
+ write_uint32_2(Stream::in, Val::in, Error::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
+"
+ mercury__io:mercury_write_int(Stream, Val),
+ % mercury_write_int does not return errors yet.
+ Error = ok
+").
+
:- pragma foreign_proc("Erlang",
write_string_2(Stream::in, Message::in, Error::out, _IO0::di, _IO::uo),
[will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
@@ -11243,12 +11587,48 @@ result_to_stream_result(error(Error)) = error(Error).
pred(put/4) is write_int
].
+:- instance stream.writer(output_stream, int8, io)
+ where
+[
+ pred(put/4) is write_int8
+].
+
+:- instance stream.writer(output_stream, int16, io)
+ where
+[
+ pred(put/4) is write_int16
+].
+
+:- instance stream.writer(output_stream, int32, io)
+ where
+[
+ pred(put/4) is write_int32
+].
+
:- instance stream.writer(output_stream, uint, io)
where
[
pred(put/4) is write_uint
].
+:- instance stream.writer(output_stream, uint8, io)
+ where
+[
+ pred(put/4) is write_uint8
+].
+
+:- instance stream.writer(output_stream, uint16, io)
+ where
+[
+ pred(put/4) is write_uint16
+].
+
+:- instance stream.writer(output_stream, uint32, io)
+ where
+[
+ pred(put/4) is write_uint32
+].
+
:- instance stream.writer(output_stream, string, io)
where
[
diff --git a/library/pprint.m b/library/pprint.m
index 8424353d3..b2897d3f9 100644
--- a/library/pprint.m
+++ b/library/pprint.m
@@ -2,6 +2,7 @@
% vim:ts=4 sw=4 expandtab tw=0 wm=0 ft=mercury
%---------------------------------------------------------------------------%
% Copyright (C) 2000-2007, 2010-2011 The University of Melbourne
+% Copyright (C) 2014-2017 The Mercury team.
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%---------------------------------------------------------------------------%
@@ -187,7 +188,12 @@
:- instance doc(doc).
:- instance doc(string).
:- instance doc(int).
+:- instance doc(int8).
+:- instance doc(int16).
+:- instance doc(int32).
:- instance doc(uint).
+:- instance doc(uint8).
+:- instance doc(uint16).
:- instance doc(float).
:- instance doc(char).
@@ -414,12 +420,19 @@ doc(X) = doc(int.max_int, X).
%---------------------------------------------------------------------------%
-:- instance doc(doc) where [ doc(_, Doc) = Doc ].
-:- instance doc(string) where [ doc(_, String) = text(String) ].
-:- instance doc(uint) where [ doc(_, UInt) = text(uint_to_string(UInt))].
-:- instance doc(int) where [ doc(_, Int) = poly(i(Int)) ].
-:- instance doc(float) where [ doc(_, Float) = poly(f(Float)) ].
-:- instance doc(char) where [ doc(_, Char) = poly(c(Char)) ].
+:- instance doc(doc) where [ doc(_, Doc) = Doc ].
+:- instance doc(string) where [ doc(_, String) = text(String) ].
+:- instance doc(int) where [ doc(_, Int) = poly(i(Int)) ].
+:- instance doc(int8) where [ doc(_, Int8) = text(int8_to_string(Int8))].
+:- instance doc(int16) where [ doc(_, Int16) = text(int16_to_string(Int16))].
+:- instance doc(int32) where [ doc(_, Int32) = text(int32_to_string(Int32))].
+:- instance doc(uint) where [ doc(_, UInt) = text(uint_to_string(UInt))].
+:- instance doc(uint8) where [ doc(_, UInt8) = text(uint8_to_string(UInt8))].
+:- instance doc(uint16) where [
+ doc(_, UInt16) = text(uint16_to_string(UInt16))
+].
+:- instance doc(float) where [ doc(_, Float) = poly(f(Float)) ].
+:- instance doc(char) where [ doc(_, Char) = poly(c(Char)) ].
%---------------------------------------------------------------------------%
diff --git a/library/private_builtin.m b/library/private_builtin.m
index 390a5287a..04fa67103 100644
--- a/library/private_builtin.m
+++ b/library/private_builtin.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 1994-2007, 2012 The University of Melbourne.
+% Copyright (C) 2013-2017 The Mercury team.
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%---------------------------------------------------------------------------%
@@ -51,23 +52,23 @@
:- pred builtin_unify_uint(uint::in, uint::in) is semidet.
:- pred builtin_compare_uint(comparison_result::uo, uint::in, uint::in) is det.
-:- pred builtin_unify_int8(T::in, T::in) is semidet.
-:- pred builtin_compare_int8(comparison_result::uo, T::in, T::in) is det.
+:- pred builtin_unify_int8(int8::in, int8::in) is semidet.
+:- pred builtin_compare_int8(comparison_result::uo, int8::in, int8::in) is det.
-:- pred builtin_unify_uint8(T::in, T::in) is semidet.
-:- pred builtin_compare_uint8(comparison_result::uo, T::in, T::in) is det.
+:- pred builtin_unify_uint8(uint8::in, uint8::in) is semidet.
+:- pred builtin_compare_uint8(comparison_result::uo, uint8::in, uint8::in) is det.
-:- pred builtin_unify_int16(T::in, T::in) is semidet.
-:- pred builtin_compare_int16(comparison_result::uo, T::in, T::in) is det.
+:- pred builtin_unify_int16(int16::in, int16::in) is semidet.
+:- pred builtin_compare_int16(comparison_result::uo, int16::in, int16::in) is det.
-:- pred builtin_unify_uint16(T::in, T::in) is semidet.
-:- pred builtin_compare_uint16(comparison_result::uo, T::in, T::in) is det.
+:- pred builtin_unify_uint16(uint16::in, uint16::in) is semidet.
+:- pred builtin_compare_uint16(comparison_result::uo, uint16::in, uint16::in) is det.
-:- pred builtin_unify_int32(T::in, T::in) is semidet.
-:- pred builtin_compare_int32(comparison_result::uo, T::in, T::in) is det.
+:- pred builtin_unify_int32(int32::in, int32::in) is semidet.
+:- pred builtin_compare_int32(comparison_result::uo, int32::in, int32::in) is det.
-:- pred builtin_unify_uint32(T::in, T::in) is semidet.
-:- pred builtin_compare_uint32(comparison_result::uo, T::in, T::in) is det.
+:- pred builtin_unify_uint32(uint32::in, uint32::in) is semidet.
+:- pred builtin_compare_uint32(comparison_result::uo, uint32::in, uint32::in) is det.
:- pred builtin_unify_character(character::in, character::in) is semidet.
:- pred builtin_compare_character(comparison_result::uo, character::in,
@@ -154,13 +155,25 @@
:- import_module char.
:- import_module float.
:- import_module int.
+:- import_module int8.
+:- import_module int16.
+:- import_module int32.
:- import_module uint.
+:- import_module uint8.
+:- import_module uint16.
+:- import_module uint32.
:- import_module require.
:- import_module string.
:- import_module type_desc.
:- pragma inline(builtin_compare_int/3).
:- pragma inline(builtin_compare_uint/3).
+:- pragma inline(builtin_compare_int8/3).
+:- pragma inline(builtin_compare_uint8/3).
+:- pragma inline(builtin_compare_int16/3).
+:- pragma inline(builtin_compare_uint16/3).
+:- pragma inline(builtin_compare_int32/3).
+:- pragma inline(builtin_compare_uint32/3).
:- pragma inline(builtin_compare_character/3).
:- pragma inline(builtin_compare_string/3).
:- pragma inline(builtin_compare_float/3).
@@ -187,88 +200,70 @@ builtin_compare_uint(R, X, Y) :-
R = (>)
).
-builtin_unify_int8(_, _) :-
- ( if semidet_succeed then
- sorry("unify for int8")
- else
- semidet_succeed
- ).
+builtin_unify_int8(X, X).
-builtin_compare_int8(R, _, _) :-
- ( if semidet_succeed then
- sorry("compare for int8")
- else
+builtin_compare_int8(R, X, Y) :-
+ ( if X < Y then
+ R = (<)
+ else if X = Y then
R = (=)
- ).
-
-builtin_unify_uint8(_, _) :-
- ( if semidet_succeed then
- sorry("unify for uint8")
else
- semidet_succeed
+ R = (>)
).
-builtin_compare_uint8(R, _, _) :-
- ( if semidet_succeed then
- sorry("compare for uint8")
- else
- R = (=)
- ).
+builtin_unify_uint8(X, X).
-builtin_unify_int16(_, _) :-
- ( if semidet_succeed then
- sorry("unify for int16")
+builtin_compare_uint8(R, X, Y) :-
+ ( if X < Y then
+ R = (<)
+ else if X = Y then
+ R = (=)
else
- semidet_succeed
+ R = (>)
).
-builtin_compare_int16(R, _, _) :-
- ( if semidet_succeed then
- sorry("compare for int16")
- else
- R = (=)
- ).
+builtin_unify_int16(X, X).
-builtin_unify_uint16(_, _) :-
- ( if semidet_succeed then
- sorry("unify for uint16")
+builtin_compare_int16(R, X, Y) :-
+ ( if X < Y then
+ R = (<)
+ else if X = Y then
+ R = (=)
else
- semidet_succeed
+ R = (>)
).
-builtin_compare_uint16(R, _, _) :-
- ( if semidet_succeed then
- sorry("compare for uint16")
- else
- R = (=)
- ).
+builtin_unify_uint16(X, X).
-builtin_unify_int32(_, _) :-
- ( if semidet_succeed then
- sorry("unify for int32")
+builtin_compare_uint16(R, X, Y) :-
+ ( if X < Y then
+ R = (<)
+ else if X = Y then
+ R = (=)
else
- semidet_succeed
+ R = (>)
).
-builtin_compare_int32(R, _, _) :-
- ( if semidet_succeed then
- sorry("compare for int32")
- else
- R = (=)
- ).
+builtin_unify_int32(X, X).
-builtin_unify_uint32(_, _) :-
- ( if semidet_succeed then
- sorry("unify for uint32")
+builtin_compare_int32(R, X, Y) :-
+ ( if X < Y then
+ R = (<)
+ else if X = Y then
+ R = (=)
else
- semidet_succeed
+ R = (>)
).
-builtin_compare_uint32(R, _, _) :-
- ( if semidet_succeed then
- sorry("compare for uint32")
- else
+builtin_unify_uint32(X, X).
+
+builtin_compare_uint32(R, X, Y) :-
+ ( if X < Y then
+ R = (<)
+ else if X = Y then
R = (=)
+ else
+ R = (>)
).
builtin_unify_character(C, C).
diff --git a/library/rtti_implementation.m b/library/rtti_implementation.m
index 2c5ea04c3..eeea7e186 100644
--- a/library/rtti_implementation.m
+++ b/library/rtti_implementation.m
@@ -1,7 +1,8 @@
%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
-% Copyright (C) 2001-2007, 2009-2010 The University of Melbourne.
+% Copyright (C) 2001-2007, 2009-2011 The University of Melbourne.
+% Copyright (C) 2014-2016 The Mercury team.
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%---------------------------------------------------------------------------%
@@ -2741,37 +2742,43 @@ deconstruct_2(Term, TypeInfo, TypeCtorInfo, TypeCtorRep, NonCanon,
Arguments = []
;
TypeCtorRep = tcr_int8,
- Functor = "<<int8>>",
+ det_dynamic_cast(Term, Int8),
+ Functor = string.int8_to_string(Int8) ++ "i8",
Ordinal = -1,
Arity = 0,
Arguments = []
;
TypeCtorRep = tcr_uint8,
- Functor = "<<uint8>>",
+ det_dynamic_cast(Term, UInt8),
+ Functor = string.uint8_to_string(UInt8) ++ "u8",
Ordinal = -1,
Arity = 0,
Arguments = []
;
TypeCtorRep = tcr_int16,
- Functor = "<<int16>>",
+ det_dynamic_cast(Term, Int16),
+ Functor = string.int16_to_string(Int16) ++ "i16",
Ordinal = -1,
Arity = 0,
Arguments = []
;
TypeCtorRep = tcr_uint16,
- Functor = "<<uint16>>",
+ det_dynamic_cast(Term, UInt16),
+ Functor = string.uint16_to_string(UInt16) ++ "u16",
Ordinal = -1,
Arity = 0,
Arguments = []
;
TypeCtorRep = tcr_int32,
- Functor = "<<int32>>",
+ det_dynamic_cast(Term, Int32),
+ Functor = string.int32_to_string(Int32) ++ "i32",
Ordinal = -1,
Arity = 0,
Arguments = []
;
TypeCtorRep = tcr_uint32,
- Functor = "<<uint32>>",
+ det_dynamic_cast(Term, UInt32),
+ Functor = string.uint32_to_string(UInt32) ++ "u32",
Ordinal = -1,
Arity = 0,
Arguments = []
diff --git a/library/stream.string_writer.m b/library/stream.string_writer.m
index 337fe951f..3b158b249 100644
--- a/library/stream.string_writer.m
+++ b/library/stream.string_writer.m
@@ -2,6 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 2006-2007, 2011 The University of Melbourne.
+% Copyright (C) 2014-2017 The Mercury team.
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%---------------------------------------------------------------------------%
@@ -32,6 +33,24 @@
:- pred put_uint(Stream::in, uint::in, State::di, State::uo) is det
<= stream.writer(Stream, string, State).
+:- pred put_int8(Stream::in, int8::in, State::di, State::uo) is det
+ <= stream.writer(Stream, string, State).
+
+:- pred put_uint8(Stream::in, uint8::in, State::di, State::uo) is det
+ <= stream.writer(Stream, string, State).
+
+:- pred put_int16(Stream::in, int16::in, State::di, State::uo) is det
+ <= stream.writer(Stream, string, State).
+
+:- pred put_uint16(Stream::in, uint16::in, State::di, State::uo) is det
+ <= stream.writer(Stream, string, State).
+
+:- pred put_int32(Stream::in, int32::in, State::di, State::uo) is det
+ <= stream.writer(Stream, string, State).
+
+:- pred put_uint32(Stream::in, uint32::in, State::di, State::uo) is det
+ <= stream.writer(Stream, string, State).
+
:- pred put_float(Stream::in, float::in, State::di, State::uo) is det
<= stream.writer(Stream, string, State).
@@ -234,6 +253,105 @@ put_uint(Stream, UInt, !State) :-
put(Stream, string.uint_to_string(UInt), !State)
).
+put_int8(Stream, Int8, !State) :-
+ ( if
+ % Handle the common I/O case more efficiently.
+ dynamic_cast(!.State, IOState0),
+ dynamic_cast(Stream, IOStream)
+ then
+ io.write_int8(IOStream, Int8, unsafe_promise_unique(IOState0), IOState),
+ ( if dynamic_cast(IOState, !:State) then
+ !:State = unsafe_promise_unique(!.State)
+ else
+ error("stream.string_writer.put_int8: unexpected type error")
+ )
+ else
+ put(Stream, string.int8_to_string(Int8), !State)
+ ).
+
+put_uint8(Stream, UInt8, !State) :-
+ ( if
+ % Handle the common I/O case more efficiently.
+ dynamic_cast(!.State, IOState0),
+ dynamic_cast(Stream, IOStream)
+ then
+ io.write_uint8(IOStream, UInt8,
+ unsafe_promise_unique(IOState0), IOState),
+ ( if dynamic_cast(IOState, !:State) then
+ !:State = unsafe_promise_unique(!.State)
+ else
+ error("stream.string_writer.put_uint8: unexpected type error")
+ )
+ else
+ put(Stream, string.uint8_to_string(UInt8), !State)
+ ).
+
+put_int16(Stream, Int16, !State) :-
+ ( if
+ % Handle the common I/O case more efficiently.
+ dynamic_cast(!.State, IOState0),
+ dynamic_cast(Stream, IOStream)
+ then
+ io.write_int16(IOStream, Int16, unsafe_promise_unique(IOState0), IOState),
+ ( if dynamic_cast(IOState, !:State) then
+ !:State = unsafe_promise_unique(!.State)
+ else
+ error("stream.string_writer.put_int16: unexpected type error")
+ )
+ else
+ put(Stream, string.int16_to_string(Int16), !State)
+ ).
+
+put_uint16(Stream, UInt16, !State) :-
+ ( if
+ % Handle the common I/O case more efficiently.
+ dynamic_cast(!.State, IOState0),
+ dynamic_cast(Stream, IOStream)
+ then
+ io.write_uint16(IOStream, UInt16,
+ unsafe_promise_unique(IOState0), IOState),
+ ( if dynamic_cast(IOState, !:State) then
+ !:State = unsafe_promise_unique(!.State)
+ else
+ error("stream.string_writer.put_uint16: unexpected type error")
+ )
+ else
+ put(Stream, string.uint16_to_string(UInt16), !State)
+ ).
+
+put_int32(Stream, Int32, !State) :-
+ ( if
+ % Handle the common I/O case more efficiently.
+ dynamic_cast(!.State, IOState0),
+ dynamic_cast(Stream, IOStream)
+ then
+ io.write_int32(IOStream, Int32, unsafe_promise_unique(IOState0), IOState),
+ ( if dynamic_cast(IOState, !:State) then
+ !:State = unsafe_promise_unique(!.State)
+ else
+ error("stream.string_writer.put_int32: unexpected type error")
+ )
+ else
+ put(Stream, string.int32_to_string(Int32), !State)
+ ).
+
+put_uint32(Stream, UInt32, !State) :-
+ ( if
+ % Handle the common I/O case more efficiently.
+ dynamic_cast(!.State, IOState0),
+ dynamic_cast(Stream, IOStream)
+ then
+ io.write_uint32(IOStream, UInt32,
+ unsafe_promise_unique(IOState0), IOState),
+ ( if dynamic_cast(IOState, !:State) then
+ !:State = unsafe_promise_unique(!.State)
+ else
+ error("stream.string_writer.put_uint32: unexpected type error")
+ )
+ else
+ put(Stream, string.uint32_to_string(UInt32), !State)
+ ).
+
put_float(Stream, Float, !State) :-
( if
% Handle the common I/O case more efficiently.
@@ -294,6 +412,18 @@ print(Stream, NonCanon, Term, !State) :-
put(Stream, Char, !State)
else if dynamic_cast(Term, UInt : uint) then
put(Stream, uint_to_string(UInt), !State)
+ else if dynamic_cast(Term, Int8 : int8) then
+ put(Stream, int8_to_string(Int8), !State)
+ else if dynamic_cast(Term, UInt8 : uint8) then
+ put(Stream, uint8_to_string(UInt8), !State)
+ else if dynamic_cast(Term, Int16 : int16) then
+ put(Stream, int16_to_string(Int16), !State)
+ else if dynamic_cast(Term, UInt16 : uint16) then
+ put(Stream, uint16_to_string(UInt16), !State)
+ else if dynamic_cast(Term, Int32 : int32) then
+ put(Stream, int32_to_string(Int32), !State)
+ else if dynamic_cast(Term, UInt32 : uint32) then
+ put(Stream, uint32_to_string(UInt32), !State)
else if dynamic_cast(Term, OrigUniv) then
write_univ(Stream, OrigUniv, !State)
else if dynamic_cast(Term, BigInt) then
@@ -397,6 +527,24 @@ do_write_univ_prio(Stream, NonCanon, Univ, Priority, !State) :-
else if univ_to_type(Univ, UInt) then
put_uint(Stream, UInt, !State),
put_char(Stream, 'u', !State)
+ else if univ_to_type(Univ, Int8) then
+ put_int8(Stream, Int8, !State),
+ put(Stream, "i8", !State)
+ else if univ_to_type(Univ, UInt8) then
+ put_uint8(Stream, UInt8, !State),
+ put(Stream, "u8", !State)
+ else if univ_to_type(Univ, Int16) then
+ put_int16(Stream, Int16, !State),
+ put(Stream, "i16", !State)
+ else if univ_to_type(Univ, UInt16) then
+ put_uint16(Stream, UInt16, !State),
+ put(Stream, "u16", !State)
+ else if univ_to_type(Univ, Int32)then
+ put_int32(Stream, Int32, !State),
+ put(Stream, "i32", !State)
+ else if univ_to_type(Univ, UInt32) then
+ put_uint32(Stream, UInt32, !State),
+ put(Stream, "u32", !State)
else if univ_to_type(Univ, Float) then
put_float(Stream, Float, !State)
else if univ_to_type(Univ, Bitmap) then
diff --git a/library/string.m b/library/string.m
index 7f809d139..fae3c7af4 100644
--- a/library/string.m
+++ b/library/string.m
@@ -2,6 +2,7 @@
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
% Copyright (C) 1993-2012 The University of Melbourne.
+% Copyright (C) 2013-2017 The Mercury team.
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%---------------------------------------------------------------------------%
@@ -1232,8 +1233,34 @@
:- func int_to_base_string_group(int, int, int, string) = string.
:- mode int_to_base_string_group(in, in, in, in) = uo is det.
+ % Convert an unsigned integer to a string.
+ %
:- func uint_to_string(uint::in) = (string::uo) is det.
+ % Convert an 8-bit integer to a string.
+ %
+:- func int8_to_string(int8::in) = (string::uo) is det.
+
+ % Convert an unsigned 8-bit integer to a string.
+ %
+:- func uint8_to_string(uint8::in) = (string::uo) is det.
+
+ % Convert an 16-bit integer to a string.
+ %
+:- func int16_to_string(int16::in) = (string::uo) is det.
+
+ % Convert an unsigned 16-bit integer to a string.
+ %
+:- func uint16_to_string(uint16::in) = (string::uo) is det.
+
+ % Convert a 32-bit integer to a string.
+ %
+:- func int32_to_string(int32::in) = (string::uo) is det.
+
+ % Convert an unsigned 32-bit integer to a string.
+ %
+:- func uint32_to_string(uint32::in) = (string::uo) is det.
+
% Convert a float to a string.
% In the current implementation, the resulting float will be in the form
% that it was printed using the format string "%#.<prec>g".
@@ -1408,6 +1435,7 @@
#include <ctype.h>
#include <string.h>
#include <stdio.h>
+#include <inttypes.h>
#include ""mercury_string.h"" /* for MR_allocate_aligned_string*() etc. */
#include ""mercury_tags.h"" /* for MR_list_cons*() */
@@ -5867,6 +5895,180 @@ uint_to_string(_) = _ :-
%---------------------%
+:- pragma foreign_proc("C",
+ int8_to_string(I8::in) = (S::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+ char buffer[5];
+ sprintf(buffer, ""%"" PRId8, I8);
+ MR_allocate_aligned_string_msg(S, strlen(buffer), MR_ALLOC_ID);
+ strcpy(S, buffer);
+").
+
+:- pragma foreign_proc("C#",
+ int_to_string(I8::in) = (S::uo),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ S = I8.ToString();
+").
+
+:- pragma foreign_proc("Java",
+ int8_to_string(I8::in) = (S::uo),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ S = java.lang.Integer.toString(I8);
+").
+
+int8_to_string(_) = _ :-
+ sorry($module, "string.int8_to_string/1").
+
+%---------------------%
+
+:- pragma foreign_proc("C",
+ uint8_to_string(U8::in) = (S::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+ char buffer[4];
+ sprintf(buffer, ""%"" PRIu8, U8);
+ MR_allocate_aligned_string_msg(S, strlen(buffer), MR_ALLOC_ID);
+ strcpy(S, buffer);
+").
+
+:- pragma foreign_proc("C#",
+ uint8_to_string(U8::in) = (S::uo),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ S = U8.ToString();
+").
+
+:- pragma foreign_proc("Java",
+ uint8_to_string(U8::in) = (S::uo),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ S = java.lang.Integer.toString(U8 & 0xff);
+").
+
+uint8_to_string(_) = _ :-
+ sorry($module, "string.uint8_to_string/1").
+
+%---------------------%
+
+:- pragma foreign_proc("C",
+ int16_to_string(I16::in) = (S::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+ char buffer[7];
+ sprintf(buffer, ""%"" PRId16, I16);
+ MR_allocate_aligned_string_msg(S, strlen(buffer), MR_ALLOC_ID);
+ strcpy(S, buffer);
+").
+
+:- pragma foreign_proc("C#",
+ int16_to_string(I16::in) = (S::uo),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ S = I16.ToString();
+").
+
+:- pragma foreign_proc("Java",
+ int16_to_string(I16::in) = (S::uo),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ S = java.lang.Integer.toString(I16);
+").
+
+int16_to_string(_) = _ :-
+ sorry($module, "string.int16_to_string/1").
+
+%---------------------%
+
+:- pragma foreign_proc("C",
+ uint16_to_string(U16::in) = (S::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+ char buffer[6];
+ sprintf(buffer, ""%"" PRIu16, (MR_Unsigned)U16);
+ MR_allocate_aligned_string_msg(S, strlen(buffer), MR_ALLOC_ID);
+ strcpy(S, buffer);
+").
+
+:- pragma foreign_proc("C#",
+ uint16_to_string(U16::in) = (S::uo),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ S = U16.ToString();
+").
+
+:- pragma foreign_proc("Java",
+ uint16_to_string(U16::in) = (S::uo),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ S = java.lang.Integer.toString(U16 & 0xffff);
+").
+
+uint16_to_string(_) = _ :-
+ sorry($module, "string.uint16_to_string/1").
+
+%---------------------%
+
+:- pragma foreign_proc("C",
+ int32_to_string(I32::in) = (S::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+ char buffer[11];
+ sprintf(buffer, ""%"" PRId32, I32);
+ MR_allocate_aligned_string_msg(S, strlen(buffer), MR_ALLOC_ID);
+ strcpy(S, buffer);
+").
+
+:- pragma foreign_proc("C#",
+ int32_to_string(I32::in) = (S::uo),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ S = I32.ToString();
+").
+
+:- pragma foreign_proc("Java",
+ int32_to_string(I32::in) = (S::uo),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ S = java.lang.Integer.toString(I32);
+").
+
+int32_to_string(_) = _ :-
+ sorry($module, "string.int32_to_string/1").
+
+%---------------------%
+
+:- pragma foreign_proc("C",
+ uint32_to_string(U32::in) = (S::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+ char buffer[10];
+ sprintf(buffer, ""%"" PRIu32, U32);
+ MR_allocate_aligned_string_msg(S, strlen(buffer), MR_ALLOC_ID);
+ strcpy(S, buffer);
+").
+
+:- pragma foreign_proc("C#",
+ uint32_to_string(U32::in) = (S::uo),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ S = U32.ToString();
+").
+
+:- pragma foreign_proc("Java",
+ uint32_to_string(U32::in) = (S::uo),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ S = java.lang.Long.toString(U32 & 0xffffffffL);
+").
+
+uint32_to_string(_) = _ :-
+ sorry($module, "string.uint32_to_string/1").
+
+%---------------------%
+
float_to_string(Float) = S2 :-
float_to_string(Float, S2).
diff --git a/library/string.to_string.m b/library/string.to_string.m
index 0a9d0f731..c1e917849 100644
--- a/library/string.to_string.m
+++ b/library/string.to_string.m
@@ -104,7 +104,8 @@ value_to_revstrings(NonCanon, OpsTable, X, !Rs) :-
value_to_revstrings_prio(NonCanon, OpsTable, Priority, X, !Rs) :-
% We need to special-case the builtin types:
- % int, uint, char, float, string
+ % int, uint, int8, uint8, int16, uint16, int32, uint32
+ % char, float, string
% type_info, univ, c_pointer, array
% and private_builtin.type_info
@@ -116,6 +117,18 @@ value_to_revstrings_prio(NonCanon, OpsTable, Priority, X, !Rs) :-
add_revstring(string.int_to_string(Int), !Rs)
else if dynamic_cast(X, UInt) then
add_revstring(string.uint_to_string(UInt) ++ "u", !Rs)
+ else if dynamic_cast(X, Int8) then
+ add_revstring(string.int8_to_string(Int8) ++ "i8", !Rs)
+ else if dynamic_cast(X, UInt8) then
+ add_revstring(string.uint8_to_string(UInt8) ++ "u8", !Rs)
+ else if dynamic_cast(X, Int16) then
+ add_revstring(string.int16_to_string(Int16) ++ "i16", !Rs)
+ else if dynamic_cast(X, UInt16) then
+ add_revstring(string.uint16_to_string(UInt16) ++ "u16", !Rs)
+ else if dynamic_cast(X, Int32) then
+ add_revstring(string.int32_to_string(Int32) ++ "i32", !Rs)
+ else if dynamic_cast(X, UInt32) then
+ add_revstring(string.uint32_to_string(UInt32) ++ "u32", !Rs)
else if dynamic_cast(X, Float) then
add_revstring(string.float_to_string(Float), !Rs)
else if dynamic_cast(X, Bitmap) then
diff --git a/library/term.m b/library/term.m
index 3a2211608..4c286f4f0 100644
--- a/library/term.m
+++ b/library/term.m
@@ -2,7 +2,7 @@
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
% Copyright (C) 1993-2000,2003-2009,2011-2012 The University of Melbourne.
-% Copyright (C) 2015-2017 The Mercury team.
+% Copyright (C) 2014-2017 The Mercury team.
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%---------------------------------------------------------------------------%
@@ -149,14 +149,38 @@
:- pred term_to_int(term(T)::in, int::out) is semidet.
+:- pred term_to_int8(term(T)::in, int8::out) is semidet.
+
+:- pred term_to_int16(term(T)::in, int16::out) is semidet.
+
+:- pred term_to_int32(term(T)::in, int32::out) is semidet.
+
:- pred term_to_uint(term(T)::in, uint::out) is semidet.
+:- pred term_to_uint8(term(T)::in, uint8::out) is semidet.
+
+:- pred term_to_uint16(term(T)::in, uint16::out) is semidet.
+
+:- pred term_to_uint32(term(T)::in, uint32::out) is semidet.
+
:- pred decimal_term_to_int(term(T)::in, int::out) is semidet.
:- func int_to_decimal_term(int, context) = term(T).
:- func uint_to_decimal_term(uint, context) = term(T).
+:- func int8_to_decimal_term(int8, context) = term(T).
+
+:- func uint8_to_decimal_term(uint8, context) = term(T).
+
+:- func int16_to_decimal_term(int16, context) = term(T).
+
+:- func uint16_to_decimal_term(uint16, context) = term(T).
+
+:- func int32_to_decimal_term(int32, context) = term(T).
+
+:- func uint32_to_decimal_term(uint32, context) = term(T).
+
%---------------------------------------------------------------------------%
%
% Predicates to unify terms.
@@ -794,11 +818,41 @@ term_to_int(Term, Int) :-
Const = integer(_Base, Integer, signed, size_word),
integer.to_int(Integer, Int).
+term_to_int8(Term, Int8) :-
+ Term = functor(Const, [], _Context),
+ Const = integer(_Base, Integer, signed, size_8_bit),
+ integer.to_int8(Integer, Int8).
+
+term_to_int16(Term, Int16) :-
+ Term = functor(Const, [], _Context),
+ Const = integer(_Base, Integer, signed, size_16_bit),
+ integer.to_int16(Integer, Int16).
+
+term_to_int32(Term, Int32) :-
+ Term = functor(Const, [], _Context),
+ Const = integer(_Base, Integer, signed, size_32_bit),
+ integer.to_int32(Integer, Int32).
+
term_to_uint(Term, UInt) :-
Term = functor(Const, [], _Context),
Const = integer(_Base, Integer, unsigned, size_word),
integer.to_uint(Integer, UInt).
+term_to_uint8(Term, UInt8) :-
+ Term = functor(Const, [], _Context),
+ Const = integer(_Base, Integer, unsigned, size_8_bit),
+ integer.to_uint8(Integer, UInt8).
+
+term_to_uint16(Term, UInt16) :-
+ Term = functor(Const, [], _Context),
+ Const = integer(_Base, Integer, unsigned, size_16_bit),
+ integer.to_uint16(Integer, UInt16).
+
+term_to_uint32(Term, UInt32) :-
+ Term = functor(Const, [], _Context),
+ Const = integer(_Base, Integer, unsigned, size_32_bit),
+ integer.to_uint32(Integer, UInt32).
+
decimal_term_to_int(Term, Int) :-
Term = functor(Const, [], _Context),
Const = integer(base_10, Integer, signed, size_word),
@@ -812,6 +866,36 @@ uint_to_decimal_term(UInt, Context) = Term :-
Const = integer(base_10, integer.from_uint(UInt), unsigned, size_word),
Term = functor(Const, [], Context).
+int8_to_decimal_term(Int8, Context) = Term :-
+ Const = integer(base_10, integer.from_int8(Int8), signed,
+ size_8_bit),
+ Term = functor(Const, [], Context).
+
+uint8_to_decimal_term(UInt8, Context) = Term :-
+ Const = integer(base_10, integer.from_uint8(UInt8), unsigned,
+ size_8_bit),
+ Term = functor(Const, [], Context).
+
+int16_to_decimal_term(Int16, Context) = Term :-
+ Const = integer(base_10, integer.from_int16(Int16), signed,
+ size_16_bit),
+ Term = functor(Const, [], Context).
+
+uint16_to_decimal_term(UInt16, Context) = Term :-
+ Const = integer(base_10, integer.from_uint16(UInt16), unsigned,
+ size_16_bit),
+ Term = functor(Const, [], Context).
+
+int32_to_decimal_term(Int32, Context) = Term :-
+ Const = integer(base_10, integer.from_int32(Int32), signed,
+ size_32_bit),
+ Term = functor(Const, [], Context).
+
+uint32_to_decimal_term(UInt32, Context) = Term :-
+ Const = integer(base_10, integer.from_uint32(UInt32), unsigned,
+ size_32_bit),
+ Term = functor(Const, [], Context).
+
%---------------------------------------------------------------------------%
unify_term(TermX, TermY, !Subst) :-
diff --git a/library/term_conversion.m b/library/term_conversion.m
index db2bdd3e1..f318f28bb 100644
--- a/library/term_conversion.m
+++ b/library/term_conversion.m
@@ -218,6 +218,36 @@ term_to_univ_special_case(ModuleName, TypeCtorName, TypeArgs, Term,
Functor = integer(_Base, Integer, unsigned, size_word),
integer.to_uint(Integer, UInt),
type_to_univ(UInt, Univ)
+ ;
+ TypeCtorName = "int8",
+ Functor = integer(_Base, Integer, signed, size_8_bit),
+ integer.to_int8(Integer, Int8),
+ type_to_univ(Int8, Univ)
+ ;
+ TypeCtorName = "uint8",
+ Functor = integer(_Base, Integer, unsigned, size_8_bit),
+ integer.to_uint8(Integer, UInt8),
+ type_to_univ(UInt8, Univ)
+ ;
+ TypeCtorName = "int16",
+ Functor = integer(_Base, Integer, signed, size_16_bit),
+ integer.to_int16(Integer, Int16),
+ type_to_univ(Int16, Univ)
+ ;
+ TypeCtorName = "uint16",
+ Functor = integer(_Base, Integer, unsigned, size_16_bit),
+ integer.to_uint16(Integer, UInt16),
+ type_to_univ(UInt16, Univ)
+ ;
+ TypeCtorName = "int32",
+ Functor = integer(_Base, Integer, signed, size_32_bit),
+ integer.to_int32(Integer, Int32),
+ type_to_univ(Int32, Univ)
+ ;
+ TypeCtorName = "uint32",
+ Functor = integer(_Base, Integer, unsigned, size_32_bit),
+ integer.to_uint32(Integer, UInt32),
+ type_to_univ(UInt32, Univ)
;
TypeCtorName = "float",
Functor = float(Float),
@@ -299,6 +329,30 @@ term_to_univ_special_case(ModuleName, TypeCtorName, TypeArgs, Term,
TypeTerm = functor(atom("uint"), [], _),
term_to_uint(ValueTerm, UInt),
Univ = univ(UInt)
+ ;
+ TypeTerm = functor(atom("int8"), [], _),
+ term_to_int8(ValueTerm, Int8),
+ Univ = univ(Int8)
+ ;
+ TypeTerm = functor(atom("uint8"), [], _),
+ term_to_uint8(ValueTerm, UInt8),
+ Univ = univ(UInt8)
+ ;
+ TypeTerm = functor(atom("int16"), [], _),
+ term_to_int16(ValueTerm, Int16),
+ Univ = univ(Int16)
+ ;
+ TypeTerm = functor(atom("uint16"), [], _),
+ term_to_uint16(ValueTerm, UInt16),
+ Univ = univ(UInt16)
+ ;
+ TypeTerm = functor(atom("int32"), [], _),
+ term_to_int32(ValueTerm, Int32),
+ Univ = univ(Int32)
+ ;
+ TypeTerm = functor(atom("uint32"), [], _),
+ term_to_uint32(ValueTerm, UInt32),
+ Univ = univ(UInt32)
;
TypeTerm = functor(atom("string"), [], _),
ValueTerm = functor(string(String), [], _),
diff --git a/library/uint.m b/library/uint.m
index 4074bc120..229e37ef7 100644
--- a/library/uint.m
+++ b/library/uint.m
@@ -58,6 +58,8 @@
:- mode uo + in = in is det.
:- mode in + uo = in is det.
+:- func plus(uint, uint) = uint.
+
% Subtraction.
%
:- func uint - uint = uint.
@@ -65,9 +67,12 @@
:- mode uo - in = in is det.
:- mode in - uo = in is det.
+:- func minus(uint, uint) = uint.
+
% Multiplication.
%
:- func (uint::in) * (uint::in) = (uint::uo) is det.
+:- func times(uint, uint) = uint.
% Maximum.
%
@@ -253,6 +258,7 @@ det_from_int(I) = U :-
U = I;
").
+%---------------------------------------------------------------------------%
cast_from_int(_) = _ :-
sorry($module, "uint.cast_from_int/1 NYI for Erlang").
diff --git a/library/uint16.m b/library/uint16.m
index 703026221..7ff0c9a4e 100644
--- a/library/uint16.m
+++ b/library/uint16.m
@@ -5,16 +5,327 @@
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%---------------------------------------------------------------------------%
+%
+% File: uint16.m
+% Main author: juliensf
+% Stability: low.
+%
+% Predicates and functions for dealing with unsigned 16-bit integer numbers.
+%
+%---------------------------------------------------------------------------%
:- module uint16.
:- interface.
- % uint16s are NYI -- this module is just a placeholder for their
- % library support.
+:- import_module pretty_printer.
+
+%--------------------------------------------------------------------------%
+
+ % from_int(I, U16):
+ % Convert an int into a uint16.
+ % Fails if I is not in [0, 65535].
+ %
+:- pred from_int(int::in, uint16::out) is semidet.
+
+ % As above, but throw an exception instead of failing.
+ %
+:- func det_from_int(int) = uint16.
+
+:- func cast_from_int(int) = uint16.
+
+:- func to_int(uint16) = int.
+
+ % Less than.
+ %
+:- pred (uint16::in) < (uint16::in) is semidet.
+
+ % Greater than.
+ %
+:- pred (uint16::in) > (uint16::in) is semidet.
+
+ % Less than or equal.
+ %
+:- pred (uint16::in) =< (uint16::in) is semidet.
+
+ % Greater than or equal.
+ %
+:- pred (uint16::in) >= (uint16::in) is semidet.
+
+ % Addition.
+ %
+:- func uint16 + uint16 = uint16.
+:- mode in + in = uo is det.
+:- mode uo + in = in is det.
+:- mode in + uo = in is det.
+
+:- func plus(uint16, uint16) = uint16.
+
+ % Subtraction.
+ %
+:- func uint16 - uint16 = uint16.
+:- mode in - in = uo is det.
+:- mode uo - in = in is det.
+:- mode in - uo = in is det.
+
+:- func minus(uint16, uint16) = uint16.
+
+ % Multiplication.
+ %
+:- func (uint16::in) * (uint16::in) = (uint16::uo) is det.
+:- func times(uint16, uint16) = uint16.
+
+ % Maximum.
+ %
+:- func max(uint16, uint16) = uint16.
+
+ % Minimum.
+ %
+:- func min(uint16, uint16) = uint16.
+
+ % Truncating integer division.
+ %
+ % Throws a `math.domain_error' exception if the right operand is zero.
+ %
+:- func (uint16::in) div (uint16::in) = (uint16::uo) is det.
+
+ % Truncating integer division.
+ %
+ % Throws a `math.domain_error' exception if the right operand is zero.
+ %
+:- func (uint16::in) // (uint16::in) = (uint16::uo) is det.
+
+ % (/)/2 is a synonym for (//)/2.
+ %
+:- func (uint16::in) / (uint16::in) = (uint16::uo) is det.
+
+ % unchecked_quotient(X, Y) is the same as X // Y, but the behaviour
+ % is undefined if the right operand is zero.
+ %
+:- func unchecked_quotient(uint16::in, uint16::in) = (uint16::uo) is det.
+
+ % Modulus.
+ % X mod Y = X - (X div Y) * Y
+ %
+ % Throws a `math.domain_error' exception if the right operand is zero.
+ %
+:- func (uint16::in) mod (uint16::in) = (uint16::uo) is det.
+
+ % Remainder.
+ % X rem Y = X - (X // Y) * Y.
%
-:- type placeholder_uint16 ---> placeholder_uint16.
+ % Throws a `math.domain_error/` exception if the right operand is zero.
+ %
+:- func (uint16::in) rem (uint16::in) = (uint16::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(uint16::in, uint16::in) = (uint16::uo) is det.
+
+ % Left shift.
+ % X << Y returns X "left shifted" by Y bits.
+ % The bit positions vacated by the shift are filled by zeros.
+ % Throws an exception if Y is not in [0, 16).
+ %
+:- func (uint16::in) << (int::in) = (uint16::uo) is det.
+
+ % unchecked_lift_shift(X, Y) is the same as X << Y except that the
+ % behaviour is undefined if Y is not in [0, 16).
+ % It will typically be be implemented more efficiently than X << Y.
+ %
+:- func unchecked_left_shift(uint16::in, int::in) = (uint16::uo) is det.
+
+ % Right shift.
+ % X >> Y returns X "right shifted" by Y bits.
+ % The bit positions vacated by the shift are filled by zeros.
+ % Throws an exception if Y is not in [0, 16).
+ %
+:- func (uint16::in) >> (int::in) = (uint16::uo) is det.
+
+ % unchecked_right_shift(X, Y) is the same as X >> Y except that the
+ % behaviour is undefined if Y is not in [0, 16).
+ % It will typically be implemented more efficiently than X >> Y.
+ %
+:- func unchecked_right_shift(uint16::in, int::in) = (uint16::uo) is det.
+
+ % even(X) is equivalent to (X mod 2 = 0).
+ %
+:- pred even(uint16::in) is semidet.
+
+ % odd(X) is equivalent to (not even(X)), i.e. (X mod 2 = 1).
+ %
+:- pred odd(uint16::in) is semidet.
+
+ % Bitwise and.
+ %
+:- func (uint16::in) /\ (uint16::in) = (uint16::uo) is det.
+
+ % Bitwise or.
+ %
+:- func (uint16::in) \/ (uint16::in) = (uint16::uo) is det.
+
+ % Bitwise exclusive or (xor).
+ %
+:- func xor(uint16, uint16) = uint16.
+:- mode xor(in, in) = uo is det.
+:- mode xor(in, uo) = in is det.
+:- mode xor(uo, in) = in is det.
+
+ % Bitwise complement.
+ %
+:- func \ (uint16::in) = (uint16::uo) is det.
+
+ % Convert a uint16 to a pretty_printer.doc for formatting.
+ %
+:- func uint16_to_doc(uint16) = pretty_printer.doc.
%---------------------------------------------------------------------------%
-:- end_module uint16.
%---------------------------------------------------------------------------%
+:- implementation.
+
+:- import_module exception.
+:- import_module int.
+:- import_module math.
+:- import_module require.
+:- import_module string.
+:- import_module uint.
+
+%---------------------------------------------------------------------------%
+
+from_int(I, U8) :-
+ I >= 0,
+ I =< 65_535,
+ U8 = cast_from_int(I).
+
+det_from_int(I) = U16 :-
+ ( if from_int(I, U16Prime) then
+ U16 = U16Prime
+ else
+ error("uint16.det_from_int: cannot convert int to uint16")
+ ).
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ cast_from_int(I::in) = (U16::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
+ does_not_affect_liveness],
+"
+ U16 = (uint16_t) I;
+").
+
+:- pragma foreign_proc("C#",
+ cast_from_int(I::in) = (U16::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ U16 = (ushort) I;
+").
+
+:- pragma foreign_proc("Java",
+ cast_from_int(I::in) = (U16::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ U16 = (short) I;
+").
+
+:- pragma no_determinism_warning(cast_from_int/1).
+cast_from_int(_) = _ :-
+ sorry($module, "uint16.cast_from_int/1 NYI for Erlang").
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ to_int(U16::in) = (I::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
+ does_not_affect_liveness],
+"
+ I = U16;
+").
+
+:- pragma foreign_proc("C#",
+ to_int(U16::in) = (I::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I = U16;
+").
+
+:- pragma foreign_proc("Java",
+ to_int(U16::in) = (I::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I = U16 & 0xffff;
+").
+
+:- pragma no_determinism_warning(to_int/1).
+to_int(_) = _ :-
+ sorry($module, "uint16.to_int/1 NYI for Erlang").
+
+%---------------------------------------------------------------------------%
+
+X div Y = X // Y.
+
+:- pragma inline('//'/2).
+X // Y = Div :-
+ ( if Y = cast_from_int(0) then
+ throw(math.domain_error("uint16.'//': division by zero"))
+ else
+ Div = unchecked_quotient(X, Y)
+ ).
+
+:- pragma inline('/'/2).
+X / Y = X // Y.
+
+X mod Y = X rem Y.
+
+:- pragma inline(rem/2).
+X rem Y = Rem :-
+ ( if Y = cast_from_int(0) then
+ throw(math.domain_error("uint16.rem: division by zero"))
+ else
+ Rem = unchecked_rem(X, Y)
+ ).
+
+%---------------------------------------------------------------------------%
+
+X << Y = Result :-
+ ( if cast_from_int(Y) < 16u then
+ Result = unchecked_left_shift(X, Y)
+ else
+ Msg = "uint16.(<<): second operand is out of range",
+ throw(math.domain_error(Msg))
+ ).
+
+X >> Y = Result :-
+ ( if cast_from_int(Y) < 16u then
+ Result = unchecked_right_shift(X, Y)
+ else
+ Msg = "uint16.(>>): second operand is out of range",
+ throw(math.domain_error(Msg))
+ ).
+
+%---------------------------------------------------------------------------%
+
+max(X, Y) =
+ ( if X > Y then X else Y ).
+
+min(X, Y) =
+ ( if X < Y then X else Y ).
+
+%---------------------------------------------------------------------------%
+
+:- pragma inline(even/1).
+even(X) :-
+ (X /\ cast_from_int(1)) = cast_from_int(0).
+
+:- pragma inline(odd/1).
+odd(X) :-
+ (X /\ cast_from_int(1)) \= cast_from_int(0).
+
+%---------------------------------------------------------------------------%
+
+uint16_to_doc(X) = str(string.uint16_to_string(X)).
+
+%---------------------------------------------------------------------------%
+:- end_module uint16.
+%---------------------------------------------------------------------------%
diff --git a/library/uint32.m b/library/uint32.m
index 4409db83a..7eb1dbd8e 100644
--- a/library/uint32.m
+++ b/library/uint32.m
@@ -5,16 +5,381 @@
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%---------------------------------------------------------------------------%
+%
+% File: uint32.m
+% Main author: juliensf
+% Stability: low.
+%
+% Predicates and functions for dealing with unsigned 32-bit integer numbers.
+%
+%---------------------------------------------------------------------------%
:- module uint32.
:- interface.
- % uint32s are NYI -- this module is just a placeholder for their
- % library support.
+:- import_module pretty_printer.
+
+%---------------------------------------------------------------------------%
+
+ % from_int(I, U32):
+ % Convert an int into a uint32.
+ % Fails if I is not in [0, 2147483647].
+ %
+:- pred from_int(int::in, uint32::out) is semidet.
+
+:- func det_from_int(int) = uint32.
+
+:- func cast_from_int(int) = uint32.
+
+:- func cast_to_int(uint32) = int.
+
+ % Less than.
+ %
+:- pred (uint32::in) < (uint32::in) is semidet.
+
+ % Greater than.
+ %
+:- pred (uint32::in) > (uint32::in) is semidet.
+
+ % Less than or equal.
+ %
+:- pred (uint32::in) =< (uint32::in) is semidet.
+
+ % Greater than or equal.
+ %
+:- pred (uint32::in) >= (uint32::in) is semidet.
+
+ % Addition.
+ %
+:- func uint32 + uint32 = uint32.
+:- mode in + in = uo is det.
+:- mode uo + in = in is det.
+:- mode in + uo = in is det.
+
+:- func plus(uint32, uint32) = uint32.
+
+ % Subtraction.
+ %
+:- func uint32 - uint32 = uint32.
+:- mode in - in = uo is det.
+:- mode uo - in = in is det.
+:- mode in - uo = in is det.
+
+:- func minus(uint32, uint32) = uint32.
+
+ % Multiplication.
+ %
+:- func (uint32::in) * (uint32::in) = (uint32::uo) is det.
+:- func times(uint32, uint32) = uint32.
+
+ % Maximum.
+ %
+:- func max(uint32, uint32) = uint32.
+
+ % Minimum.
+ %
+:- func min(uint32, uint32) = uint32.
+
+ % Truncating integer division.
+ %
+ % Throws a `math.domain_error' exception if the right operand is zero.
+ %
+:- func (uint32::in) div (uint32::in) = (uint32::uo) is det.
+
+ % Truncating integer division.
+ %
+ % Throws a `math.domain_error' exception if the right operand is zero.
+ %
+:- func (uint32::in) // (uint32::in) = (uint32::uo) is det.
+
+ % (/)/2 is a synonym for (//)/2.
+ %
+:- func (uint32::in) / (uint32::in) = (uint32::uo) is det.
+
+ % unchecked_quotient(X, Y) is the same as X // Y, but the behaviour
+ % is undefined if the right operand is zero.
+ %
+:- func unchecked_quotient(uint32::in, uint32::in) = (uint32::uo) is det.
+
+ % Modulus.
+ % X mod Y = X - (X div Y) * Y
+ %
+ % Throws a `math.domain_error' exception if the right operand is zero.
+ %
+:- func (uint32::in) mod (uint32::in) = (uint32::uo) is det.
+
+ % Remainder.
+ % X rem Y = X - (X // Y) * Y.
+ %
+ % Throws a `math.domain_error/` exception if the right operand is zero.
+ %
+:- func (uint32::in) rem (uint32::in) = (uint32::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(uint32::in, uint32::in) = (uint32::uo) is det.
+
+ % Left shift.
+ % X << Y returns X "left shifted" by Y bits.
+ % The bit positions vacated by the shift are filled by zeros.
+ % Throws an exception if Y is not in [0, 32).
+ %
+:- func (uint32::in) << (int::in) = (uint32::uo) is det.
+
+ % unchecked_lift_shift(X, Y) is the same as X << Y except that the
+ % behaviour is undefined if Y is not in [0, 32).
+ % It will typically be be implemented more efficiently than X << Y.
+ %
+:- func unchecked_left_shift(uint32::in, int::in) = (uint32::uo) is det.
+
+ % Right shift.
+ % X >> Y returns X "right shifted" by Y bits.
+ % The bit positions vacated by the shift are filled by zeros.
+ % Throws an exception if Y is not in [0, 32).
+ %
+:- func (uint32::in) >> (int::in) = (uint32::uo) is det.
+
+ % unchecked_right_shift(X, Y) is the same as X >> Y except that the
+ % behaviour is undefined if Y is not in [0, 32).
+ % It will typically be implemented more efficiently than X >> Y.
+ %
+:- func unchecked_right_shift(uint32::in, int::in) = (uint32::uo) is det.
+
+ % even(X) is equivalent to (X mod 2 = 0).
+ %
+:- pred even(uint32::in) is semidet.
+
+ % odd(X) is equivalent to (not even(X)), i.e. (X mod 2 = 1).
+ %
+:- pred odd(uint32::in) is semidet.
+
+ % Bitwise and.
+ %
+:- func (uint32::in) /\ (uint32::in) = (uint32::uo) is det.
+
+ % Bitwise or.
%
-:- type placeholder_uint32 ---> placeholder_uint32.
+:- func (uint32::in) \/ (uint32::in) = (uint32::uo) is det.
+
+ % Bitwise exclusive or (xor).
+ %
+:- func xor(uint32, uint32) = uint32.
+:- mode xor(in, in) = uo is det.
+:- mode xor(in, uo) = in is det.
+:- mode xor(uo, in) = in is det.
+
+ % Bitwise complement.
+ %
+:- func \ (uint32::in) = (uint32::uo) is det.
+
+:- func max_uint32 = uint32.
+
+ % Convert a uint32 to a pretty_printer.doc for formatting.
+ %
+:- func uint32_to_doc(uint32) = pretty_printer.doc.
%---------------------------------------------------------------------------%
-:- end_module uint32.
%---------------------------------------------------------------------------%
+:- implementation.
+
+:- import_module exception.
+:- import_module math.
+:- import_module require.
+:- import_module string.
+:- import_module uint.
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ from_int(I::in, U::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+ if (I < 0) {
+ SUCCESS_INDICATOR = MR_FALSE;
+ } else if (I > (MR_Integer) INT32_MAX) {
+ SUCCESS_INDICATOR = MR_FALSE;
+ } else {
+ U = (uint32_t) I;
+ SUCCESS_INDICATOR = MR_TRUE;
+ }
+").
+
+:- pragma foreign_proc("C#",
+ from_int(I::in, U::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ U = (uint) I;
+ SUCCESS_INDICATOR = (I < 0) ? false : true;
+").
+
+:- pragma foreign_proc("Java",
+ from_int(I::in, U::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ U = I;
+ SUCCESS_INDICATOR = (I < 0) ? false : true;
+").
+
+:- pragma no_determinism_warning(from_int/2).
+from_int(_, _) :-
+ sorry($module, "uint32.from_int NYI for Erlang").
+
+det_from_int(I) = U :-
+ ( if from_int(I, U0)
+ then U = U0
+ else error("uint32.det_from_int: cannot convert int to uint32")
+ ).
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ cast_from_int(I::in) = (U32::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
+ does_not_affect_liveness],
+"
+ U32 = (uint32_t) I;
+").
+
+:- pragma foreign_proc("C#",
+ cast_from_int(I::in) = (U32::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ U32 = (uint) I;
+").
+
+:- pragma foreign_proc("Java",
+ cast_from_int(I::in) = (U32::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ U32 = I;
+").
+
+:- pragma no_determinism_warning(cast_from_int/1).
+cast_from_int(_) = _ :-
+ sorry($module, "uint32.cast_from_int/1 NYI for Erlang").
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ cast_to_int(U32::in) = (I::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
+ does_not_affect_liveness],
+"
+ I = (MR_Integer) U32;
+").
+
+:- pragma foreign_proc("C#",
+ cast_to_int(U32::in) = (I::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I = (int) U32;
+").
+
+:- pragma foreign_proc("Java",
+ cast_to_int(U32::in) = (I::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I = U32;
+").
+
+:- pragma no_determinism_warning(cast_to_int/1).
+cast_to_int(_) = _ :-
+ sorry($module, "uint32.cast_to_int/1 NYI for Erlang").
+
+%---------------------------------------------------------------------------%
+
+X div Y = X // Y.
+
+:- pragma inline('//'/2).
+X // Y = Div :-
+ ( if Y = cast_from_int(0) then
+ throw(math.domain_error("uint32.'//': division by zero"))
+ else
+ Div = unchecked_quotient(X, Y)
+ ).
+
+:- pragma inline('/'/2).
+X / Y = X // Y.
+
+X mod Y = X rem Y.
+
+:- pragma inline(rem/2).
+X rem Y = Rem :-
+ ( if Y = cast_from_int(0) then
+ throw(math.domain_error("uint32.rem: division by zero"))
+ else
+ Rem = unchecked_rem(X, Y)
+ ).
+
+%---------------------------------------------------------------------------%
+
+X << Y = Result :-
+ ( if cast_from_int(Y) < 32u then
+ Result = unchecked_left_shift(X, Y)
+ else
+ Msg = "uint32.(<<): second operand is out of range",
+ throw(math.domain_error(Msg))
+ ).
+
+X >> Y = Result :-
+ ( if cast_from_int(Y) < 32u then
+ Result = unchecked_right_shift(X, Y)
+ else
+ Msg = "uint32.(>>): second operand is out of range",
+ throw(math.domain_error(Msg))
+ ).
+
+%---------------------------------------------------------------------------%
+
+max(X, Y) =
+ ( if X > Y then X else Y ).
+
+min(X, Y) =
+ ( if X < Y then X else Y ).
+
+%---------------------------------------------------------------------------%
+
+:- pragma inline(even/1).
+even(X) :-
+ (X /\ cast_from_int(1)) = cast_from_int(0).
+
+:- pragma inline(odd/1).
+odd(X) :-
+ (X /\ cast_from_int(1)) \= cast_from_int(0).
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ max_uint32 = (U::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+ U = UINT32_MAX;
+").
+
+:- pragma foreign_proc("C#",
+ max_uint32 = (U::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ U = uint.MaxValue;
+").
+
+:- pragma foreign_proc("Java",
+ max_uint32 = (U::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ U = 0xffffffff;
+").
+
+:- pragma no_determinism_warning(max_uint32/0).
+max_uint32 = _ :-
+ sorry($module, "uint32.max_uint32/0 NYI for Erlang").
+
+%---------------------------------------------------------------------------%
+
+uint32_to_doc(X) = str(string.uint32_to_string(X)).
+
+%---------------------------------------------------------------------------%
+:- end_module uint32.
+%---------------------------------------------------------------------------%
diff --git a/library/uint8.m b/library/uint8.m
index d640fb587..e3d0c055f 100644
--- a/library/uint8.m
+++ b/library/uint8.m
@@ -5,16 +5,327 @@
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%---------------------------------------------------------------------------%
+%
+% File: uint8.m
+% Main author: juliensf
+% Stability: low.
+%
+% Predicates and functions for dealing with unsigned 8-bit integer numbers.
+%
+%---------------------------------------------------------------------------%
:- module uint8.
:- interface.
- % uint8s are NYI -- this module is just a placeholder for their
- % library support.
+:- import_module pretty_printer.
+
+%---------------------------------------------------------------------------%
+
+ % from_int(I, U8):
+ % Convert an int to a uint8.
+ % Fails if I is not in [0, 255].
+ %
+:- pred from_int(int::in, uint8::out) is semidet.
+
+ % As above, but throw an exception instead of failing.
+ %
+:- func det_from_int(int) = uint8.
+
+:- func cast_from_int(int) = uint8.
+
+:- func to_int(uint8) = int.
+
+ % Less than.
+ %
+:- pred (uint8::in) < (uint8::in) is semidet.
+
+ % Greater than.
+ %
+:- pred (uint8::in) > (uint8::in) is semidet.
+
+ % Less than or equal.
+ %
+:- pred (uint8::in) =< (uint8::in) is semidet.
+
+ % Greater than or equal.
+ %
+:- pred (uint8::in) >= (uint8::in) is semidet.
+
+ % Addition.
+ %
+:- func uint8 + uint8 = uint8.
+:- mode in + in = uo is det.
+:- mode uo + in = in is det.
+:- mode in + uo = in is det.
+
+:- func plus(uint8, uint8) = uint8.
+
+ % Subtraction.
+ %
+:- func uint8 - uint8 = uint8.
+:- mode in - in = uo is det.
+:- mode uo - in = in is det.
+:- mode in - uo = in is det.
+
+:- func minus(uint8, uint8) = uint8.
+
+ % Multiplication.
+ %
+:- func (uint8::in) * (uint8::in) = (uint8::uo) is det.
+:- func times(uint8, uint8) = uint8.
+
+ % Maximum.
+ %
+:- func max(uint8, uint8) = uint8.
+
+ % Minimum.
+ %
+:- func min(uint8, uint8) = uint8.
+
+ % Truncating integer division.
+ %
+ % Throws a `math.domain_error' exception if the right operand is zero.
+ %
+:- func (uint8::in) div (uint8::in) = (uint8::uo) is det.
+
+ % Truncating integer division.
+ %
+ % Throws a `math.domain_error' exception if the right operand is zero.
+ %
+:- func (uint8::in) // (uint8::in) = (uint8::uo) is det.
+
+ % (/)/2 is a synonym for (//)/2.
+ %
+:- func (uint8::in) / (uint8::in) = (uint8::uo) is det.
+
+ % unchecked_quotient(X, Y) is the same as X // Y, but the behaviour
+ % is undefined if the right operand is zero.
+ %
+:- func unchecked_quotient(uint8::in, uint8::in) = (uint8::uo) is det.
+
+ % Modulus.
+ % X mod Y = X - (X div Y) * Y
+ %
+ % Throws a `math.domain_error' exception if the right operand is zero.
+ %
+:- func (uint8::in) mod (uint8::in) = (uint8::uo) is det.
+
+ % Remainder.
+ % X rem Y = X - (X // Y) * Y.
+ %
+ % Throws a `math.domain_error/` exception if the right operand is zero.
+ %
+:- func (uint8::in) rem (uint8::in) = (uint8::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(uint8::in, uint8::in) = (uint8::uo) is det.
+
+ % Left shift.
+ % X << Y returns X "left shifted" by Y bits.
+ % The bit positions vacated by the shift are filled by zeros.
+ % Throws an exception if Y is not in [0, 8).
+ %
+:- func (uint8::in) << (int::in) = (uint8::uo) is det.
+
+ % unchecked_lift_shift(X, Y) is the same as X << Y except that the
+ % behaviour is undefined if Y is not in [0, 8).
+ % It will typically be be implemented more efficiently than X << Y.
+ %
+:- func unchecked_left_shift(uint8::in, int::in) = (uint8::uo) is det.
+
+ % Right shift.
+ % X >> Y returns X "right shifted" by Y bits.
+ % The bit positions vacated by the shift are filled by zeros.
+ % Throws an exception if Y is not in [0, 8).
+ %
+:- func (uint8::in) >> (int::in) = (uint8::uo) is det.
+
+ % unchecked_right_shift(X, Y) is the same as X >> Y except that the
+ % behaviour is undefined if Y is not in [0, 8).
+ % It will typically be implemented more efficiently than X >> Y.
+ %
+:- func unchecked_right_shift(uint8::in, int::in) = (uint8::uo) is det.
+
+ % even(X) is equivalent to (X mod 2i8 = 0i8).
%
-:- type placeholder_uint8 ---> placeholder_uint8.
+:- pred even(uint8::in) is semidet.
+
+ % odd(X) is equivalent to (not even(X)), i.e. (X mod 2i8 = 1i8).
+ %
+:- pred odd(uint8::in) is semidet.
+
+ % Bitwise and.
+ %
+:- func (uint8::in) /\ (uint8::in) = (uint8::uo) is det.
+
+ % Bitwise or.
+ %
+:- func (uint8::in) \/ (uint8::in) = (uint8::uo) is det.
+
+ % Bitwise exclusive or (xor).
+ %
+:- func xor(uint8, uint8) = uint8.
+:- mode xor(in, in) = uo is det.
+:- mode xor(in, uo) = in is det.
+:- mode xor(uo, in) = in is det.
+
+ % Bitwise complement.
+ %
+:- func \ (uint8::in) = (uint8::uo) is det.
+
+ % Convert an uint8 to a pretty_printer.doc for formatting.
+ %
+:- func uint8_to_doc(uint8) = pretty_printer.doc.
%---------------------------------------------------------------------------%
-:- end_module uint8.
%---------------------------------------------------------------------------%
+:- implementation.
+
+:- import_module exception.
+:- import_module int.
+:- import_module math.
+:- import_module require.
+:- import_module string.
+:- import_module uint.
+
+%---------------------------------------------------------------------------%
+
+from_int(I, U8) :-
+ I >= 0,
+ I =< 255,
+ U8 = cast_from_int(I).
+
+det_from_int(I) = U8 :-
+ ( if from_int(I, U8Prime) then
+ U8 = U8Prime
+ else
+ error("uint8.det_from_int: cannot convert int to uint8")
+ ).
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ cast_from_int(I::in) = (U8::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
+ does_not_affect_liveness],
+"
+ U8 = (uint8_t) I;
+").
+
+:- pragma foreign_proc("C#",
+ cast_from_int(I::in) = (U8::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ U8 = (byte) I;
+").
+
+:- pragma foreign_proc("Java",
+ cast_from_int(I::in) = (U8::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ U8 = (byte) I;
+").
+
+:- pragma no_determinism_warning(cast_from_int/1).
+cast_from_int(_) = _ :-
+ sorry($module, "uint8.cast_from_int/1 NYI for Erlang").
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ to_int(U8::in) = (I::out),
+ [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
+ does_not_affect_liveness],
+"
+ I = U8;
+").
+
+:- pragma foreign_proc("C#",
+ to_int(U8::in) = (I::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I = U8;
+").
+
+:- pragma foreign_proc("Java",
+ to_int(U8::in) = (I::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ I = U8 & 0xff;
+").
+
+:- pragma no_determinism_warning(to_int/1).
+to_int(_) = _ :-
+ sorry($module, "uint8.to_int/1 NYI for Erlang").
+
+%---------------------------------------------------------------------------%
+
+X div Y = X // Y.
+
+:- pragma inline('//'/2).
+X // Y = Div :-
+ ( if Y = cast_from_int(0) then
+ throw(math.domain_error("uint.'//': division by zero"))
+ else
+ Div = unchecked_quotient(X, Y)
+ ).
+
+:- pragma inline('/'/2).
+X / Y = X // Y.
+
+X mod Y = X rem Y.
+
+:- pragma inline(rem/2).
+X rem Y = Rem :-
+ ( if Y = cast_from_int(0) then
+ throw(math.domain_error("uint8.rem: division by zero"))
+ else
+ Rem = unchecked_rem(X, Y)
+ ).
+
+%---------------------------------------------------------------------------%
+
+X << Y = Result :-
+ ( if cast_from_int(Y) < 8u then
+ Result = unchecked_left_shift(X, Y)
+ else
+ Msg = "uint8.(<<): second operand is out of range",
+ throw(math.domain_error(Msg))
+ ).
+
+X >> Y = Result :-
+ ( if cast_from_int(Y) < 8u then
+ Result = unchecked_right_shift(X, Y)
+ else
+ Msg = "uint8.(>>): second operand is out of range",
+ throw(math.domain_error(Msg))
+ ).
+
+%---------------------------------------------------------------------------%
+
+max(X, Y) =
+ ( if X > Y then X else Y ).
+
+min(X, Y) =
+ ( if X < Y then X else Y ).
+
+%---------------------------------------------------------------------------%
+
+:- pragma inline(even/1).
+even(X) :-
+ (X /\ cast_from_int(1)) = cast_from_int(0).
+
+:- pragma inline(odd/1).
+odd(X) :-
+ (X /\ cast_from_int(1)) \= cast_from_int(0).
+
+%---------------------------------------------------------------------------%
+
+uint8_to_doc(X) = str(string.uint8_to_string(X)).
+
+%---------------------------------------------------------------------------%
+:- end_module uint8.
+%---------------------------------------------------------------------------%
diff --git a/tests/invalid/invalid_int.err_exp2 b/tests/invalid/invalid_int.err_exp2
index ee90634fa..8985b3922 100644
--- a/tests/invalid/invalid_int.err_exp2
+++ b/tests/invalid/invalid_int.err_exp2
@@ -1,9 +1,29 @@
invalid_int.m:019: Error: the integer literal
invalid_int.m:019: `0b10000000000000000000000000000000000000000000000000000000000000000'
-invalid_int.m:019: is too big to be represented on this machine.
-invalid_int.m:024: Error: the integer literal `0o2000000000000000000000' is too
-invalid_int.m:024: big to be represented on this machine.
-invalid_int.m:030: Error: the integer literal `0x10000000000000000' is too big
-invalid_int.m:030: to be represented on this machine.
-invalid_int.m:035: Error: the integer literal `9223372036854775808' is too big
-invalid_int.m:035: to be represented on this machine.
+invalid_int.m:019: is outside the range of that type.
+invalid_int.m:024: Error: the integer literal `0o2000000000000000000000' is
+invalid_int.m:024: outside the range of that type.
+invalid_int.m:030: Error: the integer literal `0x10000000000000000' is outside
+invalid_int.m:030: the range of that type.
+invalid_int.m:035: Error: the integer literal `9223372036854775808' is outside
+invalid_int.m:035: the range of that type.
+invalid_int.m:040: Error: the 8-bit integer literal `-129i8' is outside the
+invalid_int.m:040: range of that type.
+invalid_int.m:043: Error: the 8-bit integer literal `128i8' is outside the
+invalid_int.m:043: range of that type.
+invalid_int.m:048: Error: the unsigned 8-bit integer literal `256u8' is outside
+invalid_int.m:048: the range of that type.
+invalid_int.m:049: Error: the unsigned 8-bit integer literal `257u8' is outside
+invalid_int.m:049: the range of that type.
+invalid_int.m:054: Error: the 16-bit integer literal `-32769i16' is outside the
+invalid_int.m:054: range of that type.
+invalid_int.m:057: Error: the 16-bit integer literal `32768i16' is outside the
+invalid_int.m:057: range of that type.
+invalid_int.m:063: Error: the unsigned 16-bit integer literal `65536u16' is
+invalid_int.m:063: outside the range of that type.
+invalid_int.m:068: Error: the 32-bit integer literal `-2147483649i32' is
+invalid_int.m:068: outside the range of that type.
+invalid_int.m:071: Error: the 32-bit integer literal `2147483648i32' is outside
+invalid_int.m:071: the range of that type.
+invalid_int.m:077: Error: the unsigned 32-bit integer literal `4294967296u32'
+invalid_int.m:077: is outside the range of that type.
diff --git a/tests/invalid/invalid_int.m b/tests/invalid/invalid_int.m
index 8a99191cf..88ecdd502 100644
--- a/tests/invalid/invalid_int.m
+++ b/tests/invalid/invalid_int.m
@@ -34,4 +34,46 @@ main(!IO) :-
9223372036854775807,
9223372036854775808
},
- io.write(X, !IO).
+ io.write(X, !IO),
+
+ I8 = {
+ -129_i8,
+ -128_i8,
+ 127_i8,
+ 128_i8
+ },
+ io.write(I8, !IO),
+
+ U8 = {
+ 256_u8,
+ 257_u8
+ },
+ io.write(U8, !IO),
+
+ I16 = {
+ -32_769_i16,
+ -32_768_i16,
+ 32_767_i16,
+ 32_768_i16
+ },
+ io.write(I16, !IO),
+
+ U16 = {
+ 65_535_u16,
+ 65_536_u16
+ },
+ io.write(U16, !IO),
+
+ I32 = {
+ -2_147_483_649_i32,
+ -2_147_483_648_i32,
+ 2_147_483_647_i32,
+ 2_147_483_648_i32
+ },
+ io.write(I32, !IO),
+
+ U32 = {
+ 4_294_967_295_u32,
+ 4_294_967_296_u32
+ },
+ io.write(U32, !IO).
More information about the reviews
mailing list