Conditional support for the fpx preprocessor.
This module implements the complete conditional compilation machinery used by fpx. It provides functionality equivalent to the traditional C preprocessor directives while also introducing a few convenience extensions.
Supported directives include:
Nested conditional blocks are supported up to MAX_COND_DEPTH levels.
The implementation follows the standard "first-match" semantics: once a branch of a conditional group evaluates to true, all remaining #elif, #elifdef, #elifndef, and #else directives belonging to the same group are ignored.
Internally, the module maintains a stack of conditional states (cond_stack) together with the current nesting depth (cond_depth). The helper function is_active() determines whether the current source line belongs to an active branch and therefore should be processed by the remainder of the preprocessor.
Each active conditional nesting level stores two pieces of state:
This design allows efficient evaluation of deeply nested conditionals while preserving correct first-match semantics.
Include guard pattern:
Feature selection using expression evaluation:
Platform-dependent compilation:
Conditional compilation using macro existence:
Using the fpx extension #elifdef:
Nested conditionals:
Data Types | |
| type | cond_state |
| State associated with a single conditional nesting level. More... | |
| integer, public cond_depth = 0 |
Current nesting depth of conditional directives (0 = outside any if).
Definition at line 176 of file conditional.f90.
| type(cond_state), dimension(max_cond_depth), public cond_stack |
Global stack of conditional states (depth-limited).
Definition at line 172 of file conditional.f90.
| subroutine, public handle_elif | ( | type(context), intent(in) | ctx, |
| type(macro), dimension(:), intent(inout), allocatable | macros, | ||
| character(*), intent(in) | token ) |
Process elif - alternative branch after if/elif Only activates if no previous branch in the group was taken.
| [in] | ctx | Context source line containing the directive |
| [in,out] | macros | Current macro table |
| [in] | token | Usually 'elif' |
Definition at line 310 of file conditional.f90.
| subroutine, public handle_elifdef | ( | type(context), intent(in) | ctx, |
| type(macro), dimension(:), intent(in) | macros, | ||
| character(*), intent(in) | token ) |
Process elifdef - test if a macro is defined.
| [in] | ctx | Context source line containing the directive |
| [in] | macros | Current macro table |
| [in] | token | Usually 'elifdef' |
Definition at line 346 of file conditional.f90.
| subroutine, public handle_elifndef | ( | type(context), intent(in) | ctx, |
| type(macro), dimension(:), intent(in) | macros, | ||
| character(*), intent(in) | token ) |
Process elifndef - test if a macro is not defined.
| [in] | ctx | Context source line containing the directive |
| [in] | macros | Current macro table |
| [in] | token | Usually 'elifndef' |
Definition at line 382 of file conditional.f90.
| subroutine, public handle_else | ( | type(context), intent(in) | ctx | ) |
Process else - final fallback branch Activates only if no previous if/elif branch was true.
| [in] | ctx | Context (for error messages) |
Definition at line 417 of file conditional.f90.
| subroutine, public handle_endif | ( | type(context), intent(in) | ctx | ) |
Process endif - end of conditional block Pops the top state from the stack. Reports error on unmatched endif.
| [in] | ctx | Context (for error messages) |
Definition at line 445 of file conditional.f90.
| subroutine, public handle_if | ( | type(context), intent(in) | ctx, |
| type(macro), dimension(:), intent(inout), allocatable | macros, | ||
| character(*), intent(in) | token ) |
Process a if directive with constant expression evaluation Evaluates the expression after if using evaluate_expression() and pushes a new state onto the conditional stack.
| [in] | ctx | Context source line containing the directive |
| [in,out] | macros | Current macro table |
| [in] | token | Usually 'if' |
Definition at line 213 of file conditional.f90.
| subroutine, public handle_ifdef | ( | type(context), intent(in) | ctx, |
| type(macro), dimension(:), intent(in) | macros, | ||
| character(*), intent(in) | token ) |
Process ifdef - test if a macro is defined.
| [in] | ctx | Context source line containing the directive |
| [in] | macros | Current macro table |
| [in] | token | Usually 'ifdef' |
Definition at line 245 of file conditional.f90.
| subroutine, public handle_ifndef | ( | type(context), intent(in) | ctx, |
| type(macro), dimension(:), intent(in) | macros, | ||
| character(*), intent(in) | token ) |
Process ifndef - test if a macro is NOT defined.
| [in] | ctx | Context source line containing the directive |
| [in] | macros | Current macro table |
| [in] | token | Usually 'ifndef' |
Definition at line 277 of file conditional.f90.
| logical function, public is_active |
Determine whether the current source position is active.
Traverses all enclosing conditional levels and returns .true. only if every surrounding conditional branch is active.
This routine is used throughout the preprocessing pipeline to decide whether directives should be executed and whether ordinary source lines should be emitted.
Definition at line 194 of file conditional.f90.