mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 01:13:30 +00:00
Until now, the only integer type we generated dense switches
(including lookup switches) for was int itself; we did not do so
for any sized and/or unsigned integer types.
compiler/switch_util.m:
Simplify the representation of whether a switch is on an integer type.
The new version makes it impossible to make the mistake that caused
bug582 in the first place: not having a single representation for
for the switch being on *any* kind of integer type.
This fix requires solving a problem we never had to solve before:
representing information such as the min and max case values
in a way that works for every integer type, signed or unsigned,
sized or not. The solution that this diff adopts is to use int32s
to represent those limits, which implies that whatever the type
of the integer value being switched on, we will generate a dense
or a lookup switch for it only if all case values fit into an int32.
Since case values over two billion are vanishingly rare, this should be
an acceptable restriction.
Use uints instead of ints to represent counts of things.
Delete an unneeded pair of arguments.
compiler/lookup_switch_util.m:
Conform to the changes in switch_util.m. Use some of the new types
there to make arguments in arguments lists less confusable.
Provide some new utility operations.
Add XXXs where the basic operations we need seem not to exist.
compiler/dense_switch.m:
compiler/lookup_switch.m:
Use the new types in switch_util.m that can represent switches
on any integer type.
compiler/ml_lookup_switch.m:
compiler/ml_simplify_switch.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
compiler/switch_gen.m:
Conform to the changes above, and thereby gain the ability
to generate switches on integer types other than int itself.
library/int64.m:
Add a (commmented-out) declaration of an operation that could
help resolve one of the issues in new code in the modules above.
Similar operations would be needed in the modules of other
sized integer types as well.
library/library.m:
Fix a typo.
tests/hard_coded/bug582.{m,exp}:
Add a test case for this issue. Note that while we test whether
we get the expected output, there is no simple automatic way
to detect whether it was generated using a lookup table.
tests/hard_coded/Mmakefile:
Enable the new test case.
67 lines
2.0 KiB
Mathematica
67 lines
2.0 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% Test the operation of lookup switches on integer types other than
|
|
% int itself.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module bug582.
|
|
:- interface.
|
|
|
|
:- import_module io.
|
|
|
|
:- pred main(io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module list.
|
|
:- import_module string.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
main(!IO) :-
|
|
Rows = [3u8, 5u8, 7u8],
|
|
Cols = [0i16, 1i16, 2i16, 3i16, 4i16, 5i16, 6i16, 7i16, 8i16, 9i16, 10i16],
|
|
list.foldl(test_action_table_row(Cols), Rows, !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred test_action_table_row(list(int16)::in, uint8::in,
|
|
io::di, io::uo) is det.
|
|
|
|
test_action_table_row(Cols, Row, !IO) :-
|
|
list.foldl(test_action_table_row_col(Row), Cols, !IO).
|
|
|
|
:- pred test_action_table_row_col(uint8::in, int16::in,
|
|
io::di, io::uo) is det.
|
|
|
|
test_action_table_row_col(Row, Col, !IO) :-
|
|
( if action_table(Row, Col, Val) then
|
|
io.format("action_table(%2u, %2i) = %u\n",
|
|
[u8(Row), i16(Col), u16(Val)], !IO)
|
|
else
|
|
io.format("action_table(%2u, %2i) failed\n",
|
|
[u8(Row), i16(Col)], !IO)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred action_table(uint8::in, int16::in, uint16::out) is semidet.
|
|
|
|
action_table(5u8, 0i16, 1661u16).
|
|
action_table(5u8, 1i16, 1663u16).
|
|
action_table(5u8, 2i16, 1665u16).
|
|
action_table(5u8, 3i16, 1667u16).
|
|
action_table(5u8, 4i16, 1669u16).
|
|
action_table(7u8, 5i16, 1660u16).
|
|
action_table(7u8, 6i16, 1662u16).
|
|
action_table(7u8, 7i16, 1664u16).
|
|
action_table(7u8, 8i16, 1666u16).
|
|
action_table(7u8, 9i16, 1668u16).
|
|
|
|
%---------------------------------------------------------------------------%
|