SELECT CASE/END SELECT block  

Purpose

Control program flow based on the value of an expression.

Syntax

SELECT CASE [AS] [LONG | CONST | CONST$ | CONST$$] expression

CASE [IS] testlist

  [statements]

[CASE [IS] testlist

  [statements]]

[CASE ELSE

  [statements]]

END SELECT

Remarks

testlist is one or more tests, separated by commas, to be performed on expressionexpression can be either string or numeric.

When a SELECT statement is encountered, expression is evaluated using the testlist in the first CASE clause.  If the evaluation is FALSE, the evaluation is repeated using the next testlist.  As soon as an evaluation is TRUE (non-zero), the statements following that CASE clause are executed, up to the next CASE clause.

Execution then passes to the statement following the END SELECT statement.  If none of the evaluations is TRUE, the statements following the optional CASE ELSE clause are executed.

The tests that may be performed by a CASE clause include: equality, inequality, greater than, less than, and range ("from-to") testing. The SELECT CASE block can do string or numeric tests, but these cannot be interchanged.

Examples of numeric CASE clause tests include:

SELECT CASE numeric_expression

  CASE > b         ' relational; is expression > b?

  CASE 14          ' equality (= is assumed); is expression equal to 14?

  CASE b TO 99     ' range; is expression between the value of the

                   ' variable b and 99 (inclusive)?

  CASE 14, b       ' two equality tests; is expression equal to

                   ' 14 or equal to b?

  CASE 25 TO 99,14 ' combination range and equality;  is expression

                   ' between 25 and 99  (inclusive) or equal to 14?

Examples of string CASE clause tests include:

SELECT CASE string_expression

  CASE > b$           ' relational; is expression > b$?

  CASE "X"            ' equality (= is assumed); is expression equal

                      ' to "X"?

  CASE "A" TO "C"     ' range; is expression between "A" and

                      ' "C"(inclusive)?

  CASE "Y", b$        ' two equality tests; is expression equal to

                      ' "Y" or equal to b$?

  CASE "A" TO "C","Q" ' combination range and equality; is expression

                      ' between "A" and "C"  (inclusive) or equal

                      ' to "Q"?

When a CASE clause contains multiple tests separated by commas, a logical OR is performed.  That is, if any one (or more) of the tests is TRUE, the entire clause is deemed to be TRUE.

Use EXIT SELECT to jump out of a SELECT block prematurely.

PowerBASIC now offers four optional modifiers to provide highly optimized code generation for specific circumstances.  By default, numeric expressions are evaluated either as floating-point values (to offer the widest range of compatibility for any possible circumstance) or as integer-class (for example, if PowerBASIC can establish that all case clauses are integer class values, etc).  Further, string expressions are evaluated dynamically to allow virtually any data.  However, if limits on the type and range of the data used for CASE comparison are restricted, performance can be dramatically enhanced with the LONG, CONST, CONST$, or CONST$$ clauses.

AS LONG

In this case, the controlling expression and the CASE expressions must evaluate in the range of a Long-integer.  Each of these expressions are calculated dynamically, so all of the normal operators are still available.  Performance is enhanced by the integral class of code generation, rather than floating-point.  For example, DWORD values are treated as Long-integer values, so &H0FFFFFFFF??? and -1& would be considered equal values.  This can help eliminate the need to use functions such as BITS when performing comparisons between signed and unsigned values. 

AS CONST

In this case, the controlling expression must evaluate in the range of a Long-integer.  However, each of the case values must be strictly specified by a numeric literal (or numeric equate) in the range of a Long-integer.  Multiple case values may be given (CASE 2,3,7), but operators and ranges of values are not allowed.  CASE ELSE is permitted.  Performance is enhanced by the internal creation of a vector jump table, one entry for each number from the smallest to the largest case value.

While this form of the structure offers the utmost performance possible, the execution speed must be carefully weighed against the increased program size, particularly when using sparse case values.  For example, with just two CASE values of 2 and 1000, the generated jump table would need 999 table entries (3996 bytes in size).  The largest allowed jump table for this form is approximately 3200 entries (12K bytes).  If exceeded, an Error 402 is generated ("Statement too long/complex").

AS CONST$

In this case, the controlling expression must evaluate to an ANSI string of length zero through 255 bytes.  However, each of the case values must be strictly specified by a string literal (a quoted ANSI string, or an ANSI string equate).  Multiple case values may be given (CASE "a","Bob",$value), but operators and ranges of values are not allowed.  Performance is enhanced by the internal creation of a vectored scan table, eight bytes for each case value specified.

AS CONST$$

In this case, the controlling expression must evaluate to a WIDE (Unicode) string of length zero through 127 characters.  However, each of the case values must be strictly specified by a string literal (a quoted wide string, or a wide string equate).  Multiple case values may be given (CASE "a"$$,"Bob"$$,$$value), but operators and ranges of values are not allowed.  Performance is enhanced by the internal creation of a vectored scan table, eight bytes for each case value specified.

See also

CHOOSE, CHOOSE&CHOOSE$EXIT SELECT, IF, IF block, IIF, IIF&, IIF$, MAX, MAX&, MAX$, MIN, MIN&, MIN$, ON GOTO, ON GOSUB, SWITCH, SWITCH&, SWITCH$

Example

DIM Dwrd AS DWORD

DIM Lint AS LONG

 

Dwrd = &H0FFFFFFFF???

Lint = -1&

 

SELECT CASE Lint

  CASE Dwrd

    a$ = "A Match!"

  CASE ELSE

    a$ = "*No Match"

END SELECT

 

SELECT CASE AS LONG Lint

  CASE Dwrd

    a$ = "*A Match!"

  CASE ELSE

    a$ = "No Match"

END SELECT

 

SELECT CASE AS CONST Dwrd

  CASE -1&

    a$ = "*A Match!"

  CASE 0

    a$ = "No Match"

END SELECT

Result

*No Match

*A Match!

*A Match!