Skip to content

math_spec.expansion

Named sub-expressions and macros, expanded into the core AST before anything reads the expression.

expand(node, schema, context, *, shadow=frozenset()) #

expand(
    node: ArithmeticNode,
    schema: Spec,
    context: str,
    *,
    shadow: frozenset[str] = ...,
) -> ArithmeticNode
expand(
    node: ComparisonNode,
    schema: Spec,
    context: str,
    *,
    shadow: frozenset[str] = ...,
) -> ComparisonNode

Expand all named sub-expressions and macro calls under node.

A comparison stays a comparison and an arithmetic node stays arithmetic.

PARAMETER DESCRIPTION
node

The parsed expression.

TYPE: ParsedNode

schema

Where names and macros are declared.

TYPE: Spec

context

What an error names.

TYPE: str

shadow

Names left as written even where a named expression has that name — a template's formals, checked without a call to bind them.

TYPE: frozenset[str] DEFAULT: frozenset()

Source code in src/math_spec/expansion.py
def expand(node: ParsedNode, schema: Spec, context: str, *, shadow: frozenset[str] = frozenset()) -> ParsedNode:
    """Expand all named sub-expressions and macro calls under *node*.

    A comparison stays a comparison and an arithmetic node stays arithmetic.

    Args:
        node: The parsed expression.
        schema: Where names and macros are declared.
        context: What an error names.
        shadow: Names left as written even where a named expression has that
            name — a template's formals, checked without a call to bind them.
    """
    if isinstance(node, ComparisonNode):
        return ComparisonNode(
            node.op,
            _expand(node.left, schema, context, (), shadow),
            _expand(node.right, schema, context, (), shadow),
        )
    return _expand(node, schema, context, (), shadow)

macro_signature(name, macro) #

Human-readable call signature, for error messages.

Source code in src/math_spec/expansion.py
def macro_signature(name: str, macro: MacroBlock) -> str:
    """Human-readable call signature, for error messages."""
    parts = [*macro.args, *(f'{k}=...' for k in macro.kwargs)]
    return f'{name}({", ".join(parts)})'

parse_and_expand(text, schema, context) #

Parse text and expand named sub-expressions and macros to core AST.

Source code in src/math_spec/expansion.py
def parse_and_expand(text: str, schema: Spec, context: str) -> ParsedNode:
    """Parse *text* and expand named sub-expressions and macros to core AST."""
    return expand(parse_expression(text), schema, context)

parse_template(name, macro, context) #

Parse a macro template, rejecting comparisons.

Source code in src/math_spec/expansion.py
def parse_template(name: str, macro: MacroBlock, context: str) -> ArithmeticNode:
    """Parse a macro template, rejecting comparisons."""
    return _parse_body(macro.template, f"macro '{name}' template", context)