[m-rev.] for review: add a builtin unsigned word sized integer type -- Part 2.
Peter Wang
novalazy at gmail.com
Thu Oct 27 17:28:05 AEDT 2016
Hi Julien,
On Thu, 27 Oct 2016 01:17:44 +1100 (AEDT), jfischer at opturion.com wrote:
>
> Part 1 has now been committed and is available in rotd-2016-10-26. I will
> wait until next week before committing anything that depends on it.
>
> ----------------
>
> For review by anyone.
>
> Add a builtin unsigned word sized integer type -- Part 2.
>
> Being implementing library support for uints.
Begin
>
> Update the compiler to use the uint type.
>
> library/uint.m:
> Begin filling this module in.
>
There's some inconsistent indentation in the commit message?
> diff --git a/library/string.m b/library/string.m
> index 890b743..8b10948 100644
> --- a/library/string.m
> +++ b/library/string.m
> @@ -1232,6 +1232,8 @@
> :- func int_to_base_string_group(int, int, int, string) = string.
> :- mode int_to_base_string_group(in, in, in, in) = uo is det.
>
> +:- func uint_to_string(uint::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".
> @@ -5725,6 +5727,36 @@ int_to_base_string_group_2(NegN, Base, Curr, GroupLength, Sep, Str) :-
> %---------------------%
>
> :- pragma foreign_proc("C",
> + uint_to_string(U::in) = (Str::uo),
> + [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
> + does_not_affect_liveness, no_sharing],
> +"
> + char buffer[100];
> + sprintf(buffer, ""%"" MR_INTEGER_LENGTH_MODIFIER ""u"", U);
> + MR_allocate_aligned_string_msg(Str, strlen(buffer), MR_ALLOC_ID);
> + strcpy(Str, buffer);
> +").
buffer seems excessively safe, but anyway.
> diff --git a/library/uint.m b/library/uint.m
> index a89ea25..995a5f6 100644
> --- a/library/uint.m
> +++ b/library/uint.m
...
> +%---------------------------------------------------------------------------%
> +
> +:- pragma foreign_proc("C",
> + cast_from_int(I::in) = (U::out),
> + [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
> + does_not_affect_liveness],
> +"
> + U = (MR_Unsigned) I;
> +").
> +
> +:- pragma foreign_proc("Java",
> + cast_from_int(I::in) = (U::out),
> + [will_not_call_mercury, promise_pure, thread_safe],
> +"
> + U = I;
> +").
> +
> +:- pragma foreign_proc("C#",
> + cast_from_int(I::in) = (U::out),
> + [will_not_call_mercury, promise_pure, thread_safe],
> +"
> + U = (uint) I;
> +").
> +
Order C# above Java.
> +cast_from_int(_) = _ :-
> + sorry($module, "uint.cast_from_int/1 NYI for Erlang").
> +
> +:- pragma foreign_proc("C",
> + cast_to_int(U::in) = (I::out),
> + [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
> + does_not_affect_liveness],
> +"
> + I = (MR_Integer) U;
> +").
> +
> +:- pragma foreign_proc("Java",
> + cast_to_int(U::in) = (I::out),
> + [will_not_call_mercury, promise_pure, thread_safe],
> +"
> + I = U;
> +").
> +
> +:- pragma foreign_proc("C#",
> + cast_to_int(U::in) = (I::out),
> + [will_not_call_mercury, promise_pure, thread_safe],
> +"
> + I = (int) U;
> +").
> +
Also here.
> +cast_to_int(_) = _ :-
> + sorry($module, "uint.cast_to_int/1 NYI for Erlang").
> +
> +%---------------------------------------------------------------------------%
> +
> +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_decl("C", "
> + #include <limits.h>
> +
> + #define ML_BITS_PER_UINT (sizeof(MR_Unsigned) * CHAR_BIT)
> +").
> +
> +:- pragma foreign_proc("C",
> + max_uint = (Max::out),
> + [will_not_call_mercury, promise_pure, thread_safe],
> +"
> + if (sizeof(MR_Integer) == sizeof(int)) {
> + Max = UINT_MAX;
> + } else if (sizeof(MR_Integer) == sizeof(long)) {
> + Max = (MR_Integer) ULONG_MAX;
> + #if defined(ULLONG_MAX)
> + } else if (sizeof(MR_Integer) == sizeof(long long)) {
> + Max = (MR_Integer) ULLONG_MAX;
> + #endif
> + } else {
> + MR_fatal_error(""Unable to figure out max uint size"");
> + }
> +").
Test sizeof(MR_Unsigned)
The rest looks okay.
Peter
More information about the reviews
mailing list