Conditional compilation

Conditional compilation is the compiler's ability to decide atcompile time whether or not portions of your source program are to be compiled.  Conditionalcompilation can test a version tag which you define.

Version tags

You can use conditional compilation to create different versionsof a program that reside in the same source.  The version that is compiled iscontrolled externally, by version tags.  

Version tags are identifiers you define in one of the followingways:

Predefined compiler version tags

The compile time IF statement

Conditional compilation is implemented by the compile time IFstatement. Unlike the Modula-2 and Ada95 IF statement, the compile time IF operatesat the token level.  A compile time IF can start between any two tokens in aprogram, and can control the compilation of any string of tokens.

The format of the compile time IF statement is:

%IF CompileTimeExpression %THEN
   TokenStream
{%ELSIF CompileTimeExpression %THEN
   TokenStream}
[%ELSE
   TokenStream]
%END

CompileTimeExpression is an expression formed by version tags, parentheses and the operators %AND, %OR, and %NOT.  The precedence ofthe operators is as follows, from highest to lowest:

%NOT

%AND

%OR

TokenStream is any stream of Modula-2 or Ada95 tokens.

Compile time IF's can be nested up to 16 levels.  They canbe used anywhere in a source file.

The CompileTimeExpressions are evaluated as boolean expressions. The value of a version tag is TRUE if the version tag is defined and FALSEif it is not. The CompileTimeExpressions are evaluated in order until one is TRUE. The TokenStream following the TRUE expression is compiled.  If none ofthe expressions is TRUE, and there is an ELSE, the TokenStream following the ELSEis compiled.  All other TokenStreams are skipped by the compiler.

Examples:

A common use of conditional compilation is to add debug codethat aids in debugging a program, but is not compiled in the final version of theprogram.  For example:

%IF DEBUG %THEN
   WriteString('After ');
   WriteCard(i, 0);
   WriteString(' iterations: X = ');
   WriteReal(X, 10);
   WriteString(' Y = ');
   WriteReal(Y, 10);
%END

Compile time IF's are not restricted to lists of statements,as in the above example.  You can also use them to conditionalize data structures:

TYPE SymbolRecord =
   RECORD
   DataType    : TypePointer;
   Address     : %IF ThirtyTwoBit %THEN
                      CARDINAL;
                 %ELSE
                      LONGCARD;
                 %END
  NextSym      : SymbolPointer;
  END;

You can use the operators %AND, %OR, %NOT and parentheses totest more complex conditions. For Example:

%IF (Win32 %OR OS2) %AND %NOT Network %THEN

...

%END

Alternate conditional compilation syntax in Modula-2

The compiler also accepts the conditional compilation syntaxused by the Macintosh p1 compiler. The syntax is nearly identical except that itis contained in directives.

<*IF (Win32 OR OS2) AND NOT Network THEN *>

...

<*END*>

To define a new version tag use the following.

<*DEFINE(TagName, value)*>

where value can be FALSE or TRUE

To change the value of a previously defined version tag use

<*ASSIGN(TagName, value)*>

where value can be FALSE or TRUE

Relationship between DEFINE, ASSIGN and /VERSION, /NOVERSION,/VALIDVERSION

<*DEFINE(TagName, TRUE)*>

is identical to

<*/VERSION:TagName/VALIDVERSION:TagName*>

<*DEFINE(TagName, FALSE)*>

is identical to

<*/VALIDVERSION:TagName*>

<*ASSIGN(TagName, TRUE)*>

is identical to

<*/VERSION:TagName*>

<*ASSIGN(TagName, FALSE)*>

is identical to

<*/NOVERSION:TagName*>