/*
* Quicksort by Quintin Stone
* Version 1.0
* The quicksort algorithm for TADS 2.  Uses global to store the list
* being sorted.  Public domain.
*/

quicksort: function(list) {
   global.quicksortlist := list;
   global.doquicksort;
   return global.quicksortlist;
   global.quicksortlist := [];
}

modify global
   partition(start, end) = {
       local pivot, bottom, top, done;
       // Partition around the last value
       pivot := self.quicksortlist[end];
       // Start outside the area to be partitioned
       bottom := start-1;
       top := end;

       done := nil;
       // Until all elements are partitioned...
       while (!done) {
           // Until we find an out of place element...
           while (!done) {
               // ... move the bottom up.
               bottom ++;

               // If we hit the top...
               if (bottom = top) {
                   // ... we are done.
                   done := true;
                   break;
               }

               // Is the bottom out of place?
               if (self.quicksortlist[bottom] > pivot) {
                   // Then put it at the top...
                   self.quicksortlist[top] := self.quicksortlist[bottom];
                   // ... and start searching from the top.
                   break;
               }
           }

           // Until we find an out of place element...
           while (!done) {
               // ... move the top down.
               top := top-1;

               // If we hit the bottom...
               if (top = bottom) {
                   // ... we are done.
                   done := true;
                   break;
               }

               // Is the top out of place?
               if (self.quicksortlist[top] < pivot) {
                   // Then put it at the bottom...
                   self.quicksortlist[bottom] := self.quicksortlist[top];
                   // ...and start searching from the bottom.
                   break;
               }
           }
       }
       // Put the pivot in its place.
       self.quicksortlist[top] := pivot;
       // Return the split point
       return top;
   }
   subquicksort(start, end) = {
       local split;
       // If there are two or more elements...
       if (start < end) {
           // ... partition the sublist...
           split := self.partition(start, end);
           // ... and sort both halves.
           self.subquicksort(start, split-1);
           self.subquicksort(split+1, end);
       } else {
           return;
       }
   }
   doquicksort() = {
       self.subquicksort(1, length(self.quicksortlist));
   }
;