SuperForth for the Tatung Einstein, showing a SuperForth 1.12 session defining a word
← Back to Courses
module
16

One Of Several

Introduction

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.

CASE

: 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.

The Code

: 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

DAY defined over four lines, then tried on 1, 2 and 9

Ranges

=OF is not the only test.

TestMatches when the value is
n =OFequal to n
n <OFless 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.

Change One Thing

  • Add 3 =OF ." WED" ENDOF to DAY. Where does the new line have to go, and where must it not go?
  • Take the default out of DAY. What does 9 DAY do now?
  • In GRADE, try 49, 50, 69 and 70. Which side of each boundary does each number fall?
  • Swap the two test lines in GRADE. Does anything change? Would it if the first test were 70 <OF?

Exercises

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.

When It Goes Wrong

SymptomCause
No ok after you thought you had finishedSuperForth is still inside the definition. Something is missing - usually ENDCASE, or the semicolon.
A later branch never runsAn earlier, wider test caught the value first. Order them narrow to wide.
Empty Stack, or a number missing afterwardsA DROP you put in a branch. ENDCASE already drops the value.

Summary

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.

Next

S17, Other Bases - the same numbers written in sixteens and in twos, and why a programmer would want them that way.

Get the Newsletter

New guides, disk images and community finds, roughly once a quarter. No spam, we promise, this isn't Tatung's marketing department.
Your subscription could not be saved. Please try again.
Your subscription has been successful.

Newsletter

Subscribe to our newsletter and stay updated.