Spaces:
Running
Running
"""The optimizer tries to constant fold expressions and modify the AST | |
in place so that it should be faster to evaluate. | |
Because the AST does not contain all the scoping information and the | |
compiler has to find that out, we cannot do all the optimizations we | |
want. For example, loop unrolling doesn't work because unrolled loops | |
would have a different scope. The solution would be a second syntax tree | |
that stored the scoping rules. | |
""" | |
import typing as t | |
from . import nodes | |
from .visitor import NodeTransformer | |
if t.TYPE_CHECKING: | |
from .environment import Environment | |
def optimize(node: nodes.Node, environment: "Environment") -> nodes.Node: | |
"""The context hint can be used to perform an static optimization | |
based on the context given.""" | |
optimizer = Optimizer(environment) | |
return t.cast(nodes.Node, optimizer.visit(node)) | |
class Optimizer(NodeTransformer): | |
def __init__(self, environment: "t.Optional[Environment]") -> None: | |
self.environment = environment | |
def generic_visit( | |
self, node: nodes.Node, *args: t.Any, **kwargs: t.Any | |
) -> nodes.Node: | |
node = super().generic_visit(node, *args, **kwargs) | |
# Do constant folding. Some other nodes besides Expr have | |
# as_const, but folding them causes errors later on. | |
if isinstance(node, nodes.Expr): | |
try: | |
return nodes.Const.from_untrusted( | |
node.as_const(args[0] if args else None), | |
lineno=node.lineno, | |
environment=self.environment, | |
) | |
except nodes.Impossible: | |
pass | |
return node | |