$c+
module test17_3 { quicksort
-- test of arrays, nested  recursive procedures,
-- parameters, local procedures.
}
private
constant max = 31;
constant mlo = max - 1;
typedefinition integer range [0..mlo] zero_mlo;
typedefinition integer array [zero_mlo] sortable;
sortable a;
integer i;

 tuple [procedure quick(value integer l,h)] sorter;
 procedure sorter@quick
   tuple [procedure partition (value integer l,h; reference integer m)] split;
   procedure split@partition 
     integer b, t;
   begin
     m := l;
     b := l;
     do  b < h ->
		   b := b + 1;
		   if a[b] >= a[l] -> skip;
		     [] a[b] < a[l] ->
		          m := m + 1;
				  t := a[m]; a[m] := a[b]; a[b] := t;
		   fi;
     od;
     t := a[l]; a[l] := a[m]; a[m] := t;
     return;
   end; { partition}

   integer m;

 begin { quick }
  if  l >= h -> skip;
   [] l <  h ->
		split!partition(l,h, m);
		sorter!quick(l,m - 1);
		sorter!quick(m + 1, h);
   fi;
 end; { quick}

begin
i := 0; do i < max -> read a[i]; i:= i+1; od;
write 'values';
i := 0; do i < max -> write a[i]; i:= i+1; od;
sorter!quick(0,mlo);
write 'sorted:';
i := 0; do i < max -> write a[i]; i:= i+1; od;
end.
