Previous | Table of Contents | Next |
A CASE statement has the form
CASE Expr OF L1 => S1 | ... | Ln => Sn ELSE S0 END
where Expr is an expression whose type is an ordinal type and each L is a list of constant expressions or ranges of constant expressions denoted by e1..e2, which represent the values from e1 to e2 inclusive. If e1 exceeds e2, the range is empty. It is a static error if the sets represented by any two Ls overlap or if the value of any of the constant expressions is not a member of the type of Expr. The ELSE S0 is optional.
The statement evaluates Expr. If the resulting value is in any Li, then Si is executed. If the value is in no Li and ELSE S0 is present, then it is executed. If the value is in no Li and ELSE S0 is absent, a checked runtime error occurs.
A TYPECASE statement has the form
TYPECASE Expr OF T1 (v1) => S1 | ... | Tn (vn) => Sn ELSE S0 END
where Expr is an expression whose type is a reference type, s0, ,sn are statements, the Ts are reference types, and the vs 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 S0 and each (v) are optional.
The statement evaluates Expr. If the resulting reference value is a member of any listed type Ti, then Si 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 S0 is present, then it is executed. If the value is a member of no listed type and ELSE S0 is absent, a checked runtime error occurs.
Each (vi) declares a variable whose type is Ti and whose scope is Si. If vi is present, it is initialized to the value of Expr before Si is executed.
If (vi) is absent, then Ti 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:
T1, ..., Tn => S
is shorthand for
T1 => S | ... | Tn => S
Here is an 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;
A LOCK statement has the form
LOCK mu DO S END
where S is a statement and mu is an expression. It is equivalent to
WITH m = mu DO Thread.Acquire(m); TRY S FINALLY Thread.Release(m) END END
where m stands for a variable that does not occur in S.
INC and DEC statements have the form
INC(v, n) DEC(v, n)
where v designates a variable of an ordinal type and n is an optional integer-valued argument. If omitted, n defaults to 1. The statements increment and decrement v by n, respectively. The statements are equivalent to
WITH x = v DO x := VAL(ORD(x) + n, T) END WITH x = v DO x := VAL(ORD(x) - n, T) END
where T is the type of v and x stands for a variable that does not appear in n. As a consequence, the statements check for range errors. In unsafe modules, INC and DEC are extended to ADDRESS.
Previous | Table of Contents | Next |