PASCAL MACRO COMPILER
Sample Bit Array Program
      
This sample program illustates how the bit array macros can be used.
The bit array macros are included using the %I include directive.
The Init_Bit macro procedure is used to define the bit masks.
The Clear_Bit and Set_Bit macro functions are used
to initialize the bit array, and to set individual bits.
The Test_Bit macro procedure is used to test the bits.
      
Notice, in particular, the section of code
begin
ct := ct + 1;
Set_Bit (target, n); {No. Mark it occupied}
end
which is used as an argument of the Test_Bit procedure.
It is possible to use this block of code as a procedure argument
because Set_Bit has been declared as a macro function.
The entire begin-end block is a code expression, and therefore
may contain macro variables and macro functions.
      
The sample program estimates how many darts can be thrown
at random into a target that has been divided into 100 equally probable
cells before any cell is hit twice.
The generated Pascal program calculates the average of 250 simulations.
      
The generated Pascal program is shown following the macro program.
The source code for the bit array macros can be seen at
Bit Array Macros.
%Macro BitSample;
{%I pas\bitarray.mac}
%Begin {BitSample}
Program Darts;
Var
rep: integer; {Repeat counter}
n: integer; {Loop index}
ct: integer; {Hit count}
target: array[0..12] of byte; {Target in byte form}
total,avg: real;
%Init_bit;
Begin {Darts}
Randomize;
total := 0;
for rep := 1 to 250 do begin
%;
for n := 0 to 100-1 do {Clear the target}
Clear_Bit (target, n);
ct := 0;
repeat
n := random (100); {Throw a random dart}
%Test_Bit (target, n, break, {Is the cell already occupied?}
begin
ct := ct + 1;
Set_Bit (target, n); {No. Mark it occupied}
end);
until false;
total := total + ct;
end;
avg := total / 250;
writeln ('Average is ', avg:4:2, ' darts');
End. {Darts}
%End. {BitSample}
      
This is the Pascal program that is generated by the Pascal Macro
Compiler from the macro program shown above.
Program Darts;
Var
rep: integer; {Repeat counter}
n: integer; {Loop index}
ct: integer; {Hit count}
target: array[0..12] of byte; {Target in byte form}
total,avg: real;
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);
Begin {Darts}
Randomize;
total := 0;
for rep := 1 to 250 do begin
for n := 0 to 100-1 do {Clear the target}
begin
bit_index := ( n) and 7 ;
byte_index := ( n) shr 3 ;
target[byte_index] := target[byte_index] and unmask_bit[bit_index] ;
end;
ct := 0;
repeat
n := random (100); {Throw a random dart}
begin
bit_index := ( n) and 7;
byte_index := ( n) shr 3;
if (target[byte_index] and mask_bit[bit_index]) <> 0
then break
else {Is the cell already occupied?}
begin
ct := ct + 1;
begin
bit_index := ( n) and 7 ;
byte_index := ( n) shr 3 ;
target[byte_index] := target[byte_index] or mask_bit[bit_index] ;
end; {No. Mark it occupied}
end;
end;
until false;
total := total + ct;
end;
avg := total / 250;
writeln ('Average is ', avg:4:2, ' darts');
End. {Darts}
© Copyright 2005 Frank Rubin