One can handle nested for loops with REPEAT and WHILE loops, without going into FOR loop contortions:
From a Delphi program I wrote long ago. By using dynamic arrays, you can get around a fixed dimension.
unit ForLoopUnit;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type TForm1 = class(TForm) private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
implementation {$R *.DFM}
const Dim = 3;
type TIndex = array[1..Dim] of Integer;
var F: TextFile; Index, LowerBound, UpperBound: TIndex;
procedure Initialize;
var K: Integer;
begin for K := 1 to Dim do begin LowerBound[K] := 0; UpperBound[K] := 5; //Random(6) + 1; end; end; // Initialize
procedure P(const Index: TIndex); // for testing
var K: Integer; S: string;
begin S := 'Index = ['; for K := 1 to Dim - 1 do S := S + IntToStr(Index[K]) + ', '; S := S + IntToStr(Index[Dim]) + ']'; Writeln(F, S); end; // P
procedure MultiForLoop;
var K: Integer;
begin Index := LowerBound; K := Dim; repeat P(Index); while (K >= 1) and (Index[K] = UpperBound[K]) do Dec(K); if K = 0 then Break; // repeat loop // K >= 1, Index[K] < UpperBound[K], // and Index[J] < UpperBound[J] for all J > K Inc(Index[K]); Inc(K); while K <= Dim do begin Index[K] := LowerBound[K]; Inc(K) end; until False; end;
initialization AssignFile(F, 'For.Pas'); Rewrite(F); Initialize; MultiForLoop; CloseFile(F); end.
Harley Flanders
====================================
Frank D. Engel, Jr. wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On Jun 29, 2005, at 2:19 AM, Frank Heckenbach wrote:
GPC accepts the following program, but produces quite silly results:
program Foo;
var a: array [1 .. 2] of Integer value (0, 0); i: Integer;
begin i := 1; for a[i] := 1 to 10 do begin WriteLn (i, ' ', a[i]); if a[i] = 5 then i := 2 end end.
The problem is that it evaluates the index i each time, not once before the loop. It would be possible to fix it, but do we really want that? Neither BP nor CP/EP allow it, they allow only identifiers in for-loops.
Waldek and I see no need for such a feature. (If it made it possible to nest a compile-time-unknown number of `for' loops, I could see some point, but of course, it doesn't.)
Actually, I think it does (untested, though):
CONST max_depth = 100;
FUNCTION Multi_For(depth, limit : INTEGER) : LONGINT; VAR i : INTEGER; a : ARRAY[1..max_depth] OF INTEGER; v : LONGINT;
BEGIN { setup } i := 1; v := 0;
{ the loops } FOR a[i] := 1 TO limit DO BEGIN IF (i < depth) THEN BEGIN INC(i); a[i] := 1 END ELSE BEGIN { actual loop stuff } v := v + a[i]; { handle reduction in depth at end of loop } IF (a[i] = limit) AND (i > 1) THEN DEC(i) END END; Multi_For := v
END;
Frank D. Engel, Jr. fde101@fjrhome.net
$ ln -s /usr/share/kjvbible /usr/manual $ true | cat /usr/manual | grep "John 3:16" John 3:16 For God so loved the world, that he gave his only begotten Son, that whosoever believeth in him should not perish, but have everlasting life. $ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (Darwin)
iD8DBQFCwrkC7aqtWrR9cZoRAmuyAJ0ZJsfJkKGZfHdWr2+9Z1wySk+eCACcCpIJ TWcqtXyw2D5jpyYhkNe36tg= =Gc9l -----END PGP SIGNATURE-----
$0 Web Hosting with up to 200MB web space, 1000 MB Transfer 10 Personalized POP and Web E-mail Accounts, and much more. Signup at www.doteasy.com