macros

High-level macro utilities.

class macro_polo.macros.DecoratorMacroInvokerMacro

A macro that processes decorator-style macro invocations.

The syntax for invoking a decorator-style macro is @![name(parameters)] or @![name] (equivalent to @![name()]).

Decorator-style macro invocations must immediately precede a “block”, defined as either a single newline-terminated line, or a line followed by an indented block.

When invoked, the registered macro is called with two arguments:

  1. parameters (as a token sequence)

  2. the block immediately following the invocation (as a token sequence).

When multiple decorator-style macros are stacked, they are invoked from bottom to top.

Macros are defined by macros (which can be updated after this class is instantiated).

__init__(macros=<factory>)
Parameters:

macros (Mapping[str, ParameterizedMacro])

Return type:

None

macros: Mapping[str, ParameterizedMacro]

A mapping of names to decorator macros.

When a decorator macro is invoked, its name is looked up here.

This mapping may be shared with other macros, such as a ImporterMacro.

class macro_polo.macros.FunctionMacroInvokerMacro

A macro that processes function-like macro invocations.

The syntax for invoking a function-style macro is:

macro_name!(input tokens)

or

macro_name![input tokens]

or

macro_name!{input tokens}

or

macro_name!:
    input
    tokens

Important

Due to the way Python’s tokenizer works, indentation and newlines are only preserved by the last (block) style.

When invoked, the registered macro is called with a single argument, the token sequence passed as input.

Macros are defined by macros (which can be updated after this class is instantiated).

__init__(macros=<factory>)
Parameters:

macros (Mapping[str, Macro])

Return type:

None

macros: Mapping[str, Macro]

A mapping of names to function macros.

When a function macro is invoked, its name is looked up here.

This mapping may be shared with other macros, such as a ImporterMacro.

class macro_polo.macros.ImporterMacro

Imports macros from other modules.

This macro expects its parameters to be in one of two forms: 1. module_name 2. macro_name1, macro_name2, ... from module_name

In the first case all macros from the target module will be imported.

Imported macros are added to function_macros, module_macros, and decorator_macros as appropriate.

__init__(function_macros=<factory>, module_macros=<factory>, decorator_macros=<factory>)
Parameters:
Return type:

None

decorator_macros: dict[str, ParameterizedMacro]

Imported decorator macros will be added to this dict.

It may be shared with other macros, such as a DecoratorMacroInvokerMacro.

function_macros: dict[str, Macro]

Imported function macros will be added to this dict.

It may be shared with other macros, such as a FunctionMacroInvokerMacro.

module_macros: dict[str, ParameterizedMacro]

Imported module macros will be added to this dict.

It may be shared with other macros, such as a ModuleMacroInvokerMacro.

class macro_polo.macros.LoopingMacro

A super-macro that repeatedely applies its inner macros until none match.

__init__()
protocol macro_polo.macros.Macro

Transforms a token sequence.

Classes that implement this protocol must have the following methods / attributes:

abstractmethod __call__(tokens)

Transform a token sequence.

This method should return a new token sequence, or None if the input sequence fails to match or should be left unchanged.

Parameters:

tokens (Sequence[Token])

Return type:

Sequence[Token] | None

class macro_polo.macros.MacroRulesParserMacro

A macro that parses macro_rules macro definitions.

Parsed macros are added to macros.

__init__(macros=<factory>)
Parameters:

macros (dict[str, Macro])

Return type:

None

macros: dict[str, Macro]

Parsed macro_rules macros will be added to this dict.

It may be shared with other macros, such as a FunctionMacroInvokerMacro.

class macro_polo.macros.ModuleMacroInvokerMacro

A macro that processes module-level macro invocations.

The syntax for invoking a module-level macro is ![name(parameters)] or ![name] (equivalent to ![name()]).

Module-level macro invocations must come before all other code (with the exception of a docstring), and must each appear on their own line.

When invoked, the registered macro is called with two arguments:

  1. parameters (as a token sequence)

  2. the remainder of the module starting from the line immediately following the

    invocation (as a token sequence).

Macros are defined by macros (which can be updated after this class is instantiated).

__init__(macros=<factory>)
Parameters:

macros (Mapping[str, ParameterizedMacro])

Return type:

None

macros: Mapping[str, ParameterizedMacro]

A mapping of names to module macros.

When a module macro is invoked, its name is looked up here.

This mapping may be shared with other macros, such as a ImporterMacro.

class macro_polo.macros.MultiMacro

A super-macro that applies each of its inner macros in sequence.

__init__()
protocol macro_polo.macros.ParameterizedMacro

Macro that takes additional parameters.

Classes that implement this protocol must have the following methods / attributes:

abstractmethod __call__(parameters, tokens)

Transform a token sequence.

This method should return a new token sequence, or None if the input sequence fails to match.

Parameters:
Return type:

Sequence[Token] | None

protocol macro_polo.macros.PartialMatchMacro

Transforms the beginning of a token sequence.

Classes that implement this protocol must have the following methods / attributes:

abstractmethod __call__(tokens)

Transform the beginning of a token sequence.

This method should return a tuple of (token sequence, number of tokens matched).

Parameters:

tokens (Sequence[Token])

Return type:

tuple[Sequence[Token], int]

class macro_polo.macros.ScanningMacro

A super-macro that scans input and applies its inner macros as they match.

This macro will only perform a single pass on the input. It can be combined with LoopingMacro to recursively expand macros.

__init__()