%PDF- %PDF-
| Direktori : /lib/python3/dist-packages/pythran/analyses/ |
| Current File : //lib/python3/dist-packages/pythran/analyses/constant_expressions.py |
""" ConstantExpressions gathers constant expression. """
from pythran.analyses.aliases import Aliases
from pythran.analyses.globals_analysis import Globals
from pythran.analyses.locals_analysis import Locals
from pythran.analyses.pure_expressions import PureExpressions
from pythran.intrinsic import FunctionIntr
from pythran.passmanager import NodeAnalysis
import gast as ast
class ConstantExpressions(NodeAnalysis):
"""Identify constant expressions."""
def __init__(self):
self.result = set()
super(ConstantExpressions, self).__init__(Globals, Locals,
PureExpressions, Aliases)
def add(self, node):
self.result.add(node)
return True
def visit_BoolOp(self, node):
return all([self.visit(x) for x in node.values]) and self.add(node)
def visit_BinOp(self, node):
rec = all([self.visit(x) for x in (node.left, node.right)])
return rec and self.add(node)
def visit_UnaryOp(self, node):
return self.visit(node.operand) and self.add(node)
def visit_IfExp(self, node):
rec = all([self.visit(x) for x in (node.test, node.body, node.orelse)])
return rec and self.add(node)
def visit_Compare(self, node):
rec = all([self.visit(x) for x in ([node.left] + node.comparators)])
return rec and self.add(node)
def visit_Call(self, node):
rec = all([self.visit(x) for x in (node.args + [node.func])])
return rec and self.add(node)
visit_Constant = add
def visit_Subscript(self, node):
rec = all([self.visit(x) for x in (node.value, node.slice)])
rec = isinstance(node.ctx, ast.Load) and rec
return rec and self.add(node)
def visit_Name(self, node):
if node in self.aliases:
# params and store are not constants
if not isinstance(node.ctx, ast.Load):
return False
# if we can alias on multiple value, it is not constant
elif len(self.aliases[node]) > 1:
return False
# if it is not a globals, it depends on variable so it is not
# constant
elif node.id not in self.globals:
return False
# if it is defined in the current function, it is not constant
elif node.id in self.locals[node]:
return False
def is_function(x):
return isinstance(x, (FunctionIntr,
ast.FunctionDef,
ast.alias))
pure_fun = all(alias in self.pure_expressions and
is_function(alias)
for alias in self.aliases[node])
return pure_fun
else:
return False
def visit_Attribute(self, node):
return Aliases.access_path(node).isconst() and self.add(node)
def visit_Dict(self, node):
rec = all([self.visit(x) for x in (node.keys + node.values)])
return rec and self.add(node)
def visit_List(self, node):
return all([self.visit(x) for x in node.elts]) and self.add(node)
visit_Tuple = visit_List
visit_Set = visit_List
def visit_Slice(self, node):
return all([x is None or self.visit(x) for x in
(node.lower, node.upper, node.step)]) and self.add(node)
def visit_Index(self, node):
return self.visit(node.value) and self.add(node)