Like colorforth, the control structures in avrforth are simpler and fewer in number than the traditional ANS control words. However, the ANS words can be added for compatibility if needed.
;
and ;;
both end the current colon definition,
but are not identical. ;;
always compiles a ret
.
;
checks if the preceeding instruction is a call
.
If so, it changes the call
to a jmp
. If not,
it compiles a ret
like ;;
.
if
performs a branch to the next then
if the
last result was zero (false). Therefore, the code between if
and then
is executed when the last result was nonzero (true).
if
does not consume the top stack element -- if works by
looking at the z-bit in the status register. Similarly, -if
branches according to the n-bit.
There is no else
. To get the functional equivalent of
if
..else
..then
, use
if
..then
with multiple returns like so:
:
foo condition if
true section
;
then
false section ;
If you need to test the top of stack directly without doing a calculation,
use ?
immediately before if
. It makes sure the
z-bit it set correctly.
Loops are formed by a word calling itself. Since words are not hidden when
they are being defined, they can be used in their own definition without
using special words like recurse
. Adding a ;
after a recursive call changes the call to a jump, avoiding stack overflow.
Usually, loops are combined with one or more if..then constructs so the
loop is not infinite. The following trivial example decrements the top
item of stack until it reaches zero.
:
loop ( x -- ) ] 1- if ] loop ; then ] drop ;