Fortran Preprocessor (fpx) - compile-time loop expansion support.
This module implements the non-standard #for / #endfor directive pair used by fpx to generate repeated source code from a list of values.
Features:
During parsing, loop bodies are stored internally and emitted only when the matching #endfor is encountered. Each iteration temporarily defines the loop variable as a macro whose value is substituted into the collected body before output.
Loop variables behave exactly like temporary object-like macros and therefore participate in all normal macro expansion rules, including nested expansion and token pasting.
| subroutine, public add_to_loop | ( | character(*), intent(in) | line | ) |
| subroutine, public handle_endfor | ( | type(context), intent(inout) | ctx, |
| integer, intent(in) | ounit, | ||
| type(c_funptr), intent(in) | p, | ||
| type(macro), dimension(:), intent(in) | macros, | ||
| character(*), intent(in) | token ) |
Finalize a loop and emit all expanded iterations.
The collected loop body is expanded once for every value contained in the loop variable parameter list. Nested loops are handled recursively by forwarding generated lines to the enclosing loop body when present.
For each iteration value:
When the outermost loop terminates, all temporary loop state is released automatically.
| [in] | ctx | Current parsing context |
| [in] | ounit | Output unit |
| [in] | p | preprocessor function pointer |
| [in,out] | macros | Active macro table |
| [in] | token | Directive keyword (endfor) |
| subroutine, public handle_for | ( | type(context), intent(in) | ctx, |
| type(macro), dimension(:), intent(inout), allocatable | macros, | ||
| character(*), intent(in) | token ) |
Process a #for directive and initialize a new loop context.
The directive header is parsed immediately, but the loop body is not expanded at this stage. Instead, subsequent source lines are collected until the matching #endfor directive is encountered.
The loop variable behaves as a temporary object-like macro whose value changes for each iteration.
Supported syntax:
where MACRO_NAME expands to a bracketed list.
| [in] | ctx | Current parsing context |
| [in,out] | macros | Active macro table |
| [in] | token | Directive keyword (for) |
| logical function, public is_in_forloop |
Query whether parsing is currently inside a #for block. This routine is typically used by the main preprocessing engine to determine whether incoming source lines should be emitted directly or collected for later expansion.