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:

  • Object-like and function-like macros
  • Variadic macros (... and __VA_ARGS__)
  • Parameter stringification (#param) and token pasting (##)
  • Built-in predefined macros: __FILE__, __FILENAME__, __LINE__, __DATE__, __TIME__, __TIMESTAMP__
  • Recursive expansion with circular dependency detection via digraph analysis
  • Dynamic macro table of macro objects with efficient addition, lookup, removal
  • Full support for nested macro calls and proper argument handling

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(context('area = PI * r**2', 10, './circle.F90', 'circle'), macros, stitch, .false., .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(context('DEBUG_PRINT(″value =″, x)', 42, 'test.F90', 'text'), macros, stitch, .false., 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(context('real :: MAKE_VAR(temp,42)', 5, 'file.F90', 'file'), macros, stitch, .false., .false.)
    !> prints: real :: var_name_42

Data Types

interface  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 67 of file macro.f90.

Methods

◆ expand_all()

character(:) function, allocatable, public expand_all ( type(context), intent(in) ctx,
type(macro), dimension(:), intent(in) macros,
logical, intent(out) stitch,
logical, intent(in) has_extra,
logical, intent(in) implicit_conti )

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]ctxContext
[in]macrosCurrent macro table
[out]stitchSet to .true.true. if result ends with '&' (Fortran continuation)
[in]has_extraHas extra macros (non-standard) like FILENAME and TIMESTAMP
[in]implicit_contiIf .true., implicit continuation is permitted
Returns
Expanded line with all macros and predefined tokens replaced

Remarks

Definition at line 195 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,
logical, intent(in) implicit_conti,
type(context), intent(in) ctx )

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]lineLine to be expanded
[in]macrosCurrent macro table
[out]stitch.true. if final line ends with '&'
[in]implicit_contiIf .true., implicit continuation is permitted
[in]ctxContext
Returns
Line with user-defined macros expanded (predefined tokens untouched)

Remarks

Definition at line 299 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 624 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 647 of file macro.f90.