mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 01:13:30 +00:00
Use the new in_range builtin.
configure.ac:
Require the installed compiler to support this new builtin.
library/private_builtin.m:
Declare the builtin, making it usable.
library/string.m:
Use it to replace the old hand-written range check.
This commit is contained in:
@@ -605,7 +605,7 @@ EOF
|
||||
$BOOTSTRAP_MC \
|
||||
--verbose \
|
||||
$link_static_opt conftest \
|
||||
--subtype-int2-2025-07-07 \
|
||||
--inrange-2025-10-01 \
|
||||
--warn-include-and-non-include \
|
||||
--allow-ho-insts-as-modes \
|
||||
--no-ssdb \
|
||||
|
||||
@@ -147,9 +147,18 @@
|
||||
:- pred builtin_uint64_lt(uint64::in, uint64::in) is semidet.
|
||||
:- pred builtin_uint64_gt(uint64::in, uint64::in) is semidet.
|
||||
|
||||
% Compare two integers after casting both to unsigned.
|
||||
%
|
||||
:- pred unsigned_lt(int::in, int::in) is semidet.
|
||||
:- pred unsigned_le(int::in, int::in) is semidet.
|
||||
|
||||
% in_range(X, Max) is true if and only if 0 <= X, X < Max.
|
||||
%
|
||||
% Implemented as the above test when targeting Java,
|
||||
% and as unsigned_lt(X, Max) when targeting C or C#.
|
||||
%
|
||||
:- pred in_range(int::in, int::in) is semidet.
|
||||
|
||||
% A "typed" version of unify/2 -- i.e. one that can handle arguments
|
||||
% of different types. It first unifies their types, and then (if the types
|
||||
% are equal) it unifies the values.
|
||||
|
||||
@@ -2614,7 +2614,7 @@ duplicate_char(Char, Count, String) :-
|
||||
|
||||
index(Str, Index, Char) :-
|
||||
Len = string.count_code_units(Str),
|
||||
( if string_index_is_in_bounds(Index, Len) then
|
||||
( if private_builtin.in_range(Index, Len) then
|
||||
unsafe_index(Str, Index, Char)
|
||||
else
|
||||
fail
|
||||
@@ -2683,7 +2683,7 @@ index_next(Str, Index, NextIndex, Char) :-
|
||||
|
||||
index_next_repl(Str, Index, NextIndex, Char, MaybeReplaced) :-
|
||||
Len = string.count_code_units(Str),
|
||||
( if string_index_is_in_bounds(Index, Len) then
|
||||
( if private_builtin.in_range(Index, Len) then
|
||||
unsafe_index_next_repl(Str, Index, NextIndex, Char, MaybeReplaced)
|
||||
else
|
||||
fail
|
||||
@@ -2777,7 +2777,7 @@ prev_index(Str, Index, PrevIndex, Char) :-
|
||||
|
||||
prev_index_repl(Str, Index, PrevIndex, Char, MaybeReplaced) :-
|
||||
Len = string.count_code_units(Str),
|
||||
( if string_index_is_in_bounds(Index - 1, Len) then
|
||||
( if private_builtin.in_range(Index - 1, Len) then
|
||||
unsafe_prev_index_repl(Str, Index, PrevIndex, Char, MaybeReplaced)
|
||||
else
|
||||
fail
|
||||
@@ -2878,35 +2878,6 @@ unsafe_prev_index_repl(Str, Index, PrevIndex, Ch, MaybeReplaced) :-
|
||||
}
|
||||
").
|
||||
|
||||
%---------------------%
|
||||
|
||||
% XXX We should consider making this routine a compiler built-in.
|
||||
%
|
||||
:- pred string_index_is_in_bounds(int::in, int::in) is semidet.
|
||||
|
||||
:- pragma foreign_proc("C",
|
||||
string_index_is_in_bounds(Index::in, Length::in),
|
||||
[will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
|
||||
does_not_affect_liveness, no_sharing],
|
||||
"
|
||||
// We do not test for negative values of Index because (a) MR_Unsigned
|
||||
// is unsigned and hence a negative argument will appear as a very large
|
||||
// positive one after the cast and (b) anybody dealing with the case
|
||||
// where strlen(Str) > MAXINT is clearly barking mad (and one may well get
|
||||
// an integer overflow error in this case).
|
||||
SUCCESS_INDICATOR = ((MR_Unsigned) Index < (MR_Unsigned) Length);
|
||||
").
|
||||
:- pragma foreign_proc("C#",
|
||||
string_index_is_in_bounds(Index::in, Length::in),
|
||||
[will_not_call_mercury, promise_pure, thread_safe],
|
||||
"
|
||||
SUCCESS_INDICATOR = ((uint) Index < (uint) Length);
|
||||
").
|
||||
|
||||
string_index_is_in_bounds(Index, Length) :-
|
||||
Index >= 0,
|
||||
Index < Length.
|
||||
|
||||
%---------------------%
|
||||
|
||||
:- pragma foreign_proc("C",
|
||||
@@ -2944,7 +2915,7 @@ set_char(Char, Index, Str0, Str) :-
|
||||
unexpected($pred, "surrogate code point")
|
||||
else
|
||||
Len0 = string.count_code_units(Str0),
|
||||
( if string_index_is_in_bounds(Index, Len0) then
|
||||
( if private_builtin.in_range(Index, Len0) then
|
||||
unsafe_set_char_copy_string(Char, Index, Len0, Str0, Str)
|
||||
else
|
||||
fail
|
||||
|
||||
Reference in New Issue
Block a user