[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