[m-rev.] for review: generalise the representation of integers in the term module

Peter Wang novalazy at gmail.com
Sat Apr 22 13:44:48 AEST 2017


On Thu, 20 Apr 2017 01:21:05 +1000 (AEST), Julien Fischer <jfischer at opturion.com> wrote:
> 
> For review by anyone.
> 
> I haven't updated the NEWS file to cover these changes; I will do so
> separately.
> 
> -------------------------------
> 
> Generalise the representation of integers in the term module.
> 
> In preparation for supporting uint literals and literals for the fixed size
> integer types, generalise the representation of integers in the term module, so
> that for every integer literal we record its base, value (as an arbitrary
> precision integer), signedness and size (the latter two based on the literal's
> suffix or lack thereof).
> 
> Have the lexer attach information about the integer base to machine sized ints;
> we already did this for the 'big_integer' alternative but not the normal one.
> In conjunction with the first change, this fixes a problem where the compiler
> was accepting non-decimal integers in like arity specifications.  (The
> resulting error messages could be improved, but that's a separate change.)
> 
> Support uints in more places; mark other places which require further work with
> XXX UINT.


> diff --git a/library/lexer.m b/library/lexer.m
> index 1cb2427..822f2de 100644
> --- a/library/lexer.m
> +++ b/library/lexer.m
> @@ -30,7 +30,7 @@
>   :- type token
>       --->    name(string)
>       ;       variable(string)
> -    ;       integer(int)
> +    ;       integer(integer_base, int)
> 
>       ;       big_integer(integer_base, integer)
>               % An integer that is too big for `int'.

Will integer and big_integer be combined when the integer literal
syntax is extended?


> diff --git a/library/term.m b/library/term.m
> index feab9cf..fa1b6e3 100644
> --- a/library/term.m
> +++ b/library/term.m

> @@ -762,6 +788,31 @@ var_id(var(VarNum)) = VarNum.
> 
>   %---------------------------------------------------------------------------%
> 
> +term_to_int(Term, Int) :-
> +    Term = functor(Const, [], _),
> +    Const = integer(_, Integer, signed, size_word),
> +    integer.to_int(Integer, Int).
> +
> +term_to_uint(Term, UInt) :-
> +    Term = functor(Const, [], _),
> +    Const = integer(_, Integer, unsigned, size_word),
> +    integer.to_uint(Integer, UInt).

Write _Base and _Context.

> +
> +term_to_decimal_int(Term, Int) :-
> +    Term = functor(Const, [], _),
> +    Const = integer(base_10, Integer, signed, size_word),
> +    integer.to_int(Integer, Int).

The name is a bit confusing as result does not have any inherent base,
obviously.  Would decimal_term_to_int be better?

> +
> +decimal_int_to_term(Int, Context) = Term :-
> +    Const = integer(base_10, integer(Int), signed, size_word),
> +    Term = functor(Const, [], Context).

int_to_decimal_term?

> +
> +decimal_uint_to_term(UInt, Context) = Term :-
> +    Const = integer(base_10, integer.from_uint(UInt), unsigned, size_word),
> +    Term = functor(Const, [], Context).
> +

Likewise.

> diff --git a/library/term_conversion.m b/library/term_conversion.m
> index 9464c69..7082d17 100644
> --- a/library/term_conversion.m
> +++ b/library/term_conversion.m
> @@ -209,9 +210,15 @@ term_to_univ_special_case(ModuleName, TypeCtorName, TypeArgs, Term,
>               type_to_univ(String, Univ)
>           ;
>               TypeCtorName = "int",
> -            Functor = integer(Int),
> +            Functor = integer(_, Integer, signed, size_word),
> +            integer.to_int(Integer, Int),
>               type_to_univ(Int, Univ)
>           ;
> +            TypeCtorName = "uint",
> +            Functor = integer(_, Integer, unsigned, size_word),
> +            integer.to_uint(Integer, UInt),
> +            type_to_univ(UInt, Univ)

Write _Base.

> diff --git a/library/term_io.m b/library/term_io.m
> index 8139f74..226641e 100644
> --- a/library/term_io.m
> +++ b/library/term_io.m
> @@ -565,7 +565,7 @@ write_list_tail(OutStream, Ops, Term, !VarSet, !N, !IO) :-
>       %
>   :- pred starts_with_digit(term(T)::in) is semidet.
> 
> -starts_with_digit(functor(integer(_), _, _)).
> +starts_with_digit(functor(integer(_, _, _, _), _, _)).
>   starts_with_digit(functor(float(_), _, _)).
>   starts_with_digit(functor(atom(Op), Args, _)) :-
>       (
> @@ -606,10 +606,8 @@ write_constant(OutStream, Const, !IO) :-
> 
>   write_constant(OutStream, Const, NextToGraphicToken, !IO) :-
>       (
> -        Const = term.integer(I),
> -        io.write_int(OutStream, I, !IO)
> -    ;
> -        Const = term.big_integer(Base, I),
> +        Const = term.integer(Base, I, _Signedness, _Size),
> +        % XXX UINT hand signedness and size.

handle


The rest looks fine.

Peter


More information about the reviews mailing list