I was wondering if there is a way to implement C's continue
statement in Forth. I have this loop, and some times I only want to
execute part of it, and then continue on to the next iteration
without finishing the current iteration. Is there any way of doing
this in OpenBIOS?
It certainly can be done. But it sounds like you are making a
word with a very big body; this is not the Forth way. Instead,
factor your words into smaller words, for example, pull the loop
body (the part between WHILE and REPEAT) into a separate word.
It then becomes trivial to do your "continue" (and it will also
be much more readable!)
begin
\ condition
while
\ conditional code
if
CONTINUE \ skip rest of loop
then
\ rest of loop ...
repeat
You don't have anything in here that "increases" the condition
(increases some counter, follows a pointer, whatever). Typically
you would have that just before the REPEAT, but your example makes
it seem you have it between the BEGIN and WHILE. So your code is:
BEGIN cond WHILE smth IF CONTINUE THEN rest REPEAT
which you can write as
BEGIN cond WHILE smth 0= IF rest THEN REPEAT
(and if you do have an "increment" just before the REPEAT, which
you want to run on CONTINUE, you can put it between the THEN and
REPEAT in the modified example).
But, let's build a CONTINUE like you described, just for fun.
Let's look at the structure words you used:
BEGIN ( C: -- dest )
WHILE ( C: dest -- orig dest )
REPEAT ( C: orig dest -- )
You want to use your CONTINUE word between WHILE and REPEAT, and
it should jump back to "dest"; at compile time, it should not drop
the "dest" from the compilation stack. So its stack diagram is
CONTINUE ( C: orig dest -- orig dest )
or just
CONTINUE ( C: dest -- dest )
For doing an unconditional jump back, there is AGAIN, which is
AGAIN ( C: dest -- )
That eats the dest from the compilation stack though, so we want
to duplicate it first, using CS-DUP
CS-DUP ( C: dest -- dest dest )
Not every system has that; just make it from CS-PICK, like so:
: CS-DUP 0 CS-PICK ; IMMEDIATE
And then let's do CONTINUE itself:
: CONTINUE CS-DUP POSTPONE AGAIN ; IMMEDIATE
Or you might want a ?CONTINUE which does the equivalent of
IF CONTINUE THEN:
: ?CONTINUE POSTPONE 0= CS-DUP POSTPONE UNTIL ; IMMEDIATE
Hope this helps,
Segher