Files
mercury/tests/hard_coded/opt_format.m
Julien Fischer 587ec47536 Lift restriction on formatting 64-bit integers.
Zoltan's recent addition of support for formatting fixed size integer types
using string.format and friends works by casting the fixed size integer value
to an int or uint value and then re-using the existing code we already have for
formatting those. This works in all cases except when formatting 64-bit integer
types on systems where int / uint is a 32-bit quantity (notably, both the C#
and Java backends). This diff lifts that restrictions.

library/string.format.m:
    Add support for formatting 64-bit integers without having to cast them
    to an int or uint.

    Export new format predicates for use by the code generated by
    compiler/format_call.m.

compiler/format_call.m:
    Generate calls to the 64-bit versions of the format_*_component predicates
    where necessary.

compiler/simplify_proc.m:
    Update the list of predicates that may be introduced by the compiler.

NEWS:
    Delete the mention of the restriction.

tests/hard_coded/opt_format.{m,exp}:
    Extend this test to cover 64-bit integers.
2021-01-07 12:19:22 +11:00

147 lines
4.8 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
%
% This test case is designed to test the correctness of the program
% transformation performed by compiler/format_call.m and the associated
% code in compiler/simplify.m.
:- module opt_format.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module char.
:- import_module int.
:- import_module list.
:- import_module stream.
:- import_module stream.string_writer.
:- import_module string.
main(!IO) :-
io.write_string(test_string_format_1(42, 'x', "HAL", 1111i64, 2222u64),
!IO),
io.write_string(test_string_format_2(142, 'y', "IBM"), !IO),
io.write_string(test_string_format_2(242, 'z', "JCN"), !IO),
io.write_string(test_string_format_2(342, 'v', "KDO"), !IO),
io.nl(!IO),
test_io_format_1(42, 'a', "WHAL", 3333i64, 4444u64, !IO),
test_io_format_2(142, 'b', "WIBM", !IO),
test_io_format_2(242, 'c', "WJCN", !IO),
test_io_format_2(342, 'd', "WKDO", !IO),
io.nl(!IO),
io.output_stream(OutStream, !IO),
test_stream_writer_format_1(OutStream, 42, 'e', "XHAL", 5555i64, 6666u64,
!IO),
test_stream_writer_format_2(OutStream, 142, 'f', "XIBM", !IO),
test_stream_writer_format_2(OutStream, 242, 'g', "XJCN", !IO),
test_stream_writer_format_2(OutStream, 342, 'h', "XKDO", !IO).
%---------------------------------------------------------------------------%
:- func test_string_format_1(int, char, string, int64, uint64) = string.
test_string_format_1(Int, Char, Str, Int64, UInt64) =
string.format("abc_%d_def_%%%c_ghi_%s_jkl_%d_mno_%u_pqr\\\n",
[i(Int), c(Char), s(Str), i64(Int64), u64(UInt64)]).
:- func test_string_format_2(int, char, string) = string.
test_string_format_2(Int, Char, Str) = Result :-
PolyStr = s(Str),
(
Int > 300
->
Tail = [c(Char), PolyStr],
IntX = Int + 1,
Result = string.format("abc_%04d_def_%%%c_ghi_%s_jkl\\\n",
[i(IntX) | Tail])
;
Int > 200,
IntY = Int - 1,
FmtStr = "cba_%s_fed_%%%c_ghi_%d_jkl\\\n",
Values = [PolyStr, c(Char), i(IntY)]
->
Result = string.format(FmtStr, Values)
;
IntX = Int + 1,
Tail = [PolyStr],
Result = string.format("cba_%c_def_%%%d_ghi_%-7s_jkl\\\n",
[c(Char), i(IntX) | Tail])
).
%---------------------------------------------------------------------------%
:- pred test_io_format_1(int::in, char::in, string::in, int64::in, uint64::in,
io::di, io::uo) is det.
test_io_format_1(Int, Char, Str, Int64, UInt64, !IO) :-
io.format("abc_%d_def_%%%c_ghi_%s_jkl_%d_mno_%u_pqr\\\n",
[i(Int), c(Char), s(Str), i64(Int64), u64(UInt64)], !IO).
:- pred test_io_format_2(int::in, char::in, string::in, io::di, io::uo) is det.
test_io_format_2(Int, Char, Str, !IO) :-
PolyStr = s(Str),
io.output_stream(OutStream, !IO),
(
Int > 300
->
Tail = [c(Char), PolyStr],
IntX = Int + 1,
io.format("abc_%05.3d_def_%%%c_ghi_%5s_jkl\\\n", [i(IntX) | Tail], !IO)
;
Int > 200,
IntY = Int - 1,
FmtStr = "cba_%s_fed_%%%c_ghi_%d_jkl\\\n",
Values = [PolyStr, c(Char), i(IntY)]
->
io.format(FmtStr, Values, !IO)
;
IntX = Int + 1,
Tail = [PolyStr],
io.format(OutStream, "cba_%c_def_%%%d_ghi_%s_jkl\\\n",
[c(Char), i(IntX) | Tail], !IO)
).
%---------------------------------------------------------------------------%
:- pred test_stream_writer_format_1(Stream::in, int::in, char::in, string::in,
int64::in, uint64::in, State::di, State::uo) is det
<= stream.writer(Stream, string, State).
test_stream_writer_format_1(Stream, Int, Char, Str, Int64, UInt64, !State) :-
stream.string_writer.format(Stream, "abc_%d_def_%%%c_ghi_%s_jkl_%d_mno_%u_pqr\\\n",
[i(Int), c(Char), s(Str), i64(Int64), u64(UInt64)], !State).
:- pred test_stream_writer_format_2(Stream::in, int::in, char::in, string::in,
State::di, State::uo) is det <= stream.writer(Stream, string, State).
test_stream_writer_format_2(Stream, Int, Char, Str, !State) :-
PolyStr = s(Str),
(
Int > 300
->
Tail = [c(Char), PolyStr],
IntX = Int + 1,
stream.string_writer.format(Stream,
"abc_%05.3d_def_%%%c_ghi_%5s_jkl\\\n", [i(IntX) | Tail], !State)
;
Int > 200,
IntY = Int - 1,
FmtStr = "cba_%s_fed_%%%c_ghi_%d_jkl\\\n",
Values = [PolyStr, c(Char), i(IntY)]
->
stream.string_writer.format(Stream, FmtStr, Values, !State)
;
IntX = Int + 1,
Tail = [PolyStr],
stream.string_writer.format(Stream, "cba_%c_def_%%%d_ghi_%s_jkl\\\n",
[c(Char), i(IntX) | Tail], !State)
).