Subsections

Multiple choice

Sometimes the number of choices can be quite large or the different choices are related in a simple way. For example, consider the following conditional clause:

   IF n = 1
   THEN action1
   ELIF n = 2
   THEN action2
   ELIF n = 3
   THEN action3
   ELIF n = 4
   THEN action4
   ELSE action5
   FI

This sort of choice can be expressed more concisely using the case clause in which the boolean enquiry clause is replaced by an integer enquiry clause. Here is the above conditional clause rewritten using a case clause:

   CASE n
   IN
      action1
         ,
      action2
         ,
      action3
         ,
      action4
   OUT
      action5
   ESAC

which could be abbreviated as

   (n|action1,action2,action3,action4|action5)

Notice that action1, action2, action3 and action4 are separated by commas (they are not terminators). Each of action1, action2 and action3 is a unit, so that if you want more than one phrase for each action, you must make it an enclosed clause by enclosing the action in parentheses (or BEGIN and END). If the INT enquiry clause yields 1, action1 is elaborated, 2, action2 is elaborated and so on. If the value yielded is negative or zero, or exceeds the number of actions available, action5 in the OUT part is elaborated. The OUT part is a serial clause so no enclosure is required if there is more than one unit.

In the following case clause, the second unit is a conditional clause to show you that any piece of program which happens to be a unit can be used for one of the cases:

   CASE i IN 3,(x>3.5|4|-2),6 OUT i+3 ESAC

The first action yields 3, the second yields 4 if x exceeds 3.5 and -2 otherwise, and the third action yields 6.

Sometimes the OUT clause consists of another case clause. For example,

   CASE n MOD 4
   IN
      print("case 1"),
      print("case 2"),
      print("case 3")
   OUT
      CASE (n-10) MOD 4
      IN
         print("case 11"),
         print("case 12"),
         print("case 13")
      OUT
         print("other case")
      ESAC
   ESAC

Just as with ELIF in a conditional clause, OUT CASE ... ESAC ESAC can be replaced by OUSE ... ESAC. So the above example can be rewritten

   CASE n MOD 4
   IN
      print("case 1"),
      print("case 2"),
      print("case 3")
   OUSE (n-10) MOD 4
   IN
      print("case 11"),
      print("case 12"),
      print("case 13")
   OUT print("other case")
   ESAC

Here is a case clause with embedded case clauses:

   CASE command
   IN
      action1,
      action2,
      (subcommand1
      |subaction1,subaction2
      |subaction3)
   OUSE subcommand2
   IN subaction4,
      subaction5,
      subaction6
   OUT
      subaction7
   ESAC

Calendar computations, which are notoriously difficult, give examples of case clauses:

   INT days = CASE month IN
               31,
               IF year MOD 4 = 0
                       &
                  year MOD 100 /= 0
                      OR
                  year MOD 400 = 0
               THEN 29
               ELSE 28
               FI,
               31,30,31,30,31,31,30,31,30,31
               OUT -1
              ESAC

And here is one in dealing cards:

   []CHAR suit=(i|"spades",
                  "hearts",
                  "diamonds",
                  "clubs"
                 |"")

Like the conditional clause, if you omit the OUT part, the compiler assumes that you wrote OUT SKIP. In the following example, when i is 4, nothing gets printed:5.3

   PROGRAM prog CONTEXT VOID
   USE standard
   FOR i TO 5
   DO
      print((i MOD 4|"a","g","r"))
   OD
   FINISH

Exercises

4.8
What is wrong with the following identity declaration, assuming that p has been predeclared as a value of mode BOOL:
   INT i = (p|1,2,3|4)
Ans[*]
4.9
Write a program consisting solely of a case clause which uses the SIGN operator to give three different actions depending on the sign of a number of mode REAL. Ans[*]


Sian Mountbatten 2012-01-19