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 ;