2.3.18 Typecase

A TYPECASE statement has the form:

    TYPECASE Expr OF
      T_1 (v_1) => S_1
    | ...
    | T_n (v_n) => S_n
    ELSE S_0
    END
where Expr is an expression whose type is a reference type, the S's are statements, the T's are reference types, and the v's are identifiers. It is a static error if Expr has type ADDRESS or if any T is not a subtype of the type of Expr. The ``ELSE S_0'' and each ``(v)'' are optional.

The statement evaluates Expr. If the resulting reference value is a member of any listed type T_$i$, then S_$i$ is executed, for the minimum such $i$. (Thus a NULL case is useful only if it comes first.) If the value is a member of no listed type and ``ELSE S_0'' is present, then it is executed. If the value is a member of no listed type and ``ELSE S_0'' is absent, a checked runtime error occurs.

Each (v_$i$) declares a variable whose type is T_$i$ and whose scope is S_$i$. If v_$i$ is present, it is initialized to the value of Expr before S_$i$ is executed.

If (v_$i$) is absent, then T_$i$ can be a list of type expressions separated by commas, as shorthand for a list in which the rest of the branch is repeated for each type expression. That is:

    T_1, ..., T_n => S
is shorthand for:
    T_1 => S | ... | T_n => S

For example:

    PROCEDURE ToText(r: REFANY): TEXT =
      (* Assume r = NIL or r^ is a BOOLEAN or INTEGER. *)
      BEGIN
        TYPECASE r OF
          NULL => RETURN "NIL"
        | REF BOOLEAN (rb) => RETURN Fmt.Bool(rb^)
        | REF INTEGER (ri) => RETURN Fmt.Int(ri^)
        END
      END ToText;

m3-support@elego.de