5. Conditional Assembly
SMAL supports structured conditional assembly facilities which provide an assembly-time control structure comparable to the if-then-else statements of many high level languages. It is important to remember that these conditional constructs are not run-time control structures! Instead, they control which text will be processed by the assembler and which will be ignored.
<symbolic directive> ::= IF <expression> | ENDIF
The basic conditional directives IF and ENDIF are used to bracket a block of code that should be included in the assembly source if the expression on the IF statement evaluates to true (-1) and excluded from the assembly source of the expression evaluates to false (not -1).
The code between the IF and the ENDIF can be described as a conditional block. Conditional blocks may be nested arbitrarily. A "missing endif" error will be raised if an if block is not correctly terminated before the end of a macro, text insertion, or program.
In general, labels should not be used on the IF and ENDIF directives, but they are allowed. If labels are used, they will be treated as part of the immediately preceding sequence of lines. Thus, the label on an IF directive will be processed as if it was outside the conditional block and the label on an ENDIF directive will be processed as part of the body of the conditional block.
The following fragment of a SMAL32 assembler listing illustrates a valid use of the basic conditional assembly directives:
4 VERSION = 3 5 IF VERSION < 5 +000000: 00000000 6 LOWV: W 0 7 ENDIF
The above example might be used to declare and initialize the variable LOWV to zero, in the case where that variable is only used in versions of the program with VERSION less than 5. If the constant VERSION is set to any value greater than 5, LOWV will not be declared at all.
<symbolic directive> ::= ELSEIF <expression> | ELSEIn a simple conditional block, the body of the block is either assembled or ignored, depending on the value tested by the IF directive. More complex conditional blocks may be constructed by using the ELSEIF and ELSE directives to introduce alternative bodies of code.
The code following an ELSEIF directive will only be assembled if the corresponding boolean expression evaluated to true (-1). The lines within an elseif or else block will only be assembled if no previous if or elseif block within that conditional block was assembled. No more than one sub-block within a conditional block will ever be assembled. Only if none of the IF or ELSEIF conditions are true will the code after the ELSE directive be assembled. It is inappropriate to use labels on the ELSEIF or ELSE directives, but as is the case with IF and ENDIF, they are allowed.
The following fragment of a SMAL32 assembler listing illustrates a valid uses of these conditional assembly directives:
8 IF VERSION < 2 9 STR: ASCII "SIMPLE VERSION " 10 ELSEIF VERSION < 4 +000004: 4D 45 44 49 11 STR: ASCII "MEDIUM VERSION " 55 4D 20 20 56 45 52 53 49 4F 4E 20 12 ELSE ;VERSION >= 4 13 STR: ASCII "COMPLEX VERSION " 14 ENDIF +000014: 00 15 B 0
The above example might be used to create the part of the title string of a program which depends on the value of VERSION. The example shown was assembled with VERSION set to 3, so the midddle alternative was assembled. When the conditional block is long, and particularly when there are multiple ELSEIF conditions, it is useful to comment the ELSE directive to document the assertion which is known to be true for that clause, as illustrated here.
The following extended example is equivalent to the previous one, but it uses nested conditional blocks instead of an elseif directive:
16 STR1: IF VERSION < 2 17 ASCII "SIMPLE " 18 ELSE 19 IF VERSION < 4 +000015: 4D 45 44 49 20 ASCII "MEDIUM " 55 4D 20 20 21 ELSE 22 ASCII "COMPLEX " 23 ENDIF 24 ENDIF +00001D: 56 45 52 53 25 ASCII "VERSION " 49 4F 4E 20 +000025: 00 26 B 0