Skip to content

Rough draft of Section 3.5 conditionals: #if, #elif, etc. #61

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
139 changes: 134 additions & 5 deletions drafts/25-xxx-specifications.txt
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@ syntax below, we denote these as just "token-list" or
"replacement-list".


di00. The directives listed in di01-di08 are only recognized as such
if the token immediately following the '#' introducing a
directive line exactly matches one of the standard directive
names ('define', 'if', 'pragma', etc.).

di01. The '#define' object-like macro directive

di02. The '#define' function-like macro directive
Expand All @@ -232,7 +237,7 @@ di03. The '#undef' directive
di04. The '#include' directive

di05. The '#if', '#ifdef', '#ifndef', '#elif', '#elifdef',
'#elifndef', '#else', '#endif' directives
'#elifndef', '#else', '#endif' conditional directives

di06. The '#error' and '#warning' directives

Expand Down Expand Up @@ -316,7 +321,7 @@ df04. The identifier-list is a comma-separated list of ID tokens.
df06. No identifier may appear more than once in the identifier-list.

df08. The identifier names in the identifier-list define macro "parameters" that affect
macro expansion of the replacement list. (See the section "Macro recognition and
macro expansion of the replacement list. (See the section "Macro recognition and
expansion" for the semantics of function-like macro expansion.)

df10. The replacement-list may be the empty sequence of tokens.
Expand Down Expand Up @@ -413,22 +418,146 @@ in28. Unlike INCLUDE lines (see the section on "INCLUDE lines"),
the #include directive is not prohibited from including the
same source file at a deeper level of nesting.


3.5 The '#if', '#ifdef', '#ifndef', '#elif', '#elifdef',
'#elifndef', '#else', '#endif' directives
'#elifndef', '#else', '#endif' conditional directives
---------------------------------------------------------

Example syntax:
Example syntax (extra spacing for illustration purposes only):
General form:
<if-head> #endif EOL
<if-head> <if-elif-list> #endif EOL
<if-head> <if-elif-list> <if-else> #endif EOL

Where:
<if-head> is one of:
#if token-list EOL <group>
#ifdef ID EOL <group>
#ifndef ID EOL <group>

<if-elif-list> is zero or more of:
<if-elif> <group>

<if-elif> is one of:
#elif token-list EOL <group>
#elifdef ID EOL <group>
#elifndef ID EOL <group>

<if-else> is one of:
#else EOL <group>

<group> is zero or more of:
directive lines
Fortran comment lines
Fortran source lines


3.5.1 Static semantics specifications
--------------------------------------
-------------------------------------

if05. A #if, #ifdef, or #ifndef directive signals the start of a list
of conditional directives.

if15. The list of #elif, #elifdef, and #elifndef directives, and the
#else directive (if present) are part of the same list of
directives introduced by the #if directive.

if20. The chain of conditional directives ends with the #endif
directive.

if25. Within a conditional directive list, a #if, #ifdef, or #endif
directive introduces a new list of conditional directives, at a new
nesting level, within the enclosing conditional directive list.

if30. The conditional directive lists must properly nest.



3.5.2 Evaluation semantics specifications
-----------------------------------------


ix05. The #ifdef and #ifndef directives are evaluated as if they had been
written "#if defined(ID)" and "#if !defined(ID)" respectively.
(For brevity, the descriptions of #ifdef and #ifndef directives
below are omitted, and assume this transformation.)

ix10. The #elifdef and #elifndef directives are evaluated as if they had
been written "#elif defined(ID)" and "#elif !defined(ID)"
respectively.

ix12. In the descriptions below, <group> constructs may be "skipped".
When skipped,
- Conditional directives within the <group> are recognized only
to maintain proper nesting of conditional directives.
- No nested directives in the <group> are processed.
- No macro expansion takes place in directive lines, Fortran
comment lines or source lines in the <group>.
- No skipped lines of any kind in the <group> are made available
subsequent processing by the processor.

ix14. In the descriptions below, <group> constructs that are not
skipped participate in further preprocessing and processing.
When participating

- Macros are expanded in Fortran comment lines and source
lines.
- Nested directives in the <group> are processed.
- The resulting Fortran comment lines and source lines
are made available for subsequent processing by the
processor.

ix15. Before evaluating the token-lists in the <if-head> and <if-elif>
constructs, macros in the token-lists are processed as described
in the section "Macro recognition and expansion".

ix20. After expansion, the resulting token list in <if-head> and <if-elif>
constructs must be able to be parsed as a valid integer expression as
described in the section "Expressions allowed in #if and #elif
directives" static semantics. This expression is called the "controlling
expression" for the directive.

ix25. The values of controlling expressions in <if-head> and <if-elif>
constructs are evaluated according to the evaluation semantics
described in the section "Expressions allowed in #if and #elif
directives".

ix30. If the controlling expression in an <if-head> evaluates to a
nonzero value, then the <group> contained within that <if-head>
construct participates in further preprocessing, as describe
above. Subsequent <if-elif> and <if-else> constructs at the same
level of nesting are skipped.

ix45. If the controlling expression in an <if-head> construct
evaluates to a zero value, then the <group> contained within
that <if-head> construct is skipped. Preprocessing continues
with any <if-elif> constructs at the same level of nesting, as
described below.

ix50. When the controlling expression in an <if-head> construct
evaluates to zero, the controlling expressions in each <if-elif>
construct at the same nesting level are evaluated in turn. Those
<group>s whose controlling expression evaluates to zero are
skipped.

ix55. When the controlling expression in an <if-elif> construct
evaluates to a nonzero value, the <group> contained within that
<if-elif> construct continues to participate in preprocessing.
Subsequent <if-elif> constructs and any remaining <if-else>
constructs at the same nesting level are skipped.

ix60. When all controlling expressions in the <if-head> construct and
<if-elif> constructs evaluate to a zero value and an <if-else>
construct is present at the same nesting level, the <group>
contained in the <if-else> construct continues to participate in
preprocessing.

ix65. When all controlling expressions in the <if-head> construct and
all <if-elif> constructs evaluate to a zero value and no
<if-else> construct is present at the same nesting level, then
all <group>s in these constructs are skipped.


3.6 The '#error' and '#warning' directives
------------------------------------------

Expand Down