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).
At run-time, if f=0, execution continues after the
THEN
(or ELSE
) that consumes the orig,
otherwise right after the IF
(see Selection).
At run-time, execution continues after the THEN
that
consumes the orig.
The IF
, AHEAD
, ELSE
or WHILE
that
pushed orig jumps right after the THEN
(see Selection).
The UNTIL
, AGAIN
or REPEAT
that consumes
the dest jumps right behind the BEGIN
(see General Loops).
At run-time, if f=0, execution continues after the
BEGIN
that produced dest, otherwise right after
the UNTIL
(see General Loops).
At run-time, execution continues after the BEGIN
that
produced the dest (see General Loops).
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:
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).
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).
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:
Same as THEN
.
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.