From: minforth@gmx.net   
      
   Am 07.07.2025 um 08:54 schrieb Gerry Jackson:   
   > On 03/07/2025 20:33, minforth wrote:   
   >> On Sat, 28 Jun 2025 21:01:48 +0000, Anton Ertl wrote:   
   >>   
   >>> sean@conman.org writes:   
   >>>> What is the difference between FOR/NEXT and DO/LOOP? Don't they do   
   >>>> the   
   >>>> same thing?   
   >>>   
   >>> FOR ... NEXT on one system does not do the same thing as FOR ... NEXT   
   >>> on some other systems, and they all behave different from DO ... LOOP.   
   >>>   
   >>   
   >> Correct. Here are variants with iterators that even run on gforth 0.7.9:   
   >>   
   >> \ ====== FOR# .. #TIMES   
   >> ==================================================   
   >> \ original: machine code   
   >> \ demo variant: slow Forth   
   >>   
   >> : _ITERATE \ end xt   
   >> swap   
   >> BEGIN dup 0>   
   >> WHILE over execute 1-   
   >> REPEAT 2drop ;   
   >>   
   >> : FOR# postpone [: ; IMMEDIATE   
   >>   
   >> : #TIMES postpone ;] postpone _iterate ; IMMEDIATE   
   >>   
   >> \ ====== FOR .. N M .. NEXT   
   >> ==============================================   
   >   
   > I've found looping quotations useful but I like to include the quotation   
   > inside the loop e.g. (without the syntactic sugar and moving the   
   > iterator inside the quotation):   
   >   
   > : downcount begin [: dup 0> if dup . 1- then ;] over 0> while execute   
   > repeat 2drop ;   
   > 10 downcount \ displays 10 9 8 7 6 5 4 3 2 1 ok   
   >   
   > Advantages are:   
   > 1) The xt is not passed to the quotation and so doesn't get in the way.   
   > 2) The xt is loaded as a literal when the quotation exits.   
   > 3) The quotation can exit the loop early by EXITing with 0 on the stack.   
      
   That's the nice thing about Forth: you can mould it to your taste. :-)   
      
   My initial motivation was that I wanted free access to the return   
   stack, and to kick UNLOOP out. From my slow playhorse Forth   
   (VM with address interpreter):   
      
   \ ------ Template: n FOR .. NEXT and adr n elsize FOR> .. NEXT   
   \ (negative elsize iterates backwards over array)   
   \ Primitives:   
   \ _ITERATE ( a n s xt -- ) M3 iterator (max. nesting depth 2)   
   \ N ( -- n ) N! ( n -- ) inner index in single FOR..NEXT loop   
   \ M ( -- n ) M! ( n -- ) inner index in nested FOR.FOR..NEXT.NEXT loops   
   : FOR> postpone [: ; IMMEDIATE \ M3   
   : FOR 0 postpone literal postpone swap 1 postpone literal   
    postpone for> ; IMMEDIATE \ M3   
   : NEXT postpone ;] postpone _iterate ; IMMEDIATE \ M3   
      
   Demo session:   
      
   +---------------------+   
   ¦ Min3rd Core Forth ¦   
   +---------------------+   
   1020048 bytes free   
   # : T1 10 FOR n . NEXT ; ok   
   # t1 0 1 2 3 4 5 6 7 8 9 ok   
   : t4 10 FOR -111 >r n . r> drop NEXT ; ok   
   # t4 0 1 2 3 4 5 6 7 8 9 ok   
   # : T2 pad 5 cell FOR> n u. NEXT ; ok   
   # : T3 pad 5 cell negate FOR> n u. NEXT ; ok   
   # hex ok   
   $ pad u. F7BD2F1C ok   
   $ t2 F7BD2F1C F7BD2F20 F7BD2F24 F7BD2F28 F7BD2F2C ok   
   $ t3 F7BD2F2C F7BD2F28 F7BD2F24 F7BD2F20 F7BD2F1C ok   
   $ decimal ok   
   # fload demo/for_next.m3   
   Benchmarking 1000000 loops:   
   DO..LOOP: 101.7 ms   
   FOR..NEXT: 26.5 ms ok   
   # : T5 3 FOR 7 >r 3 FOR 8 >r n . m . r> drop NEXT r> drop NEXT ; ok   
   # t5 0 0 1 0 2 0 0 1 1 1 2 1 0 2 1 2 2 2 ok   
   #   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|