SELECT..OF block is a bit more complicated than the normal
SELECT block, but can be very useful.
It has the following form:
SELECT maxrange OF expression CASE constA statementsA CASE constB1 TO constB2 statementsB CASE range1, range2 statementsC DEFAULT statementsD ENDSELECT
The value to be matched is expression, which can be any expression, not just a variable like in the normal
However, the maxrange, constA, constB1 and constB2 must all be explicit numbers, i.e., constants (see 8 Constants).
maxrange must be a positive constant and the other constants must all be between zero and maxrange (including zero but excluding maxrange).
CASE values to be matched are specified using ranges.
A simple range is a single constant (the first
The more general range is shown in the second
CASE, using the
TO keyword (constB2 must be greater than constB1).
CASE in the
SELECT..OF block can specify a number of possible ranges to match against by separating each range with a comma, as in the third
For example, the following
CASE lines are equivalent and can be used to match any number from one to five (inclusive):
CASE 1 TO 5 CASE 1, 2, 3, 4, 5 CASE 1 TO 3, 3 TO 5 CASE 1, 2 TO 3, 4, 5 CASE 1, 5, 2, 4, 3 CASE 2 TO 3, 5, 1, 4
If the value of the expression is less than zero, greater than or equal to maxrange, or it does not match any of the constants in the
CASE ranges, then the statements in the
DEFAULT part are executed.
Otherwise the statements in the first matching
CASE part are executed.
As in the normal
SELECT block, there does not need to be a
SELECT..OF block prints the (numeric) day of the month nicely:
SELECT 32 OF day CASE 1, 21, 31 WriteF('The \dst day of the month\n', day) CASE 2, 22 WriteF('The \dnd day of the month\n', day) CASE 3, 23 WriteF('The \drd day of the month\n', day) CASE 4 TO 20, 24 TO 30 WriteF('The \dth day of the month\n', day) DEFAULT WriteF('Error: invalid day=\d\n', day) ENDSELECT
The maxrange for this block is 32, since 31 is the maximum of the values used in the
If the value of
day was 100, for instance, then the statements in the
DEFAULT part would be executed, signalling an invalid day.
This example can be rewritten as an
IF (day=1) OR (day=21) OR (day=31) WriteF('The \dst day of the month\n', day) ELSEIF (day=2) OR (day=22) WriteF('The \dnd day of the month\n', day) ELSEIF (day=3) OR (day=23) WriteF('The \drd day of the month\n', day) ELSEIF ((4<=day) AND (day<=20)) OR ((24<=day) AND (day<=30)) WriteF('The \dth day of the month\n', day) ELSE WriteF('Error: invalid day=\d\n', day) ENDIF
The comma separating two ranges in the
CASE part has been replaced by an
OR of two comparison expressions, and the
TO range has been replaced by an
AND of two comparisons.
(It is worth noticing the careful bracketing of the resulting expressions.)
SELECT..OF block is much more readable than the equivalent
It is also a lot faster, mainly because none of the comparisons present in
IF block have to be done in the
Instead the value to be matched is used to immediately locate the correct
However, it's not all good news: the maxrange value directly affects the size of compiled executable, so it is recommended that
SELECT..OF blocks be used only with small maxrange values.
See the Reference Manual for more details.
Go to the Next or Previous section, the Detailed Contents, or the Amiga E Encyclopedia.