The DO ... LOOP
execute always at least one time. If I want to skip execution when limit = index, I can put the loop inside a if ... then
:
2DUP <> IF DO ... LOOP THEN
The recommended alternative is
?DO ... LOOP
In this last case, where does THEN
goes? As I see it, the ?DO
word contains an IF
that doesn't get closed.
The word ?do
can be defined via do
as follows.
: noop ( -- ) ;
: then, ( orig -- ) postpone then ;
: ?do ( -- do-sys )
postpone 2dup postpone =
postpone if postpone 2drop
postpone else
postpone do ['] then,
; immediate
: do ( -- do-sys )
postpone do ['] noop
; immediate
: loop ( do-sys -- )
>r postpone loop r> execute
; immediate
: +loop ( do-sys -- )
>r postpone +loop r> execute
; immediate
With this ?do
, a definition:
: foo ?do bar baz loop ;
is compiled as:
: foo 2dup = if 2drop else do bar baz loop then ;
In some Forth implementations, if you perform see ?do
, it will show you that ?do
contains if
and else
, as well as see then,
will show that then,
(sic comma) contains then
. This means that then,
performs the compilation semantics of then
, and ?do
performs the compilation semantics of if
and else
.