Skip to content

scopes

Define the lexical-scope stack used to resolve locals and detect redeclarations during analysis.

Classes:

Scope dataclass

Scope(
    kind: str, symbols: dict[str, SemanticSymbol] = dict()
)

Hold the local symbol table for one lexical region such as a module or function body. attributes: kind: type: str symbols: type: dict[str, SemanticSymbol]

ScopeStack

ScopeStack()

Manage nested lexical scopes for local declarations and name lookup. attributes: _stack: type: list[Scope]

Methods:

Attributes:

Source code in packages/irx/src/irx/analysis/scopes.py
50
51
52
53
54
def __init__(self) -> None:
    """
    title: Initialize ScopeStack.
    """
    self._stack: list[Scope] = []

current property

current: Scope | None

Expose the innermost active lexical scope, if one has been pushed. returns: type: Scope | None

declare

declare(symbol: SemanticSymbol) -> bool

Add one local symbol to the current scope, reporting whether the name was new there. parameters: symbol: type: SemanticSymbol returns: type: bool

Source code in packages/irx/src/irx/analysis/scopes.py
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
def declare(self, symbol: SemanticSymbol) -> bool:
    """
    title: Declare a symbol in the current scope.
    summary: >-
      Add one local symbol to the current scope, reporting whether the name
      was new there.
    parameters:
      symbol:
        type: SemanticSymbol
    returns:
      type: bool
    """
    current = self.current
    if current is None:
        raise RuntimeError("No active scope")
    if symbol.name in current.symbols:
        return False
    current.symbols[symbol.name] = symbol
    return True

pop

pop() -> Scope

Remove and return the innermost lexical scope after a block finishes analysis. returns: type: Scope

Source code in packages/irx/src/irx/analysis/scopes.py
83
84
85
86
87
88
89
90
91
92
def pop(self) -> Scope:
    """
    title: Pop the current scope.
    summary: >-
      Remove and return the innermost lexical scope after a block finishes
      analysis.
    returns:
      type: Scope
    """
    return self._stack.pop()

push

push(kind: str) -> Scope
Source code in packages/irx/src/irx/analysis/scopes.py
69
70
71
72
73
74
75
76
77
78
79
80
81
def push(self, kind: str) -> Scope:
    """
    title: Push a scope.
    summary: Create and activate a new lexical scope of the requested kind.
    parameters:
      kind:
        type: str
    returns:
      type: Scope
    """
    scope = Scope(kind=kind)
    self._stack.append(scope)
    return scope

resolve

resolve(name: str) -> SemanticSymbol | None

Search outward from the innermost scope to find the visible local symbol for one name. parameters: name: type: str returns: type: SemanticSymbol | None

Source code in packages/irx/src/irx/analysis/scopes.py
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
def resolve(self, name: str) -> SemanticSymbol | None:
    """
    title: Resolve a symbol by name.
    summary: >-
      Search outward from the innermost scope to find the visible local
      symbol for one name.
    parameters:
      name:
        type: str
    returns:
      type: SemanticSymbol | None
    """
    for scope in reversed(self._stack):
        symbol = scope.symbols.get(name)
        if symbol is not None:
            return symbol
    return None