o
    í@ËaÐ
  ã                   @   sP   d Z ddlmZ ddlmZ ddlZddlmZ ddl	m
Z
 G dd„ deƒZdS )	z> Simplify expressions based on range information when possibleé    )ÚRangeValues)ÚTransformationN)Úisinf)Údeepcopyc                   @   s@   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ ZeZd
d„ Z	e	Z
dS )ÚRangeBasedSimplifyaÞ  
    Simplify expressions based on range analysis

    >>> import gast as ast
    >>> from pythran import passmanager, backend

    >>> node = ast.parse("def any():\n for x in builtins.range(10): y=x%8")
    >>> pm = passmanager.PassManager("test")
    >>> _, node = pm.apply(RangeBasedSimplify, node)
    >>> print(pm.dump(backend.Python, node))
    def any():
        for x in builtins.range(10):
            y = (x if (x < 8) else (x - 8))

    >>> node = ast.parse("def any(): x = 1 or 2; return 3 == x")
    >>> pm = passmanager.PassManager("test")
    >>> _, node = pm.apply(RangeBasedSimplify, node)
    >>> print(pm.dump(backend.Python, node))
    def any():
        x = (1 or 2)
        return 0

    >>> node = ast.parse("def a(i): x = 1,1,2; return x[2], x[0 if i else 1]")
    >>> pm = passmanager.PassManager("test")
    >>> _, node = pm.apply(RangeBasedSimplify, node)
    >>> print(pm.dump(backend.Python, node))
    def a(i):
        x = (1, 1, 2)
        return (2, 1)
    c                 C   s   t  | t¡ d S ©N)r   Ú__init__r   )Úself© r
   úL/usr/lib/python3/dist-packages/pythran/optimizations/range_based_simplify.pyr   +   s   zRangeBasedSimplify.__init__c                 C   s   |S r   r
   ©r	   Únoder
   r
   r   Úvisit_OMPDirective.   s   z%RangeBasedSimplify.visit_OMPDirectivec              	   C   sÊ   |   |¡}t|jtjƒs|S | j|j }| j|j }|jdk s$t	|j
ƒr&|S |j|j k r/|S |j
|j
d kr9|S t|jƒt|jƒ}}t|jƒ}d| _t t |jt ¡ g|jg¡|t |t ¡ |¡¡S )Nr   é   T)Úgeneric_visitÚ
isinstanceÚopÚastZModÚrange_valuesÚrightÚleftÚlowr   Úhighr   ÚupdateZIfExpZCompareZLtZBinOpZSub)r	   r   Zright_rangeZ
left_rangeZcleft0Zcleft1Zcrightr
   r
   r   Úvisit_BinOp1   s$   

þzRangeBasedSimplify.visit_BinOpc                 C   sH   | j | }t|jƒr|  |¡S |j|jkrd| _t |jd ¡S |  |¡S )NT)r   r   r   r   r   r   r   ZConstant)r	   r   Zrange_valuer
   r
   r   Úvisit_rangeH   s   



zRangeBasedSimplify.visit_rangec                 C   s"   t |jtjƒr|  |¡S |  |¡S r   )r   Úctxr   ZLoadr   r   r   r
   r
   r   Ú
visit_NameT   s   

zRangeBasedSimplify.visit_NameN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   Zvisit_Comparer   Zvisit_Subscriptr
   r
   r
   r   r      s    
r   )r!   Zpythran.analysesr   Zpythran.passmanagerr   Zgastr   Zmathr   Úcopyr   r   r
   r
   r
   r   Ú<module>   s    