
* Fix stdlib warnings * Mark unused includes when used from non-included files * Do not mark indirectly included files as unused * Show unused include warning only for files that are never used * Remove unused include from Option.aes * Consider functions passed as args as used * Return warnings as a sorted list * Fix failing tests * Fix dialyzer warning * Fix warning in Func.aes
127 lines
3.4 KiB
Plaintext
127 lines
3.4 KiB
Plaintext
@compiler >= 4.3
|
|
|
|
namespace Bitwise =
|
|
|
|
// bit shift 'x' right 'n' postions
|
|
function bsr(n : int, x : int) : int =
|
|
let step = 2^n
|
|
let res = x / step
|
|
if (x >= 0 || x mod step == 0)
|
|
res
|
|
else
|
|
res - 1
|
|
|
|
// bit shift 'x' left 'n' positions
|
|
function bsl(n : int, x : int) : int =
|
|
x * 2^n
|
|
|
|
// bit shift 'x' left 'n' positions, limit at 'lim' bits
|
|
function bsli(n : int, x : int, lim : int) : int =
|
|
(x * 2^n) mod (2^lim)
|
|
|
|
// bitwise 'and' for arbitrary precision integers
|
|
function band(a : int, b : int) : int =
|
|
if (a >= 0 && b >= 0)
|
|
uband_(a, b)
|
|
elif (b >= 0)
|
|
ubnand_(b, -1 - a)
|
|
elif (a >= 0)
|
|
ubnand_(a, -1 - b)
|
|
else
|
|
-1 - ubor_(-1 - a, -1 - b)
|
|
|
|
// bitwise 'or' for arbitrary precision integers
|
|
function
|
|
bor : (int, int) => int
|
|
bor(0, b) = b
|
|
bor(a, 0) = a
|
|
bor(a : int, b : int) : int =
|
|
if (a >= 0 && b >= 0)
|
|
ubor_(a, b)
|
|
elif (b >= 0)
|
|
-1 - ubnand_(-1 - a, b)
|
|
elif (a >= 0)
|
|
-1 - ubnand_(-1 - b, a)
|
|
else
|
|
-1 - uband_(-1 - a, -1 - b)
|
|
|
|
// bitwise 'xor' for arbitrary precision integers
|
|
function
|
|
bxor : (int, int) => int
|
|
bxor(0, b) = b
|
|
bxor(a, 0) = a
|
|
bxor(a, b) =
|
|
if (a >= 0 && b >= 0)
|
|
ubxor_(a, b)
|
|
elif (b >= 0)
|
|
-1 - ubxor_(-1 - a, b)
|
|
elif (a >= 0)
|
|
-1 - ubxor_(a, -1 - b)
|
|
else
|
|
ubxor_(-1 - a, -1 - b)
|
|
|
|
// bitwise 'not' for arbitrary precision integers
|
|
function bnot(a : int) = bxor(a, -1)
|
|
|
|
// Bitwise 'and' for non-negative integers
|
|
function uband(a : int, b : int) : int =
|
|
require(a >= 0 && b >= 0, "uband is only defined for non-negative integers")
|
|
switch((a, b))
|
|
(0, _) => 0
|
|
(_, 0) => 0
|
|
_ => uband__(a, b, 1, 0)
|
|
|
|
private function uband_(a, b) = uband__(a, b, 1, 0)
|
|
|
|
private function
|
|
uband__(0, b, val, acc) = acc
|
|
uband__(a, 0, val, acc) = acc
|
|
uband__(a, b, val, acc) =
|
|
switch (a mod 2 + b mod 2)
|
|
2 => uband__(a / 2, b / 2, val * 2, acc + val)
|
|
_ => uband__(a / 2, b / 2, val * 2, acc)
|
|
|
|
// Bitwise 'or' for non-negative integers
|
|
function ubor(a, b) =
|
|
require(a >= 0 && b >= 0, "ubor is only defined for non-negative integers")
|
|
switch((a, b))
|
|
(0, _) => b
|
|
(_, 0) => a
|
|
_ => ubor__(a, b, 1, 0)
|
|
|
|
private function ubor_(a, b) = ubor__(a, b, 1, 0)
|
|
|
|
private function
|
|
ubor__(0, 0, val, acc) = acc
|
|
ubor__(a, b, val, acc) =
|
|
switch (a mod 2 + b mod 2)
|
|
0 => ubor__(a / 2, b / 2, val * 2, acc)
|
|
_ => ubor__(a / 2, b / 2, val * 2, acc + val)
|
|
|
|
//Bitwise 'xor' for non-negative integers
|
|
function
|
|
ubxor : (int, int) => int
|
|
ubxor(0, b) = b
|
|
ubxor(a, 0) = a
|
|
ubxor(a, b) =
|
|
require(a >= 0 && b >= 0, "ubxor is only defined for non-negative integers")
|
|
ubxor__(a, b, 1, 0)
|
|
|
|
private function ubxor_(a, b) = ubxor__(a, b, 1, 0)
|
|
|
|
private function
|
|
ubxor__(0, 0, val, acc) = acc
|
|
ubxor__(a, b, val, acc) =
|
|
switch(a mod 2 + b mod 2)
|
|
1 => ubxor__(a / 2, b / 2, val * 2, acc + val)
|
|
_ => ubxor__(a / 2, b / 2, val * 2, acc)
|
|
|
|
private function ubnand_(a, b) = ubnand__(a, b, 1, 0)
|
|
|
|
private function
|
|
ubnand__(0, b, val, acc) = acc
|
|
ubnand__(a, b, val, acc) =
|
|
switch((a mod 2, b mod 2))
|
|
(1, 0) => ubnand__(a / 2, b / 2, val * 2, acc + val)
|
|
_ => ubnand__(a / 2, b / 2, val * 2, acc)
|