language-Modula2-0.1: examples/Modula-2_Libraries/andrea-m2/lib/generic/bitsetfun.mod
IMPLEMENTATION MODULE BitsetFunctions;
(* logical operations on BITSETS *)
(* V2.0, J. Andrea, Jun.17/93 - determine word size at runtime *)
(* V1.0, J. Andrea, 1985 *)
(* This code may be freely used and distributed, it may not be sold. *)
FROM SYSTEM IMPORT TSIZE;
VAR
empty, full :BITSET;
i, bits_in_set :CARDINAL;
(* --------------------------------------------------------- *)
PROCEDURE Or( a, b :BITSET ) :BITSET;
BEGIN
RETURN ( a + b ); (* set union *)
END Or;
(* --------------------------------------------------------- *)
PROCEDURE Nor( a, b :BITSET ) :BITSET;
BEGIN
RETURN Not(Or(a,b));
END Nor;
(* --------------------------------------------------------- *)
PROCEDURE Xor( a, b :BITSET ) :BITSET;
BEGIN
RETURN ( a / b ); (* symmetric set difference *)
END Xor;
(* --------------------------------------------------------- *)
PROCEDURE And( a, b :BITSET ) :BITSET;
BEGIN
RETURN ( a * b ); (* set intersection *)
END And;
(* --------------------------------------------------------- *)
PROCEDURE Nand( a, b :BITSET ) :BITSET;
BEGIN
RETURN Not(And(a,b));
END Nand;
(* --------------------------------------------------------- *)
PROCEDURE Xand( a, b :BITSET ) :BITSET;
BEGIN
RETURN (a - b); (* set difference *)
END Xand;
(* --------------------------------------------------------- *)
PROCEDURE Not( a :BITSET ) :BITSET;
BEGIN
RETURN Xor( a, full ); (* a Xor with <all bits> *)
END Not;
(* --------------------------------------------------------- *)
PROCEDURE ShiftLeft( a :BITSET; n :CARDINAL ) :BITSET;
(* perform a circular shift left, n times *)
VAR
i, last :CARDINAL;
save :BOOLEAN;
BEGIN
last := bits_in_set - 1;
FOR i := 1 TO n DO
save := last IN a; (* is the 31st bit set ? *)
EXCL( a, last ); (* remove it in any case *)
a := BITSET( CARDINAL(a) * 2 );(* shift = multiply by 2 *)
EXCL( a, 0 ); (* remove the 0th bit *)
IF save THEN INCL( a, 0 ) END; (* shift the last bit around *)
END;
RETURN a;
END ShiftLeft;
(* --------------------------------------------------------- *)
PROCEDURE ShiftRight( a :BITSET; n :CARDINAL ) :BITSET;
(* perform a circular shift right, n times *)
VAR
i, last :CARDINAL;
save :BOOLEAN;
BEGIN
last := bits_in_set - 1;
FOR i := 1 TO n DO
save := 0 IN a; (* is the 0th bit set ? *)
EXCL( a, 0 ); (* remove it in any case *)
a := BITSET( CARDINAL(a) DIV 2 ); (* shift = divide by 2 *)
EXCL( a, last ); (* remove the last bit *)
IF save THEN INCL( a, last ) END; (* shift the 0th around *)
END;
RETURN a;
END ShiftRight;
BEGIN
bits_in_set := TSIZE( BITSET ) * 8;
empty := {};
full := empty;
FOR i := 1 TO bits_in_set DO
INCL( full, i-1 );
END;
END BitsetFunctions.