• Re: LOOP

    From Gerry Jackson@do-not-use@swldwa.uk to comp.lang.forth on Mon Jul 7 07:54:19 2025
    From Newsgroup: comp.lang.forth

    On 03/07/2025 20:33, minforth wrote:
    On Sat, 28 Jun 2025 21:01:48 +0000, Anton Ertl wrote:

    sean@conman.org writes:
    -aWhat is the difference between FOR/NEXT and DO/LOOP?-a 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:

    \ ====== <n> FOR# .. #TIMES ==================================================
    \ original: machine code
    \ demo variant: slow Forth

    : _ITERATE \ end xt
    -a-a-a-aswap
    -a-a-a-aBEGIN dup 0>
    -a-a-a-aWHILE over execute 1-
    -a-a-a-aREPEAT 2drop ;

    : FOR# postpone [: ; IMMEDIATE

    : #TIMES postpone ;] postpone _iterate ; IMMEDIATE

    \ ====== <n> 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.
    --
    Gerry
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From minforth@minforth@gmx.net to comp.lang.forth on Mon Jul 7 10:46:24 2025
    From Newsgroup: comp.lang.forth

    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:
    -aWhat is the difference between FOR/NEXT and DO/LOOP?-a 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:

    \ ====== <n> FOR# .. #TIMES
    ==================================================
    \ original: machine code
    \ demo variant: slow Forth

    : _ITERATE \ end xt
    -a-a-a-a-aswap
    -a-a-a-a-aBEGIN dup 0>
    -a-a-a-a-aWHILE over execute 1-
    -a-a-a-a-aREPEAT 2drop ;

    : FOR# postpone [: ; IMMEDIATE

    : #TIMES postpone ;] postpone _iterate ; IMMEDIATE

    \ ====== <n> 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-a 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:

    +---------------------+
    -a Min3rd Core Forth -a
    +---------------------+
    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
    #








    --- Synchronet 3.21a-Linux NewsLink 1.2