PASCAL MACRO COMPILER
Sort Procedure Generator
      
The GenSort macro procedure generates Pascal sorting procedures.
The GenSort macro is flexible, and can generate procedures to sort
either specific arrays, or specific types of arrays.
The arrays can be sorted on the entire contents of each array element,
or on one, two, or three fields within each element.
The details are explained in the procedure prologue.
      
The generated sort procedures are very efficient, and sort
an array of N elements in time proportional to N log2N.
{GenSort - Sample sort procedure generator. }
{ Frank Rubin Nov. 14, 2004 }
{ One sort procedure is needed for each different array or}
{each type of array to be sorted. }
{ }
{sortname the name for the generated sort procedure. }
{ Example: TimeSort }
{arname (optional) the name of the array to be sorted. }
{ If arname is given, then a procedure to sort that}
{ specific array will be generated. If arname is }
{ omitted then the generated sort procedure will }
{ get the array name as a parameter. }
{ Example: Inventory }
{artype the type of the array to be sorted. }
{ Example: array of trans_rec }
{eltype the type of each array element. }
{ Example: customername }
{field1,field2,field3 }
{ (optional) sort fields within each record, in }
{ order of importance. }
{ Example: last_name, first_name,) }
{ }
{ Sample calls to GenSort, with a sample call to each of }
{the generated sort procedures: }
{ }
{%GenSort (VolSort,, array of vol, real,,,); }
{VolSort (packvolume, 0, maxpacks); }
{ }
{%GenSort (TranSort, trantable, tranlist, tranitem, }
{ date, time,); }
{TranSort (1, trancount); }
%Procedure GenSort (sortname: code; {Name for the resulting sort procedure}
arname: code; {Optional array name}
artype: code; {Type of the array to be sorted}
eltype: code; {Type of each array element}
field1,field2, {Optional sort fields}
field3: code);
%Var
fieldcount: integer; {Num of optional fields specified}
sarray: code;
%Begin {GenSort}
%fieldcount := 0; {How many sort fields were given?}
%if field1
then %fieldcount := 1;
%if field2
then %fieldcount := 2;
%if field3
then %fieldcount := 3;
{External sort procedure}
%if arname
then %begin
%sarray :=arname;
Procedure SortName (const lo_end,hi_end: longint);
%end;
else %begin
%sarray :=sortar;
Procedure SortName (var sortar: artype;
const lo_end,hi_end: longint);
%end;
{Internal recursive sort procedure}
Procedure Sort (const bot,top: longint);
Var
i,j: longint; {Loop indexes}
pivot: eltype; {Pivot element}
temp: eltype; {Temp for swapping}
Begin {Sort}
i := bot; {Start at the ends of the range}
j := top;
pivot := sarray[(bot+top) shr 1]; {Choose the middle element}
repeat%;
%if fieldcount = 0 then
while sarray[i] < pivot do {Skip low elements at the bottom}
%;
%if fieldcount = 1 then
while sarray[i].field1 < pivot.field1 do {Skip low elements at the bottom}
%;
%if fieldcount = 2 then %begin
{Skip low elements at the bottom}
while (sarray[i].field1 < pivot.field1) or
((sarray[i].field1 = pivot.field1) and
(sarray[i].field2 < pivot.field2)) do
%; %end;
%if fieldcount = 3 then %begin
{Skip low elements at the bottom}
while (sarray[i].field1 < pivot.field1) or
((sarray[i].field1 = pivot.field1) and
(sarray[i].field2 < pivot.field2)) or
((sarray[i].field1 = pivot.field1) and
(sarray[i].field2 = pivot.field2) and
(sarray[i].field3 < pivot.field3)) do
%; %end;
i := i + 1;
%if fieldcount = 0 then
while sarray[j] > pivot do {Skip high elements at the top}
%;
%if fieldcount = 1 then
while sarray[j].field1 > pivot.field1 do {Skip high elements at the top}
%;
%if fieldcount = 2 then %begin
{Skip high elements at the top}
while (sarray[j].field1 > pivot.field1) or
((sarray[j].field1 = pivot.field1) and
(sarray[j].field2 > pivot.field2)) do
%; %end;
%if fieldcount = 3 then %begin
{Skip high elements at the top}
while (sarray[j].field1 > pivot.field1) or
((sarray[j].field1 = pivot.field1) and
(sarray[j].field2 > pivot.field2)) or
((sarray[j].field1 = pivot.field1) and
(sarray[j].field2 = pivot.field2) and
(sarray[j].field3 > pivot.field3)) do
%; %end;
j := j - 1;
if i <= j {Swap these out-of-order elements}
then begin
temp := sarray[i];
sarray[i] := sarray[j];
sarray[j] := temp;
i := i + 1;
j := j - 1;
end;
until i > j;
if bot < j
then Sort (bot, j);
if i < top
then Sort (i, top);
End; {Sort}
Begin
Sort (lo_end, hi_end);
End;
%End; {GenSort}
© Copyright 2004 Frank Rubin