Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ preprocessor_directives(1) — ACMSxp 3.2A

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

stdl(1)

statement(1)

stdl_syntax(1)

acmsxp_introduction(1)

preprocessor directives(1)  —  Commands

Digital

NAME

Preprocessor Directives − supply and process replacement macro definitions before compilation
 

SYNOPSIS

 
#DEFINE
 
The format for a #DEFINE preprocessor directive is:
 
  #DEFINE <preprocessor-identifier>
 
        [<preprocessor-identifier-1>  ]
        [<decimal-literal>            ]
        [<integer-literal>            ]
        [                             ] . . . <eol>
        [<string-literal>             ]
        [<operator>                   ]
        [<punctuators>                ]
        [                             ]
 
#IF
 
The format for a #IF preprocessor directive is:
 
                  {DEFINED (<identifier>)  }
              #IF {<boolean-expression>    } <eol>
                  {                        }
 
                   [[ <preprocessor-identifier-1> ]             ]
                   [[ <decimal-literal>           ]             ]
                   [[ <integer-literal>           ]             ]
                   [[ <string-literal>            ] . . . <eol> ]
                   [[ <operator>                  ]             ]
                   [[ <punctuators>               ]             ]
                   [                                            ]
                   [#DEFINE                                     ]
                   [#IF                                         ]
                   [#INCLUDE                                    ]
                   [#UNDEF                                      ]
 
               [ #ELIF <boolean-expression> <eol>                ]
               [ [                                            ]  ]
               [ [[ <preprocessor-identifier-1>  ]            ]  ]
               [ [[ <decimal-literal>            ]            ]  ]
               [ [[ <integer-literal>            ]. . . <eol> ]  ]
               [ [[ <string-literal>             ]            ]  ]
               [ [[ <operator>                   ]            ]  ]
               [ [[ <punctuators>                ]            ]  ]
               [ [                                            ]  ]
               [ [#DEFINE                                     ]  ]
               [ [#IF                                         ]  ]
               [ [#INCLUDE                                    ]  ]
               [ [#UNDEF                                      ]  ]
               [                                                 ]
 
               [ #ELSE <boolean-expression> <eol>                ]
               [ [                                            ]  ]
               [ [[ <preprocessor-identifier-1>  ]            ]  ]
               [ [[ <decimal-literal>            ]            ]  ]
               [ [[ <integer-literal>            ]. . . <eol> ]  ]
               [ [[ <string-literal>             ]            ]  ]
               [ [[ <operator>                   ]            ]  ]
               [ [[ <punctuators>                ]            ]  ]
               [ [                                            ]  ]
               [ [#DEFINE                                     ]  ]
               [ [#IF                                         ]  ]
               [ [#INCLUDE                                    ]  ]
               [ [#UNDEF                                      ]  ]
               [                                                 ]
 
          #ENDIF <eol>
 
#IFDEF
 
The format for a #IFDEF preprocessor directive is:
 
          #IFDEF <preprocessor-identifier-1> <eol>
 
                   [[ <preprocessor-identifier-1> ]             ]
                   [[ <decimal-literal>           ]             ]
                   [[ <integer-literal>           ]             ]
                   [[ <string-literal>            ] . . . <eol> ]
                   [[ <operator>                  ]             ]
                   [[ <punctuators>               ]             ]
                   [                                            ]
                   [#DEFINE                                     ]
                   [#IF                                         ]
                   [#INCLUDE                                    ]
                   [#UNDEF                                      ]
 
                   [#ELIF <boolean-expression> <eol>                ]
                   [[                                            ]  ]
                   [[ [<preprocessor-identifier-1>  ]            ]  ]
                   [[ [<decimal-literal>            ]            ]  ]
                   [[ [<integer-literal>            ] . . . <eol>]  ]
                   [[ [<string-literal>             ]            ]  ]
                   [[ [<operator>                   ]            ]  ]
                   [[ [<punctuators>                ]            ]  ]
                   [[                                            ]  ]
                   [[ #DEFINE                                    ]  ]
                   [[ #IF                                        ]  ]
                   [[ #INCLUDE                                   ]  ]
                   [[ #UNDEF                                     ]  ]
                   [                                                ]
 
                   [#ELSE <boolean-expression> <eol>                ]
                   [[                                            ]  ]
                   [[ [<preprocessor-identifier-1>  ]            ]  ]
                   [[ [<decimal-literal>            ]            ]  ]
                   [[ [<integer-literal>            ] . . . <eol>]  ]
                   [[ [<string-literal>             ]            ]  ]
                   [[ [<operator>                   ]            ]  ]
                   [[ [<punctuators>                ]            ]  ]
                   [[                                            ]  ]
                   [[ #DEFINE                                    ]  ]
                   [[ #IF                                        ]  ]
                   [[ #INCLUDE                                   ]  ]
                   [[ #UNDEF                                     ]  ]
                   [                                                ]
 
              #ENDIF <eol>
 
#IFNDEF
 
The format for a #IFNDEF preprocessor directive is:
 
          #IFNDEF <preprocessor-identifier-1> <eol>
 
               [ [<preprocessor-identifier-1>  ]            ]
               [ [<decimal-literal>            ]            ]
               [ [<integer-literal>            ]            ]
               [ [<string-literal>             ] . . . <eol>]
               [ [<operator>                   ]            ]
               [ [<punctuators>                ]            ]
               [                                            ]
               [ #DEFINE                                    ]
               [ #IF                                        ]
               [ #INCLUDE                                   ]
               [ #UNDEF                                     ]
 
               [ #ELIF <boolean-expression> <eol>                ]
               [ [                                            ]  ]
               [ [[ <preprocessor-identifier-1>  ]            ]  ]
               [ [[ <decimal-literal>            ]            ]  ]
               [ [[ <integer-literal>            ]. . . <eol> ]  ]
               [ [[ <string-literal>             ]            ]  ]
               [ [[ <operator>                   ]            ]  ]
               [ [[ <punctuators>                ]            ]  ]
               [ [                                            ]  ]
               [ [#DEFINE                                     ]  ]
               [ [#IF                                         ]  ]
               [ [#INCLUDE                                    ]  ]
               [ [#UNDEF                                      ]  ]
               [                                                 ]
 
               [ #ELSE <boolean-expression> <eol>                ]
               [ [                                            ]  ]
               [ [[ <preprocessor-identifier-1>  ]            ]  ]
               [ [[ <decimal-literal>            ]            ]  ]
               [ [[ <integer-literal>            ]. . . <eol> ]  ]
               [ [[ <string-literal>             ]            ]  ]
               [ [[ <operator>                   ]            ]  ]
               [ [[ <punctuators>                ]            ]  ]
               [ [                                            ]  ]
               [ [#DEFINE                                     ]  ]
               [ [#IF                                         ]  ]
               [ [#INCLUDE                                    ]  ]
               [ [#UNDEF                                      ]  ]
               [                                                 ]
 
              #ENDIF <eol>
 
#INCLUDE
 
The format for a #INCLUDE preprocessor directive is:
 
              #INCLUDE <file-name> <eol>
              #CINCLUDE <file-name> <eol>
 
#UNDEF
 
The format for a #UNDEF preprocessor directive is:
 
              #UNDEF <preprocessor-identifier-1> <eol>
 

PARAMETERS

       •preprocessor-identifier
 
An unqualified internal identifier specifying a preprocessor macro that can be used in other preprocessor directives and STDL source lines. The identifier must follow the syntax described in the Identifiers section in the stdl_syntax man page. 
 
The preprocessor macro definition is valid for the rest of the source file unless removed by a #UNDEF preprocessor directive. If the preprocessor macro appears in another preprocessor directive or STDL source line, the compiler replaces the macro with the valid definition.
 
The preprocessor identifier is a superset of reserved words, predefined words, and user-defined words. During preprocessing, all reserved words, predefined words, and user-defined words are treated as preprocessor identifiers. For example, you can replace all occurrences of an STDL reserved word with another word during preprocessing. This is not recommended.

       •preprocessor-identifier-1
 
An unqualified internal identifier specifying a preprocessor macro that is defined in a preceding #DEFINE preprocessor directive. If there is no intervening #UNDEF preprocessor directive, the compiler replaces the macro with the definition. If there is an intervening #UNDEF directive, the identifier has no effect.

       •decimal-literal
 
Sequence of numeric characters from the STDL alphanumeric character set. See the Decimal Literal section in the stdl_syntax man page. 

       •integer-literal
 
Sequence of numeric characters from the STDL alphanumeric character set. See the Integer Literal section in the stdl_syntax man page. 

       •string-literal
 
A sequence of characters selected from one execution character set. See the String Literal section in the stdl_syntax man page. 

       •operator
 
A character or characters from the STDL alphanumeric character set specifying a relational, an arithmetic, or an assignment operation to be performed. See the Operators section in the stdl_syntax man page. 

       •punctuators
 
A character or characters from the STDL alphanumeric character set specifying a syntactic separation used in an STDL definition or specification. For example, a comma (,)  to separate arguments. See the Punctuators section in the stdl_syntax man page. 

       •eol
 
A carriage return-line feed pair signalling the end of the source line.

       •identifier
 
An internal unqualified identifier representing a preprocessor identifier. The identifier must follow the syntax described in the Identifiers section in the stdl_syntax man page.  See the description of the Boolean expression parameter for information on the processing of DEFINED. 

       •Boolean-expression
 
A condition that produces a truth value when evaluated; the truth value can be either true or false. Before the Boolean expression is evaluated, the compiler does the following:
 
1. Replaces any occurrence of DEFINED (identifier) as
   follows:
 
   o  If identifier is defined as a preprocessor macro, it
      is replaced by a Boolean term that evaluates to true.
 
   o  If identifier is not defined as a preprocessor macro,
      it is replaced by a Boolean term that evaluates to
      false.
 
2. Replaces with their definitions all preprocessor
   identifiers that are defined as preprocessor macros.
 
3. Except for AND, NOT, and OR, replaces all remaining
   preprocessor identifiers with Boolean terms that
   evaluate to false.
 
   A Boolean expression in a #IF, #IFDEF, or #IFNDEF
   preprocessing directive:
 
   o  Refers only to preprocessing identifiers and integer
      literals.
 
   o  Cannot contain a string literal.
 
See the Boolean Expressions section in the stdl_syntax man page. 

       •file-name
 
An operating system name specifying the external file containing STDL source lines that replace the #INCLUDE or #CINCLUDE directive for compilation. The file name must:
 
o  Contain between 1 and 255 characters
 
o  Contain only the following characters from the SIMPLE-
   LATIN character set:
 
   -  Letters (uppercase and lowercase characters are
      equivalent)
 
   -  Numbers
 
   -  Underscore (_) and hyphen (-)
 
   -  Period (.)
 
o  Begin with a letter
 
o  Not contain STDL reserved or predefined words
 
o  Be an unqualified file name (that is, no directory
   specification)
 
If you do not specify a file type, the compiler assumes a type of .stdl.
 

DESCRIPTION

 
Use preprocessor directives in STDL source files to supply and process replacement macro definitions before compilation, allowing source to be conditionally compiled. The preprocessing directives define and logically test preprocessor identifiers that can be nil or STDL source language elements that replace the identifiers.
 
The preprocessing directives are:
 
o  #DEFINE
 
   Specifies a preprocessor identifier and a preprocessor
   replacement macro statement to be associated with that
   identifier.
 
o  #IF
 
   Tests an identifier to allow conditional inclusion
   of STDL source statements in definitions and
   specifications.
 
o  #IFDEF
 
   Conditionally includes source statements based on
   whether a preprocessor macro is defined.
 
o  #IFNDEF
 
   Conditionally includes source statements based on
   whether a preprocessor macro is not defined.
 
o  #INCLUDE
 
   Calls into a file the contents of an external file,
   allowing an STDL definition or specification to be
   shared in multiple places.
 
o  #UNDEF
 
   Removes the preprocessor macro definition in effect from
   a preceding #DEFINE directive.
 
Preprocessing syntax is separate from STDL syntax and is processed before any STDL syntax. Write preprocessor directives using the STDL alphanumeric source character set. Lowercase Latin letters are equivalent to uppercase Latin letters in the directives.
 
During preprocessing, the STDL compiler examines each source file line-by-line. (Contrast this with STDL syntax translation, which is done without regard to lines.) A source line that has the preprocessor directive flag character (#)  as its first nonwhite space character is a preprocessing directive. Because preprocessor directives are lexically identified by the (#)  flag, they are not STDL reserved words.
 
Preprocessing directive lines can contain comments. The #DEFINE directive is the only preprocessing directive on whose line STDL syntax can appear.
 
Preprocessing consists of the following semantic actions:
 
o  The compiler removes all comments and replaces them with
   white space.
 
o  The compiler applies preprocessing syntax to the source
   file. Line demarcation significant as is indicated
   by the end-of-line  character shown in the format
   descriptions.
 
o  The compiler interprets any preprocessor directive
   according to the rules for that particular directive.
 
o  For the source lines included in the translation, the
   compiler scans for preprocessor identifiers. If an
   identifier is defined and not preceded by the #UNDEF
   directive, the compiler substitutes the macro definition
   for the identifier.
 
o  The compiler scans any substituted macro definitions
   for preprocessor identifiers. If an identifier different
   from the previously substituted identifier is found,
   the compiler substitutes the macro definition for the
   identifier. If any preprocessor identifier is identical
   to a previously replaced identifier in the substituted
   definitions, no replacement is done. Macro replacement
   is recursive unless the preprocessor identifier is
   identical.
 
o  When the compiler skips text, it tracks preprocessor
   directives only to find a matching #ENDIF or #ELSE.
 
o  If a source file is included by the #INCLUDE
   preprocessor directive, the compiler applies all the
   preprocessing actions.
 
Unless the syntax descriptions of the preprocessor directives state so, preprocessor lines are not subject to macro substitution.
 

#DEFINE

 
Use #DEFINE preprocessor directives to conditionally insert multiple lines of code used at various places in the source file. For the remainder of the source file, the preprocessing identifier specified in a #DEFINE directive is valid as a preprocessor macro. The compiler rules for the directive are:
 
1. The compiler saves the definition associated with the
   preprocessor macro.
 
   To remove the definition in effect, use the #UNDEF
   directive.
 
2. In any source after the #DEFINE directive, the compiler
   replaces any occurrence of the preprocessor identifier
   with the macro definition.
 
   If the definition is nil, the compiler effectively
   removes occurrences of the preprocessing identifier.
 
3. The compiler removes the #DEFINE before translation.
 
   The scope of the macro definition is independent of any
   other STDL syntax scope.
 
The preprocessor identifier in the #DEFINE directive is not subject to macro replacement. If the preprocessor identifier is previously defined as a preprocessor macro, the current definition must equal the previous definition. To change a definition, use the #UNDEF preprocessor directive to invalidate the current definition and a #DEFINE preprocessor directive to supply a new definition.
 

#IF

 
Within a #IF, #IFDEF, or #IFNDEF preprocessor directive, at most one substitution is included in the source to be compiled.
 
For a #IF, the substitution is included only if the test evaluates to true.
 
The #IF must be terminated by a #ENDIF directive. Statements can be nested up to six levels. The compiler removes the #IF directive before translation.
 

#IFDEF

 
Within a #IF, #IFDEF, or #IFNDEF preprocessor directive, at most one substitution is included in the source to be compiled.
 
For a #IFDEF, the substitution is included only if the preprocessor identifier is defined as a preprocessor macro.
 
The #IFDEF must be terminated by a #ENDIF directive. Statements can be nested up to six levels.
 
A preprocessor identifier in a #IFDEF preprocessor directive is not subject to macro substitution.
 
The compiler removes the #IFDEF directive before translation.
 

#IFNDEF

 
Within a #IF, #IFDEF, or #IFNDEF preprocessor directive, at most one substitution is included in the source to be compiled.
 
For a #IFNDEF, the substitution is included only if the preprocessor identifier is NOT defined as a preprocessor macro.
 
The #IFNDEF must be terminated by a #ENDIF directive. Statements can be nested up to six levels.
 
A preprocessor identifier in a #IFNDEF preprocessor directive is not subject to macro substitution.
 
The compiler removes the #IFNDEF directive before translation.
 

#ELIF

 
For a #ELIF preprocessor directive, the substitution is included only if no previous substitution within the #IF, #IFDEF, or #IFNDEF is included and the test evaluates to true.
 

#ELSE

 
For a #ELSE preprocessor directive, the substitution is included only if no previous substitution within the #IF, #IFDEF, or #IFNDEF is included.
 

#INCLUDE and #CINCLUDE

 
The #INCLUDE directive brings into a source file all source lines from an external file. The source lines from the external file lexically unconditionally replace the source line that contains the #INCLUDE directive. The #CINCLUDE directive is a conditional #INCLUDE; it does not include source lines if the file has already been included.
 
The compiler preprocesses an input source file. Sometimes the input source file can be a single definition, for example, a data type definition. Usually, however, the input source file must include more than one definition or specification. For example, an input source file for a processing group specification also requires the data type definitions for the workspace arguments used in the processing procedures. In other cases, you may find it convenient to include multiple definitions and specifications in the input source file, even when you can compile them as separate input source files.
 
Often you need to use a definition or specification in more than one source file. Write the definition or specification once, and use the #INCLUDE or #CINCLUDE preprocessor to include it in multiple input source files.
 
A task source file can contain task definitions for only one task group.
 
Do not use #INCLUDE or #CINCLUDE in include files that contain lines of source code that you plan to debug. Instead, include the definitions directly in the input source file that you compile. Source lines contained within the included file are not visible to the ACMSxp debugger.
 
When you invoke the compiler, have the necessary include files in the directory containing the top-level input source file. However, you can specify a search path on the command so that, if the files are not in that directory, the compiler looks for them in the directories specified in the search path. The compiler stores output files in the current working directory, but you can specify a different output directory using an option flag.
 
A recursive reference to the same external source file generates an error and stops the compilation.
 

#UNDEF

 
The #UNDEF preprocessor directive removes the definition of a specified preprocessor identifier as a preprocessor macro for the rest of the source file. If another #DEFINE preprocessor directive is used, the definition is in effect again.
 
Use a #UNDEF statement to override a macro definition at various places in the source file or to change a macro definition. If you use the #UNDEF immediately before a #DEFINE preprocessor directive, you can redefine the preprocessor macro.
 
A preprocessor identifier is not subject to macro replacement in a #UNDEF preprocessor directive.
 

EXCEPTIONS

 
Preprocessor directives do not generate exceptions or error messages.
 

EXAMPLES

 
The following example shows the use of some preprocessor directives.
 
1.   #DEFINE a b
 
     TASK a IN tskgrp
 
     The compiler substitutes for the macro a to give the
     following line for translation:
 
     TASK b IN tskgrp
 
2.   #DEFINE a b
 
     #DEFINE b a
     a = 1;
 
     The compiler substitutes for the macro a. Because the
     macro definition is also subject to substitution, the
     compiler replaces b with a. The recursion stops, because
     the replacement a in the second line is identical to a
     previously replace preprocessor identifier. The result
     gives the following line for translation:
 
     a = 1;
 
3.   #DEFINE a b
 
     #DEFINE b c
     a = 1;
 
     The compiler substitutes b for the macro a and c for b
     to give the following line for translation:
 
     c = 1;
 
4.   #DEFINE a b
 
     #UNDEFINE a
     #DEFINE a c
     c = 1;
 
     The compiler substitutes c for the macro a to give the
     following line for translation:
 
     c = 1;
 
     The intervening #UNDEFINE is necessary, because the
     compiler prevents you from redefining a macro.
 
5.   #DEFINE a b
 
     #DEFINE c a
     a = 1;
     c = 1;
 
     The compiler yields the following two assignment
     statements for translation:
 
     b = 1;
     b = 1;
 
     In the first line the compiler replaces the macro a
     with b and in the second line replaces c with b (the
     definition for the preprocessor identifier c is itself
     subject to substitution).
 
6.   #DEFINE a a
 
     a = 1;
 
     The compiler replaces the macro a with its definition
     a. Because the replacement equals a previously replaced
     preprocessor identifier, the recursion stops.
 
7.   #IF DEFINED (system1)
 
     #DEFINE file "sys1"
     #ELSE
     #DEFINE file "default"
     #ENDIF
     #INCLUDE file
 
     This example shows a #IF preprocessor directive
     determining the name of the file to be included by
     the #INCLUDE preprocessor directive. If the identifier
     system1 is defined as a preprocessor macro, the term
     evaluates as true and the macro file has the definition
     sys1. If system1 is not defined as a preprocessor macro,
     the term evaluates to false, and the definition for file
     is default. The #INCLUDE preprocessor directive can load
     either the sys1.stdl file or the default.stdl file.
 

RELATED INFORMATION

Commands: stdl(1)
 
Syntax: statement(1), stdl_syntax(1)

acmsxp_introduction(1)

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026