
GRADE in S14 chose among three things with two IFs and already looked a mess. Seven days of the week that way would be unreadable. SuperForth has a structure made for the job.
: DAY CASE
1 =OF ." MON" ENDOF
2 =OF ." TUE" ENDOF
." ???" ENDCASE ;
CASE takes the number on the stack and holds it up against each test in turn.
1 =OF means "if it equals 1". When a test matches, the words up to the next ENDOF run, and then everything else is skipped, straight to ENDCASE. When it does not match, SuperForth moves on to the next test.
Anything between the last ENDOF and ENDCASE is the default: it runs only if nothing matched. It is optional, but a program that says nothing at all when it meets something unexpected is hard to debug, so put one in.
ENDCASE finishes the structure and throws the number away, so the stack is clean whichever branch ran.
This is a natural definition to spread over several lines. One line for each possibility reads like a table, which is what it is.
: DAY CASE
1 =OF ." MON" ENDOF
2 =OF ." TUE" ENDOF
." ???" ENDCASE ;
1 DAY
2 DAY
9 DAY
Starting from
A fresh boot, with SuperForth just started.
What you should see
No ok until the fourth line, which has the semicolon. Then:
1 DAY
MONok
2 DAY
TUEok
9 DAY
???ok

=OF is not the only test.
| Test | Matches when the value is |
|---|---|
n =OF | equal to n |
n <OF | less than n |
n1 n2 <OF> | anywhere from n1 to n2, including both ends |
: GRADE CASE
50 <OF ." FAIL" ENDOF
50 69 <OF> ." PASS" ENDOF
." MERIT" ENDCASE ;
Below 50 fails, 50 to 69 passes, and the default catches everything above. Compare how it reads with S14's version. (The two draw their lines in slightly different places: this one passes a 50.)
The tests are tried in order and the first match wins, so put narrow tests before wide ones.
3 =OF ." WED" ENDOF to DAY. Where does the new line have to go, and where must it not go?DAY. What does 9 DAY do now?GRADE, try 49, 50, 69 and 70. Which side of each boundary does each number fall?GRADE. Does anything change? Would it if the first test were 70 <OF?16.1 Finish DAY for all seven days.
16.2 Define MENU to wait for a key and print APPLE if it was A, BANANA if it was B, and ? for anything else.
16.3 Define SEASON ( month -- ) to print the season for a month number from 1 to 12, using ranges. Winter wraps round the end of the year: how will you deal with December?
Worked solutions are in Appendix II.
| Symptom | Cause |
|---|---|
No ok after you thought you had finished | SuperForth is still inside the definition. Something is missing - usually ENDCASE, or the semicolon. |
| A later branch never runs | An earlier, wider test caught the value first. Order them narrow to wide. |
Empty Stack, or a number missing afterwards | A DROP you put in a branch. ENDCASE already drops the value. |
CASE holds a value against a list of tests - =OF, <OF, <OF> - and runs the words after the first that matches, up to its ENDOF. Words before ENDCASE are the default. ENDCASE drops the value. Lay it out one possibility to a line.
S17, Other Bases - the same numbers written in sixteens and in twos, and why a programmer would want them that way.