mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-18 15:26:31 +00:00
code_util.nl, float.nl, llds.nl, mercury_builtin.nl, opt_debug.nl, parser.nl, polymorphism.nl, sp_lib.nl, string.nl, string.nu.nl, type_util.nl, typecheck.nl, unify_gen.nl: Implement floating point. Makefile.common: Remove `-include test.dep' line. Use Mmake. int.nl: Update a few of the comments. io.nu.nl: For Sicstus Prolog, if main/2 is not defined then enter the debugger.
203 lines
4.6 KiB
Mathematica
203 lines
4.6 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
% int - some predicates for dealing with machine-size integer numbers.
|
|
%
|
|
% Main authors: conway, fjh.
|
|
%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module int.
|
|
|
|
:- interface.
|
|
|
|
% '<' and '>' are currently defined in mercury_builtin.nl, since they need to
|
|
% be because they are used in the implementation of compare/3.
|
|
%
|
|
% :- pred <(int, int).
|
|
% :- mode <(in, in) is semidet.
|
|
%
|
|
% :- pred >(int, int).
|
|
% :- mode >(in, in) is semidet.
|
|
|
|
:- pred =<(int, int).
|
|
:- mode =<(in, in) is semidet.
|
|
|
|
:- pred >=(int, int).
|
|
:- mode >=(in, in) is semidet.
|
|
|
|
:- pred int__abs(int, int).
|
|
:- mode int__abs(in, out) is det.
|
|
|
|
:- pred int__max(int, int, int).
|
|
:- mode int__max(in, in, out) is det.
|
|
|
|
:- pred int__min(int, int, int).
|
|
:- mode int__min(in, in, out) is det.
|
|
|
|
:- pred int__pow(int, int, int).
|
|
:- mode int__pow(in, in, out) is det.
|
|
% int__pow(X, Y, Z): Z is X raised to the Yth power
|
|
% Y must not be negative.
|
|
|
|
:- pred int__log2(int, int).
|
|
:- mode int__log2(in, out) is det.
|
|
% int__log2(X, N): N is the least integer such that 2 to the power N
|
|
% is greater than or equal to X. X must be positive.
|
|
|
|
/*
|
|
|
|
% If Mercury had undiscriminated unions (like the NU-Prolog type checker)
|
|
% we could handle is/2 better:
|
|
|
|
:- type int__expr = int__expr_2 + int.
|
|
:- type int__expr_2 ---> (int__expr + int__expr)
|
|
; (int__expr * int__expr)
|
|
; (int__expr - int__expr)
|
|
; (int__expr mod int__expr)
|
|
; (int__expr // int__expr).
|
|
|
|
:- pred is(int :: out, int__expr :: (in)) is det.
|
|
|
|
*/
|
|
|
|
% Instead, we use some hacks in the parser.
|
|
|
|
:- type int__simple_expr ---> (int + int)
|
|
; (int * int)
|
|
; (int - int)
|
|
; (int mod int) % modulus
|
|
; (int // int) % integer division
|
|
; (int << int) % left shift
|
|
; (int >> int) % right shift
|
|
; (int /\ int) % bitwise and
|
|
; (int \/ int) % bitwise or
|
|
; (int ^ int) % bitwise exclusive or
|
|
; (\ int). % bitwise complement
|
|
|
|
:- pred is(int :: out, int__simple_expr :: in) is det.
|
|
|
|
/* NB: calls to `is' get automagically converted into
|
|
calls to builtin_whatever by the parser.
|
|
That is a quick hack to allow us to generate efficient code for it.
|
|
*/
|
|
|
|
:- pred builtin_plus(int, int, int).
|
|
:- mode builtin_plus(in, in, out) is det.
|
|
|
|
:- pred builtin_minus(int, int, int).
|
|
:- mode builtin_minus(in, in, out) is det.
|
|
|
|
:- pred builtin_times(int, int, int).
|
|
:- mode builtin_times(in, in, out) is det.
|
|
|
|
:- pred builtin_div(int, int, int).
|
|
:- mode builtin_div(in, in, out) is det.
|
|
|
|
:- pred builtin_mod(int, int, int).
|
|
:- mode builtin_mod(in, in, out) is det.
|
|
|
|
:- pred builtin_left_shift(int, int, int).
|
|
:- mode builtin_left_shift(in, in, out) is det.
|
|
|
|
:- pred builtin_right_shift(int, int, int).
|
|
:- mode builtin_right_shift(in, in, out) is det.
|
|
|
|
:- pred builtin_bit_or(int, int, int).
|
|
:- mode builtin_bit_or(in, in, out) is det.
|
|
|
|
:- pred builtin_bit_and(int, int, int).
|
|
:- mode builtin_bit_and(in, in, out) is det.
|
|
|
|
:- pred builtin_bit_xor(int, int, int).
|
|
:- mode builtin_bit_xor(in, in, out) is det.
|
|
|
|
:- pred builtin_bit_neg(int, int).
|
|
:- mode builtin_bit_neg(in, out) is det.
|
|
|
|
:- implementation.
|
|
|
|
:- import_module require.
|
|
|
|
:- external((is)/2).
|
|
/*
|
|
Z is (X + Y) :- builtin_plus(X, Y, Z).
|
|
Z is (X * Y) :- builtin_times(X, Y, Z).
|
|
Z is (X - Y) :- builtin_minus(X, Y, Z).
|
|
Z is (X mod Y) :- builtin_mod(X, Y, Z).
|
|
Z is (X // Y) :- builtin_div(X, Y, Z).
|
|
Z is (X << Y) :- builtin_left_shift(X, Y, Z).
|
|
Z is (X >> Y) :- builtin_right_shift(X, Y, Z).
|
|
Z is (X /\ Y) :- builtin_bit_and(X, Y, Z).
|
|
Z is (X \/ Y) :- builtin_bit_or(X, Y, Z).
|
|
Z is (X ^ Y) :- builtin_bit_xor(X, Y, Z).
|
|
Z is (\ X) :- builtin_bit_neg(X, Z).
|
|
*/
|
|
|
|
int__abs(Num, Abs) :-
|
|
(
|
|
Num < 0
|
|
->
|
|
Abs is 0 - Num
|
|
;
|
|
Abs = Num
|
|
).
|
|
|
|
int__max(X, Y, Max) :-
|
|
(
|
|
X > Y
|
|
->
|
|
Max = X
|
|
;
|
|
Max = Y
|
|
).
|
|
|
|
int__min(X, Y, Min) :-
|
|
(
|
|
X < Y
|
|
->
|
|
Min = X
|
|
;
|
|
Min = Y
|
|
).
|
|
|
|
int__pow(Val, Exp, Result) :-
|
|
( Exp < 0 ->
|
|
error("int__pow: negative exponent")
|
|
;
|
|
int__pow_2(Val, Exp, 1, Result)
|
|
).
|
|
|
|
:- pred int__pow_2(int, int, int, int).
|
|
:- mode int__pow_2(in, in, in, out) is det.
|
|
|
|
int__pow_2(Val, Exp, Result0, Result) :-
|
|
( Exp = 0 ->
|
|
Result = Result0
|
|
;
|
|
Exp1 is Exp - 1,
|
|
Result1 is Result0 * Val,
|
|
int__pow_2(Val, Exp1, Result1, Result)
|
|
).
|
|
|
|
int__log2(X, N) :-
|
|
( X =< 0 ->
|
|
error("int__log2: cannot take log of a non-positive number")
|
|
;
|
|
int__log2_2(X, 0, N)
|
|
).
|
|
|
|
:- pred int__log2_2(int, int, int).
|
|
:- mode int__log2_2(in, in, out) is det.
|
|
|
|
int__log2_2(X, N0, N) :-
|
|
( X = 1 ->
|
|
N = N0
|
|
;
|
|
X1 is X + 1,
|
|
X2 is X1 // 2,
|
|
N1 is N0 + 1,
|
|
int__log2_2(X2, N1, N)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|