math_spec.resolution
Name resolution — the pass that makes the core AST fully typed.
Parsers emit unresolved names; this module rewrites each into the typed node its kind asks for, so the AST reaching a consumer holds none. Done once here, every consumer scopes identically by construction. The rules live in the language reference; the namespace is flat, and macro formals are the one scope.
Namespace(variables, parameters, dimensions, lookups, dtypes)
#
The declared names of one schema, by kind.
Flat by construction: :meth:kind is a single lookup, not an ordered
walk through several stores.
Source code in src/math_spec/resolution.py
dimensions = frozenset(dimensions)
instance-attribute
#
dtypes = dict(dtypes)
instance-attribute
#
lookups = dict(lookups)
instance-attribute
#
parameters = frozenset(parameters)
instance-attribute
#
variables = frozenset(variables)
instance-attribute
#
groupable()
#
The lookups a by= may name: name -> the dimension it maps into.
A label space is absent, which is what makes naming one in a by=
answerable with the promotion rewrite rather than "no such lookup".
Source code in src/math_spec/resolution.py
into_of(lookup)
#
kind(name)
#
'variable' | 'parameter' | 'dimension' | 'lookup' | None.
Source code in src/math_spec/resolution.py
of(schema)
classmethod
#
Build the namespace of schema, the whole of what a file may name.
A targeted lookup's values are labels of its target, so its dtype is the target's.
Source code in src/math_spec/resolution.py
expression_of(text, schema, ns, context)
#
Parse, expand and resolve text — the only way a consumer gets an AST.
validation.py runs the same path at load time, so a consumer calling
this gets a typed tree off a result already known to be clean, without
duplicating the pass.
| RAISES | DESCRIPTION |
|---|---|
LanguageError
|
Listing every problem the text has. |
Source code in src/math_spec/resolution.py
resolve_expression(node, ns, context, errors)
#
Rewrite every NameNode under node to a typed node.
Operator call shapes are checked here too (operators.call_shape_error).
Arity is a language rule, and this is the pass every consumer goes through,
so no consumer has to state a signature a second time.
| RETURNS | DESCRIPTION |
|---|---|
ExpressionNode | None
|
The typed tree, or |
ExpressionNode | None
|
errors rather than raising, so a caller collecting problems across a |
ExpressionNode | None
|
whole schema reports them together. |
Source code in src/math_spec/resolution.py
resolve_where(node, ns, context, errors, self_variable=None)
#
Rewrite a parsed where AST into typed predicates.
Both parameters and dimensions are legal here — a where-string is a predicate over the frame, and the frame carries its own coordinates. What is not legal is an unknown name: read as "scalar False" it would mask every row out and produce an empty model in silence.
Source code in src/math_spec/resolution.py
where_of(text, ns, context, self_variable=None)
#
Parse, resolve and fold a where string — None for no mask, however the file spelled it.
Every constant the connectives decide is folded away, so a mask that
admits every row arrives as None and one that admits none as
BooleanLiteralNode(False); that node stands at the root of a mask or
nowhere in it, and every reader — a program, a typeset page — gets the
same predicate.
| RAISES | DESCRIPTION |
|---|---|
LanguageError
|
Listing every problem the predicate has. |