Loading...
Searching...
No Matches
For

Definition

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:

  • Simple iteration over explicit lists: #for T in [integer, real, complex]
  • Iteration over macro-expanded lists: #define NUMERICS [integer, real, complex] #for T in NUMERICS
  • Arbitrary nesting of #for blocks
  • Integration with the normal macro expansion engine
  • Deferred body collection until matching #endfor
  • Automatic cleanup of loop-local variables

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.

Examples

  1. Basic iteration:
    #for T in [integer, real, complex]
    type(T) :: value
    #endfor
    ! Expands to:
    type(integer) :: value
    type(real) :: value
    type(complex) :: value
  2. Using a macro list:
    #define NUMERICS [integer, real, complex]
    #for T in NUMERICS
    type(T) :: value
    #endfor
  3. Nested loops:
    #define CONCAT(a,b) a##b
    #for T in [integer, real]
    #for R in [32,64]
    type(CONCAT(T,R)) :: value
    #endfor
    #endfor
  4. Generic procedure generation:
    #define CONCAT(a,b) a##b
    #define NUMERICS [integer, real, complex]
    #for T in NUMERICS
    module procedure concat(add_,t)
    #endfor
  5. Cartesian product generation:
    #for T in [real, complex]
    #for K in [32, 64]
    type(T(K)) :: value
    #endfor
    #endfor
    ! Generates:
    ! type(real(32)) :: value
    ! type(real(64)) :: value
    ! type(complex(32)) :: value
    ! type(complex(64)) :: value

Loop variables behave exactly like temporary object-like macros and therefore participate in all normal macro expansion rules, including nested expansion and token pasting.

Note
When nested loops are active, generated lines are appended to the enclosing loop body rather than written immediately. This guarantees inside-out expansion semantics.

Methods

◆ add_to_loop()

subroutine, public add_to_loop ( character(*), intent(in) line)

Append a source line to the innermost active loop body.

Lines are stored verbatim without macro expansion. Expansion is deferred until the corresponding #endfor directive is processed.

Parameters
[in]lineSource line to store

Definition at line 383 of file loop.f90.

◆ handle_endfor()

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:

  • the loop variable macro is activated,
  • the stored body is macro-expanded,
  • generated lines are reprocessed by the normal preprocessing engine,
  • output is either emitted directly or forwarded to an enclosing loop.

When the outermost loop terminates, all temporary loop state is released automatically.

Parameters
[in]ctxCurrent parsing context
[in]ounitOutput unit
[in]ppreprocessor function pointer
[in,out]macrosActive macro table
[in]tokenDirective keyword (endfor)

Definition at line 289 of file loop.f90.

◆ handle_for()

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:

#for identifier in [value1, value2, ...]
#for identifier in macro_name

where MACRO_NAME expands to a bracketed list.

Note
#for and #endfor are fpx extensions and are not part of the ISO C preprocessor specification.
Parameters
[in]ctx
Current parsing context
[in,out]macrosActive macro table
[in]token
Directive keyword (for)

Definition at line 161 of file loop.f90.

◆ is_in_forloop()

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.

Returns
.true. when one or more loop contexts are active, .false. otherwise.

Definition at line 397 of file loop.f90.