Dr.CH.Ting:

“n FOR-NEXT runs n+1 loops by design”

Why and how to cope with:

https://github.com/TG9541/stm8ef/wiki/eForth-FOR-..-NEXT

# Discussion of eForth FOR .. NEXT

While it’s advisable to use the STM8 eForth `DO .. LEAVE .. LOOP/+LOOP` structure instead of `FOR .. NEXT` and its variants, the following discussion deals with the most main properties, idioms and limitations of the this “eForth-ism”.

## Basic properties of eForth `FOR .. NEXT`

Among “small Forth implemenations” the eForth `FOR .. NEXT` construct is idiosyncratic, and some of its properties and idioms are rather difficult to understand.

Here is a the basic `FOR .. NEXT` loop:

```: test-for
FOR I . NEXT ;```

`NEXT` decrements the loop counter on the return stack (accessible with `I` or `R@`) and loops while the counter is positive. `4 test-for` prints `4 3 2 1 0``0 test-for` prints `0`, and `-1 test-for` prints `-1`.

The following `FOR .. NEXT` properties are noteworthy:

• at least one iteration, with the loop counter equal to the input to `FOR` will be performed
• the nuber of iterations is limited to 32768, and
• the loop count will be “one-too-many” compared to standard loop structures (e.g. `DO .. LOOP`)

## eForth `FOR .. AFT .. THEN .. NEXT`

The most unusual feature eForth provides is the word `AFT`:

```: test-aft1 ( n -- )
FOR
\ first loop
."  for"
AFT
\ following iterations
."  aft"
THEN
\ all iterations
I .
NEXT ;```

`2 test-aft1` prints `for 2 aft 1 aft 0`. Why one would need such a control structure is all but obvious. The eForth core implementation use of `AFT`, however, shows that it not only works around the “one-too-many” iterations in `FOR .. NEXT`, but it also provides loop count testing if the actual “loop clause code” is in the `AFT .. THEN` block:

```: test-aft2 ( n -- )
FOR AFT
I .
THEN NEXT ;```

Running `3 test-aft2` prints `2 1 0`, and `0 test-aft2` or `-1 test-aft2` print nothing at all. This structure is widely used in the eForth core, e.g. in `CMOVE``SAME?` and `TYPE`. The effect is that input testing around `FOR .. NEXT`, especially for `0` counts, isn’t needed.

## eForth `FOR .. WHILE .. NEXT .. ELSE .. THEN`

A loop structure similar to `DO .. LEAVE .. LOOP` can be implemented in “pure eForth” with an idiomatic combination of `FOR .. NEXT``WHILE`, and `ELSE .. THEN`:

```: test-for-while ( n1 n2 -- )
FOR
DUP I = NOT WHILE
I . \ limit not reached
NEXT
."  end"
ELSE
."  limit"
R> DROP \ remove the FOR loop counter
THEN
DROP ;   \ drop limit```

In this example, `5 10 test-for-while` prints `10 9 8 5 6 limit`, and `5 4 test-for-while` prints `4 3 2 1 0 end`.

`WHILE` puts a the address of its conditional branch target on the stack above the start address of `FOR` the for loop (which is used when compiling `NEXT`). During compilation, `ELSE` then uses this address to make `WHILE` exit to the code block delimited by `THEN`. Note that the `ELSE` clause is responsible of removing the loop counter from the return stack.

Note that the `FOR .. WHILE .. NEXT .. ELSE .. THEN` idiom can’t be mixed with the `FOR .. AFT .. THEN .. NEXT` idiom!