1# -*- coding: utf-8 -*- 2"""The optimizer tries to constant fold expressions and modify the AST 3in place so that it should be faster to evaluate. 4 5Because the AST does not contain all the scoping information and the 6compiler has to find that out, we cannot do all the optimizations we 7want. For example, loop unrolling doesn't work because unrolled loops 8would have a different scope. The solution would be a second syntax tree 9that stored the scoping rules. 10""" 11from . import nodes 12from .visitor import NodeTransformer 13 14 15def optimize(node, environment): 16 """The context hint can be used to perform an static optimization 17 based on the context given.""" 18 optimizer = Optimizer(environment) 19 return optimizer.visit(node) 20 21 22class Optimizer(NodeTransformer): 23 def __init__(self, environment): 24 self.environment = environment 25 26 def generic_visit(self, node, *args, **kwargs): 27 node = super(Optimizer, self).generic_visit(node, *args, **kwargs) 28 29 # Do constant folding. Some other nodes besides Expr have 30 # as_const, but folding them causes errors later on. 31 if isinstance(node, nodes.Expr): 32 try: 33 return nodes.Const.from_untrusted( 34 node.as_const(args[0] if args else None), 35 lineno=node.lineno, 36 environment=self.environment, 37 ) 38 except nodes.Impossible: 39 pass 40 41 return node 42