Next: Calls and returns, Previous: General control structures with case, Up: Control Structures [Contents][Index]
Standard Forth permits and supports using control structures in a non-nested way. Information about incomplete control structures is stored on the control-flow stack. This stack may be implemented on the Forth data stack, and this is what we have done in Gforth.
An orig entry represents an unresolved forward branch, a dest entry represents a backward branch target. A few words are the basis for building any control structure possible (except control structures that need storage, like calls, coroutines, and backtracking).
IF ( compilation – orig ; run-time f – ) core
At run-time, if f=0, execution continues after the
THEN (or ELSE) that consumes the orig,
otherwise right after the IF (see Selection).
AHEAD ( compilation – orig ; run-time – ) tools-ext
At run-time, execution continues after the THEN that
consumes the orig.
THEN ( compilation orig – ; run-time – ) core
The IF, AHEAD, ELSE or WHILE that
pushed orig jumps right after the THEN
(see Selection).
BEGIN ( compilation – dest ; run-time – ) core
The UNTIL, AGAIN or REPEAT that consumes
the dest jumps right behind the BEGIN
(see General Loops).
UNTIL ( compilation dest – ; run-time f – ) core
At run-time, if f=0, execution continues after the
BEGIN that produced dest, otherwise right after
the UNTIL (see General Loops).
AGAIN ( compilation dest – ; run-time – ) core-ext
At run-time, execution continues after the BEGIN that
produced the dest (see General Loops).
CS-PICK ( dest0/orig0 dest1/orig1 ... destu/origu u – ... dest0/orig0 ) tools-ext “c-s-pick”
CS-ROLL ( destu/origu .. dest0/orig0 u – .. dest0/orig0 destu/origu ) tools-ext “c-s-roll”
CS-DROP ( dest/orig – ) gforth-1.0
The Standard words cs-pick and cs-roll allow you to
manipulate the control-flow stack in a portable way. Without them, you
would need to know how many stack items are occupied by a control-flow
entry (Many systems use one cell. In Gforth they currently take four
cells, but this may change in the future).
When using cs-pick and cs-drop on an orig, you need to
use one cs-drop for every cs-pick (and vice versa) of a
given orig, because the orig must be resolved by then exactly
once.
Some standard control structure words are built from these words:
ELSE ( compilation orig1 – orig2 ; run-time – ) core
At run-time, execution continues after the THEN that
consumes the orig; the IF, AHEAD, ELSE
or WHILE that pushed orig1 jumps right after the
ELSE. (see Selection).
WHILE ( compilation dest – orig dest ; run-time f – ) core
At run-time, if f=0, execution continues after the
REPEAT (or THEN or ELSE) that consumes the
orig, otherwise right after the WHILE
(see General Loops).
REPEAT ( compilation orig dest – ; run-time – ) core
At run-time, execution continues after the BEGIN that
produced the dest; the WHILE, IF,
AHEAD or ELSE that pushed orig jumps right
after the REPEAT. (see General Loops).
Gforth adds some more control-structure words:
ENDIF ( compilation orig – ; run-time – ) gforth-0.2
Same as THEN.
?dup-IF ( compilation – orig ; run-time n – n| ) gforth-0.2 “question-dupe-if”
This is the preferred alternative to the idiom "?DUP
IF", since it can be better handled by tools like stack
checkers. Besides, it’s faster.
?DUP-0=-IF ( compilation – orig ; run-time n – n| ) gforth-0.2 “question-dupe-zero-equals-if”
Next: Calls and returns, Previous: General control structures with case, Up: Control Structures [Contents][Index]