#### 6.9.5 General control structures with `case` ¶

Gforth 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 `?of`s 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`.

#### Footnotes

##### (13)

`Next-case` has a `-`, unlike the other `case` words, because VFX Forth contains a `nextcase` that drops a value.