Loading...
Searching...
No Matches
Define

Definition

Macro definition and removal directives for the fpx preprocessor.

This module implements the #define and #undef directives used to create, update, and remove preprocessor macros during source preprocessing.

Supported macro forms include:

  • Object-like macros: #define NAME value
  • Function-like macros: #define NAME(arg1,arg2,...) replacement
  • Variadic macros: #define LOG(level, ...) ...
  • Empty definitions: #define FEATURE
  • Macro redefinition: Existing definitions are replaced by the most recent one.

The parser correctly identifies matching parentheses in function-like macro signatures, allowing nested parentheses inside parameter lists. Whitespace surrounding parameters is ignored, and variadic arguments are detected automatically through the ... notation.

The module also implements #undef, allowing previously defined symbols to be removed from the active macro table. Symbols listed in globalundef are protected from redefinition and silently ignored.

All syntax errors are reported through the diagnostic framework, providing source locations and explanatory messages.

Note
Macro definitions are local to the current preprocessing context unless explicitly propagated by the caller.

Examples

  1. Object-like macros:
    #define PI 3.141592653589793
    #define DEBUG 1
    #define VERSION
  2. Empty definitions:
    #define USE_MPI
    #ifdef USE_MPI
    !...
    #endif
  3. Function-like macros:
    #define SQR(x) ((x)*(x))
    #define MIN(a,b) ((a)<(b)?(a):(b))
    #define CONCAT(a,b) a ## b
  4. Variadic macros:
    #define LOG(level, ...) &
    print *, , level, , __va_args__
  5. Removing a definition:
    #undef DEBUG
    #ifdef DEBUG
    ! This block is skipped
    #endif
  6. Redefinition:
    #define SIZE 128
    #define SIZE 256
    integer :: buf(SIZE) ! expands to 256
  7. Reserved names:
    #define defined(x) 1

produces a diagnostic because defined is reserved for conditional expressions.

See also
macro
global
context

Methods

◆ handle_define()

subroutine, public handle_define ( type(context), intent(in) ctx,
type(macro), dimension(:), intent(inout), allocatable macros,
character(*), intent(in) token )

Process a #define directive.

Parses the directive contained in the supplied context and updates the active macro table accordingly.

The routine automatically distinguishes between:

  • object-like macros,
  • function-like macros,
  • variadic macros using ...,
  • empty definitions.

Function-like signatures are parsed using matching-parenthesis tracking, ensuring that the closing parenthesis corresponding to the opening ( is located correctly even in the presence of nested parentheses.

Existing definitions are overwritten. Symbols listed in globalundef are ignored. Attempts to define the reserved identifier defined generate an error diagnostic.

Parameters
[in]ctxSource context containing the complete #define directive.
[in,out]macrosActive macro table updated in place.
[in]tokenDirective keyword, typically "define".

Definition at line 150 of file define.f90.

◆ handle_undef()

subroutine, public handle_undef ( type(context), intent(in) ctx,
type(macro), dimension(:), intent(inout), allocatable macros,
character(*), intent(in) token )

Process a #undef directive.

Removes the specified macro from the active macro table. If the requested symbol is not currently defined, a warning diagnostic is emitted.

Parameters
[in]ctxSource context containing the complete #undef directive.
[in,out]macrosActive macro table updated in place.
[in]tokenDirective keyword, typically "undef".

Definition at line 297 of file define.f90.