Loading...
Searching...
No Matches
Macro

Definition

Macro management and expansion core of the fpx Fortran preprocessor

This module implements a complete, standards-inspired macro system supporting:

The design allows safe, repeated expansion while preventing infinite recursion. All operations are container-agnostic using allocatable dynamic arrays.

Examples

  1. Define and use simple macros:
    type(macro), allocatable :: macros(:)
    call add(macros, macro('PI', '3.1415926535'))
    call add(macros, macro('MSG(x)', 'print *, ″Hello ″, x'))
    print *, expand_all('area = PI * r**2', macros, 'circle.F90', 10, .false.)
    !> prints: area = 3.1415926535 * r**2
  2. Variadic macro with stringification and pasting:
    call add(macros, macro('DEBUG_PRINT(...)', 'print *, ″DEBUG[″, __FILE__, ″:″, __LINE__, ″]: ″, __VA_ARGS__'))
    print *, expand_all('DEBUG_PRINT(″value =″, x)', macros, ″test.f90″, 42, .false.)
    !> prints: print *, 'DEBUG[', 'test.F90', ':', 42, ']: ', 'value =', x
  3. Token pasting with ##:
    call add(macros, macro('MAKE_VAR(name,num)', 'var_name_##num'))
    print *, expand_all('real :: MAKE_VAR(temp,42)', macros, 'file.F90', 5, .false.)
    !> prints: real :: var_name_42

Data Types

type  macro
 Derived type representing a single preprocessor macro Extends string with macro-specific fields: replacement value, parameters, variadic flag, and cyclic self-reference detection. More...
 
interface  add
 Add one or more macros to a dynamic table. More...
 
interface  clear
 Remove all macros from a table. More...
 
interface  get
 Retrieve a macro by index. More...
 
interface  insert
 Insert more macro to a dynamic table. More...
 
interface  remove
 Remove a macro at given index. More...
 
interface  sizeof
 Return current number of stored macros. More...
 

Variables

◆ buffer_size

integer, parameter buffer_size = 256
private

Default buffer size.

Definition at line 65 of file macro.f90.

Methods

◆ expand_all()

character(:) function, allocatable, public expand_all ( character(*), intent(in) line,
type(macro), dimension(:), intent(in) macros,
character(*), intent(in) filepath,
integer, intent(in) iline,
logical, intent(out) stitch,
logical, intent(in) has_extra )

Fully expand a line including predefined macros (FILE, LINE, etc.) First performs normal macro expansion via expand_macros(), then substitutes standard predefined tokens with current file/line/date information.

Parameters
[in]lineInput source line
[in]macrosCurrent macro table
[in]filepathCurrent source file path
[in]ilineCurrent line number
[out]stitchSet to .true.true. if result ends with '&' (Fortran continuation)
[in]has_extraHas extra macros (non-standard) like FILENAME and TIMESTAMP
Returns
Expanded line with all macros and predefined tokens replaced

Remarks

Definition at line 194 of file macro.f90.

◆ expand_macros()

character(:) function, allocatable, public expand_macros ( character(*), intent(in) line,
type(macro), dimension(:), intent(in) macros,
logical, intent(out) stitch )

Core recursive macro expander (handles function-like, variadic, #, ##)

Performs actual macro replacement with full support for:

  • Function-like macros with argument collection
  • Stringification (#param)
  • Token pasting (##)
  • Variadic macros and __VA_ARGS__, __VA_OPT__
  • Recursion with cycle detection via digraph
  • Proper handling of nested parentheses and quoted strings
Parameters
[in]lineInput line
[in]macrosCurrent macro table
[out]stitch.true. if final line ends with '&'
Returns
Line with user-defined macros expanded (predefined tokens untouched)

Remarks

Definition at line 308 of file macro.f90.

◆ is_circular()

logical function is_circular ( type(macro), dimension(:), intent(in) macros,
integer, intent(in) idx )
private

Detect whether expanding macro at index idx would cause a cycle Builds a dependency graph from macro replacement texts and checks for circular paths. Used during expansion to avoid infinite recursion.

Remarks

Definition at line 614 of file macro.f90.

◆ is_defined()

logical function, public is_defined ( character(*), intent(in) name,
type(macro), dimension(:), intent(in) macros,
integer, intent(inout), optional idx )

Check if a macro with given name exists in table.

Parameters
[in]nameMacro name to test
[in]macrosCurrent macro table
[in,out]idxOptional: returns index (1-based) if found
Returns
.true. if macro is defined

Remarks

Definition at line 676 of file macro.f90.

◆ tostring()

character(:) function, allocatable tostring ( class(*), intent(in) any)
private

Generic conversion of polymorphic value to string Used internally during macro argument stringification and debugging. Supports integers, reals, logicals, characters, and complex.

Remarks

Definition at line 699 of file macro.f90.