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