Next: Arbitrary control structures, Previous: BEGIN loops with multiple exits, Up: Control Structures [Contents][Index]
caseGforth provides an extended case that solves the problems of
the multi-exit loops discussed above, and offers additional options.
You can find a portable implementation of this extended case in
compat/caseext.fs.
There are three additional words in the extension. The first is
?of which allows general tests (rather than just testing for
equality) in a case; e.g.,
: sgn ( n -- -1|0|1 )
( n ) case
dup 0 < ?of drop -1 endof
dup 0 > ?of drop 1 endof
\ otherwise leave the 0 on the stack
0 endcase ;
Note that endcase drops a value, which works fine much of the
time with of, but usually not with ?of, so we leave a 0
on the stack for endcase to drop. The n that is passed into
sgn is also 0 if neither ?of triggers, and that is then
passed out.
The second additional word is next-case, which allows turning
case into a loop. Our triple-exit loop becomes:
case condition1 ?of exit-code1 endof condition2 ?of exit-code2 endof condition3 ?of exit-code3 endof ... next-case common code afterwards
As you can see, this solves both problems of the variants discussed
above (see BEGIN loops with multiple exits). Note that
next-case does not drop a value, unlike
endcase.13
The last additional word is contof, which is used instead of
endof and starts the next iteration instead of leaving the
loop. This can be used in ways similar to Dijkstra’s guarded command
do, e.g.:
: gcd ( n1 n2 -- n )
case
2dup > ?of tuck - contof
2dup < ?of over - contof
endcase ;
Here the two ?ofs have different ways of continuing the loop;
when neither ?of triggers, the two numbers are equal and are
the gcd. Endcase drops one of them, leaving the other as n.
You can also combine these words. Here’s an example that uses each of
the case words once, except endcase:
: collatz ( u -- )
\ print the 3n+1 sequence starting at u until we reach 1
case
dup .
1 of endof
dup 1 and ?of 3 * 1+ contof
2/
next-case ;
This example keeps the current value of the sequence on the stack. If
it is 1, the of triggers, drops the value, and leaves the
case structure. For odd numbers, the ?of triggers,
computes 3n+1, and starts the next iteration with contof.
Otherwise, if the number is even, it is divided by 2, and the loop is
restarted with next-case.
Next-case has a -, unlike the
other case words, because VFX Forth contains a nextcase
that drops a value.
Next: Arbitrary control structures, Previous: BEGIN loops with multiple exits, Up: Control Structures [Contents][Index]