%PDF- %PDF-
| Direktori : /lib/python3/dist-packages/pythran/analyses/ |
| Current File : //lib/python3/dist-packages/pythran/analyses/pure_expressions.py |
"""
PureExpressions detects functions without side-effects.
"""
from pythran.analyses.aliases import Aliases
from pythran.analyses.argument_effects import ArgumentEffects
from pythran.analyses.global_effects import GlobalEffects
from pythran.passmanager import ModuleAnalysis
from pythran.intrinsic import Intrinsic
import gast as ast
class PureExpressions(ModuleAnalysis):
'''Yields the set of pure expressions'''
def __init__(self):
self.result = set()
super(PureExpressions, self).__init__(ArgumentEffects, GlobalEffects,
Aliases)
def visit_FunctionDef(self, node):
# do not visit arguments
for stmt in node.body:
self.visit(stmt)
# Pure functions are already compute, we don't need to add them again
return False
def generic_visit(self, node):
is_pure = all([self.visit(x) for x in ast.iter_child_nodes(node)])
if is_pure:
self.result.add(node)
return is_pure
def visit_Call(self, node):
# check if all arguments are Pures
is_pure = all([self.visit(arg) for arg in node.args])
# check all possible function called
func_aliases = self.aliases[node.func]
if func_aliases:
for func_alias in func_aliases:
# does the function have a global effect?
if isinstance(func_alias, Intrinsic):
is_pure &= not func_alias.global_effects
else:
is_pure &= func_alias in self.result
# does the function have an argument effect ?
# trivial arguments can be ignored
if func_alias in self.argument_effects:
func_aes = self.argument_effects[func_alias]
for arg, ae in zip(node.args, func_aes):
if ae:
try:
ast.literal_eval(arg)
except ValueError:
is_pure = False
else:
is_pure = False
else:
is_pure = False # conservative choice
# check for chained call
is_pure &= self.visit(node.func)
if is_pure:
self.result.add(node)
return is_pure
def prepare(self, node):
super(PureExpressions, self).prepare(node)
self.result = {func for func, ae in self.argument_effects.items()
if func not in self.global_effects and not any(ae)}