<< Home | About Forth | About TurboForth | Download | Language Reference | Resources | Tutorials | YouTube >>
Forth has a number of words in its vocabulary to make a body of code repeat either indefinitely, or a fixed or variable number of times.
The BEGIN...AGAIN loop construct is used when you want a section of your code to loop forever.
: FOREVER BEGIN ." Hello Mother! " AGAIN ;
In this example, AGAIN causes the program to repeat from the word just after BEGIN. Note that BEGIN itself is not executed.
BEGIN and AGAIN can only be used in colon definitions.
When you want to execute a loop a fixed, or a variable number of times, the DO...LOOP construct is one option that you have available.
It works like this:
limit start DO <code here> LOOP
: TEST 100 0 DO ." I'm in a loop " LOOP ;
In this example, the loop will execute 100 times, starting at 0 and ending at 99. The word I (see below) is available to retrieve the current loop count.
You don't have to start counting from 0 if you don't want to:
: TEST 100 10 DO ." Another loop " LOOP ;
The above example will repeat exactly 90 times - starting at 10 and ending at 99.
Of course, you don't have to use numbers in front of DO. DO just expects two numbers on the stack (and consumes them), so you can use words instead of numbers, which may in turn perform some sort of calculation and push a value to the stack. For example:
: TEST endPoint startPoint DO LOOP <code here> LOOP ;
Here, startPoint and endPoint are words that perform some calculation and push values to the stack.
I is a word just like any other Forth word. It is used to get the current index of a loop:
: TEST 100 DO I . LOOP ;
Here we have a DO...LOOP construct. The loop will execute 100 times; starting at 0 and ending at 99. I is used to track the current index of the loop. When called, it pushes the current index to the stack.
When used with LOOP, I increases by 1 each time through the loop. When used with +LOOP I will be modified by the value supplied to +LOOP, as shown below:
: TEST 100 0 DO I . 3 +LOOP ;
Here, I increases by 3 each time through the loop. See below for a discussion of +LOOP.
J is similar to I, but is used in a nested. It allows one to get the index of the outer loop from the inner loop:
: TEST 10 0 DO I . ASCII : EMIT 5 0 DO J . LOOP CR LOOP ;
In this example, the first loop (the outer loop) displays its index. Note that it is reffering to its own index, so it uses I. The inner loop also displays the index of the outer loop. To do this, it uses J.
+LOOP is used when you want the index of the loop to change by more than one on each iteration of the loop. For example:
: TwoByTwo 100 0 DO I . 2 +LOOP ;
Here, the loop increases by 2 on each iteration of the loop. When the index exceeds the maximum index value (100 in this example) the loop will terminate and execution continues with the word following +LOOP, just like LOOP.
+LOOP can be used to make a loop count backwards:
: -TwoByTwo 0 100 DO I . -2 +LOOP ;
Here, -2 is added to the loop on each iteration. Note that the loop begins counting at 100, the maximum is 0.
FOR and NEXT are used like DO...LOOP. However, the loop always counts backwards to 0. Example:
: ForTest 100 FOR I . NEXT ;
Each time next is encountered execution loops back to the word immediately after FOR. When the loop index (I) reaches 0, the loop terminates, and execution resumes with the word immediately following NEXT. Note that I, J and LEAVE are also available for use inside FOR/NEXT loops.
BEGIN...WHILE...REPEAT is a useful loop construct where a condition can be tested before code is executed, as in the following example:
In the above example, KEY is called, which waits for a key to be pressed and leaves the ASCII keycode on the stack. We then AND the keycode with 1 to determine if the keycode is odd or even. If the code is even, the result of the 1 AND will be 0, otherwise it will be 1. The conditional loop then begins. If the value on the stack is TRUE then the code following WHILE is allowed to execute. When REPEAT is encountered, the program jumps back to BEGIN. However, if the value on the stack is FALSE, the code after WHILE does not execute, and execution jumps to the word after REPEAT, thus terminating the program.
LEAVE is used inside a DO...LOOP or a FOR...NEXT loop to exit the loop early. It should be placed inside an IF...THEN block:
<-- Back to Tutorials
<< Home | About Forth | About TurboForth | Download | Language Reference | Resources | Tutorials | YouTube | Forum >>