PASCAL MACRO COMPILER
Bit Array Macros
      
The following macro procedures and functions implement bit arrays
in Pascal.
A bit array is an array of single bits that can be turned on and
off and tested individually.
Using bit arrays provides 8 times as many binary flags or switches
in a given amount of storage as using Pascal boolean arrays.
This can be a great space-saver in programs with large binary arrays.
      
These macros generate in-line code for the bit operations.
This is much faster than calling Pascal procedures to set and test bits.
      
Bit arrays are equivalent to packed boolean arrays, so these routines
are not needed with Pascal compilers that implement packed boolean arrays.
However, in a program that might have to be compiled using different
Pascal compilers for different environments it is much safer
to use these bit array macros.
      
The macro headers, or prologues, describe how the bit array
macros are used.
A sample macro program that uses the bit array macros can bee seen
at Bit Array Example.
{ These macro procedures and functions handle bit arrays, }
{or packed boolean arrays. Each bit array must be declared }
{in the Pascal program as array[0..N-1] of byte where N is}
{the number of bytes in the array. The macros treat the }
{array as 8N separate bits. }
{ Note that Set_Bit, Clear_Bit and Flip_Bit are macro }
{functions, not macro procedures. This allows them to be }
{used in code expressions.
{ Frank Rubin Nov. 15, 2004 }
{ Init_Bit Declares variables used by the bit procedures.}
{ Set_Bit Sets a bit in the array (turns the bit on). }
{ Clear_Bit Clears a bit in the array (turns the bit off).}
{ Flip_Bit Flips a bit in the array (reverses its parity)}
{ Test_Bit Tests a bit in the array. }
{Init_Bit declares two arrays of bit masks and two }
{integer variables required by the Bit routines. }
{Init_Bit must appear once in the declaration section}
{of the Pascal program. }
%Procedure Init_Bit;
%Begin {Init_Bit}
Var
byte_index, bit_index: integer; {Variables needed for bit arrays}
Const
mask_bit: array[0..7] of byte {Masks for bit arrays}
= (1, 2, 4, 8, 16, 32, 64, 128);
unmask_bit: array[0..7] of byte
= (254, 253, 251, 247, 239, 223, 191, 127);
%End; {Init_Bit}
{Set_Bit turns on a bit in the bit array (packed boolean array) }
{ table The bit array. }
{ index Index to the specific bit in the array. }
{Example: }
{ %Set_Bit (PaidOnTime, CustomerNumber); }
%Function Set_Bit (table: code; index: code): code;
%Begin {Set_Bit}
%Set_Bit :=begin
bit_index := (index) and 7 _semi
byte_index := (index) shr 3 _semi
table[byte_index] := table[byte_index] or mask_bit[bit_index] _semi
end;
%End; {Set_Bit}
{Clear_Bit turns off a bit in the bit array (packed boolean array)}
{ table The bit array. }
{ index Index to the specific bit in the array. }
{Example: }
{ %Clear_Bit (PaidOnTime, SlowCustomer); }
%Function Clear_Bit (table: code; index: code): code;
%Begin {Clear_Bit}
%Clear_Bit :=begin
bit_index := (index) and 7 _semi
byte_index := (index) shr 3 _semi
table[byte_index] := table[byte_index] and unmask_bit[bit_index] _semi
end;
%End; {Clear_Bit}
{Flip_Bit flips a bit in the bit array (packed boolean array),}
{that is, it reverses the setting of the bit. }
{ table The bit array. }
{ index Index to the specific bit in the array. }
{Example: }
{ %Flip_Bit (ReadySwitches, SwitchNum); }
%Function Flip_Bit (table: code; index: code): code;
%Begin {Flip_Bit}
%Flip_Bit :=begin
bit_index := (index) and 7 _semi
byte_index := (index) shr 3 _semi
table[byte_index] := table[byte_index] xor mask_bit[bit_index] _semi
end;
%End; {Flip_Bit}
{Test_Bit tests a bit in the bit array (packed boolean array)}
{It is called once for each bit to be tested. }
{ table The bit array. }
{ index Index to the specific bit in the array. }
{ action1 (Optional) the action to be taken if the bit is }
{ set (turned on). }
{ action2 (Optional) The action to be taken if the bit is }
{ not set (turned off). }
{Examples: }
{ %Test_Bit (occupied, loc, TryNext (loc+1), break); }
{ %Test_Bit (OnlineNow, next, SendMessage(next),); }
{ %Test_Bit (LineReady, lnum[t],, SignOff(lnum[t])); }
%Procedure Test_Bit (table: code; index: code;
action1,action2: code);
%Begin {Test_Bit}
begin
bit_index := (index) and 7;
byte_index := (index) shr 3;
%if action1
then %if action2
then %begin
if (table[byte_index] and mask_bit[bit_index]) <> 0
then action1
else action2;
%end
else %begin
if (table[byte_index] and mask_bit[bit_index]) <> 0
then action1;
%end
else %begin
if (table[byte_index] and mask_bit[bit_index]) = 0
then action2;
%end;
end;
%End; {Test_Bit}
© Copyright 2004, 2005 Frank Rubin