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