%PDF- %PDF-
Direktori : /lib/python3/dist-packages/pythran/ |
Current File : //lib/python3/dist-packages/pythran/intrinsic.py |
""" This module contains all classes used to model intrinsics behavior. """ from pythran.conversion import to_ast from pythran.interval import UNKNOWN_RANGE, bool_values from pythran.types.signature import extract_combiner from pythran.typing import Any, Union, Fun, Generator import gast as ast class UnboundValueType(object): ''' Represents a new location, bound to no identifier ''' UnboundValue = UnboundValueType() # FIXME: we should find a better way to implement default behavior DefaultArgNum = 20 class UpdateEffect(object): pass class ReadEffect(object): pass class ReadOnceEffect(ReadEffect): pass class Intrinsic(object): """ Model any Method/Function. Its member variables are: - argument_effects that describes the effect of the function on its argument (either UpdateEffect, ReadEffect or ReadOnceEffect) - global_effects that describes whether the function has side effects - return_alias that describes the aliasing between the return value and the parameters. The lambda returns an ast expression, generally depending on the node arguments (see dict.setdefault) - args that describes the name and default value of each arg, using the same representation as ast.FunctionDef, i.e. ast.arguments """ def __init__(self, **kwargs): self.argument_effects = kwargs.get('argument_effects', (UpdateEffect(),) * DefaultArgNum) self.global_effects = kwargs.get('global_effects', False) self.return_alias = kwargs.get('return_alias', lambda x: {UnboundValue}) self.args = ast.arguments( [ast.Name(n, ast.Param(), None, None) for n in kwargs.get('args', [])], [], None, [ast.Name(n, ast.Param(), None, None) for n in kwargs.get('kwonlyargs', [])], [], None, [to_ast(d) for d in kwargs.get('defaults', [])]) self.return_range = kwargs.get("return_range", lambda call: UNKNOWN_RANGE) self.return_range_content = kwargs.get("return_range_content", lambda c: UNKNOWN_RANGE) def isliteral(self): return False def isfunction(self): return False def isstaticfunction(self): return False def ismethod(self): return False def isattribute(self): return False def isconst(self): return not any( isinstance(x, UpdateEffect) for x in self.argument_effects ) and not self.global_effects def isreadonce(self, n): return isinstance(self.argument_effects[n], ReadOnceEffect) def combiner(self, s, node): pass class FunctionIntr(Intrinsic): def __init__(self, **kwargs): kwargs.setdefault('combiners', ()) super(FunctionIntr, self).__init__(**kwargs) self.combiners = kwargs['combiners'] if 'signature' in kwargs: self.signature = kwargs['signature'] deduced_combiner = extract_combiner(self.signature) if deduced_combiner is not None: self.combiners += deduced_combiner, if 'return_range' not in kwargs: if isinstance(self.signature, Union): if all(r.__args__[-1] is bool for r in self.signature.__args__): self.return_range = bool_values elif isinstance(self.signature, Generator): if self.signature.__args__[0] is bool: self.return_range = bool_values elif isinstance(self.signature, Fun): if self.signature.__args__[-1] is bool: self.return_range = bool_values else: self.signature = Any if 'immediate_arguments' in kwargs: self.immediate_arguments = kwargs['immediate_arguments'] else: self.immediate_arguments = [] def isfunction(self): return True def isstaticfunction(self): return True def add_combiner(self, _combiner): self.combiners += (_combiner,) def combiner(self, s, node): for comb in self.combiners: comb(s, node) class UserFunction(FunctionIntr): def __init__(self, *combiners, **kwargs): kwargs['combiners'] = combiners super(UserFunction, self).__init__(**kwargs) class ConstFunctionIntr(FunctionIntr): def __init__(self, **kwargs): kwargs.setdefault('argument_effects', (ReadEffect(),) * DefaultArgNum) super(ConstFunctionIntr, self).__init__(**kwargs) class ConstExceptionIntr(ConstFunctionIntr): def __init__(self, **kwargs): kwargs.setdefault('argument_effects', (ReadEffect(),) * DefaultArgNum) super(ConstExceptionIntr, self).__init__(**kwargs) class ReadOnceFunctionIntr(ConstFunctionIntr): def __init__(self, **kwargs): super(ReadOnceFunctionIntr, self).__init__( argument_effects=(ReadOnceEffect(),) * DefaultArgNum, **kwargs) class MethodIntr(FunctionIntr): def __init__(self, *combiners, **kwargs): kwargs.setdefault('argument_effects', (UpdateEffect(),) + (ReadEffect(),) * DefaultArgNum) kwargs['combiners'] = combiners super(MethodIntr, self).__init__(**kwargs) def ismethod(self): return True def isstaticfunction(self): return False class ConstMethodIntr(MethodIntr): def __init__(self, *combiners, **kwargs): kwargs.setdefault('argument_effects', (ReadEffect(),) * DefaultArgNum) super(ConstMethodIntr, self).__init__(*combiners, **kwargs) class ReadOnceMethodIntr(ConstMethodIntr): def __init__(self, **kwargs): super(ReadOnceMethodIntr, self).__init__( argument_effects=(ReadOnceEffect(),) * DefaultArgNum, **kwargs) class AttributeIntr(Intrinsic): """ Internal representation for any attributes. Examples -------- >> a.real """ def __init__(self, **kwargs): """ Forward arguments. """ super(AttributeIntr, self).__init__(**kwargs) if 'signature' in kwargs: self.signature = kwargs['signature'] else: self.signature = Any def isattribute(self): """ Mark this intrinsic as an attribute. """ return True class ConstantIntr(Intrinsic): """ Internal representation for any constant. Examples -------- >> math.pi """ def __init__(self, **kwargs): """ Forward arguments and remove arguments effects. """ kwargs["argument_effects"] = () super(ConstantIntr, self).__init__(**kwargs) def isliteral(self): """ Mark this intrinsic as a literal. """ return True class Class(Intrinsic): def __init__(self, d, *args, **kwargs): super(Class, self).__init__(*args, **kwargs) self.fields = d def __getitem__(self, key): return self.fields[key] def __iter__(self): return self.fields.__iter__() def __contains__(self, key): """ Forward key content to aliased module. """ return key in self.fields class ClassWithReadOnceConstructor(Class, ReadOnceFunctionIntr): def __init__(self, d, *args, **kwargs): super(ClassWithReadOnceConstructor, self).__init__(d, *args, **kwargs) class ClassWithConstConstructor(Class, ConstFunctionIntr): def __init__(self, d, *args, **kwargs): super(ClassWithConstConstructor, self).__init__(d, *args, **kwargs) class ExceptionClass(Class, ConstExceptionIntr): def __init__(self, d, *args, **kwargs): super(ExceptionClass, self).__init__(d, *args, **kwargs) class UFunc(Class, ConstFunctionIntr): """ Representation of ufunc from numpy. """