[OpenBIOS] C's continue statement in Forth?

Segher Boessenkool segher at kernel.crashing.org
Fri Aug 24 21:14:16 CEST 2012


> 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




More information about the OpenBIOS mailing list