Esempio n. 1
0
    def visit_UnaryOp(self, node):
        """ Update range with given unary operation.

        >>> import ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse('''
        ... def foo():
        ...     a = 2
        ...     c = -a
        ...     d = ~a
        ...     f = +a
        ...     e = not a''')
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValues, node)
        >>> res['f']
        Range(low=2, high=2)
        >>> res['c']
        Range(low=-2, high=-2)
        >>> res['d']
        Range(low=-3, high=-3)
        >>> res['e']
        Range(low=0, high=1)
        """
        res = self.visit(node.operand)
        if isinstance(node.op, ast.Not):
            return Range(0, 1)
        elif (isinstance(node.op, ast.Invert) and isinstance(res.high, int)
              and isinstance(res.low, int)):
            return Range(~res.high, ~res.low)
        elif isinstance(node.op, ast.UAdd):
            return res
        elif isinstance(node.op, ast.USub):
            return Range(-res.high, -res.low)
        else:
            return UNKNOWN_RANGE
Esempio n. 2
0
    def visit_Compare(node):
        """ Boolean are possible index.

        >>> import ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse('''
        ... def foo():
        ...     a = 2 or 3
        ...     b = 4 or 5
        ...     c = a < b''')
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValues, node)
        >>> res['c']
        Range(low=0, high=1)
        """
        return Range(0, 1)
Esempio n. 3
0
    def visit_BoolOp(self, node):
        """ Merge right and left operands ranges.

        TODO : We could exclude some operand with this range information...

        >>> import ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse('''
        ... def foo():
        ...     a = 2
        ...     c = 3
        ...     d = a or c''')
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValues, node)
        >>> res['d']
        Range(low=2, high=3)
        """
        res = zip(*map(self.visit, node.values))
        return Range(min(res[0]), max(res[1]))
Esempio n. 4
0
    def visit_IfExp(self, node):
        """ Use worst case for both possible values.

        >>> import ast
        >>> from pythran import passmanager, backend
        >>> node = ast.parse('''
        ... def foo():
        ...     a = 2 or 3
        ...     b = 4 or 5
        ...     c = a if a else b''')
        >>> pm = passmanager.PassManager("test")
        >>> res = pm.gather(RangeValues, node)
        >>> res['c']
        Range(low=2, high=5)
        """
        self.visit(node.test)
        body_res = self.visit(node.body)
        orelse_res = self.visit(node.orelse)
        return Range(min(orelse_res.low, body_res.low),
                     max(orelse_res.high, body_res.high))
Esempio n. 5
0
 def visit_Num(node):
     """ Handle literals integers values. """
     if isinstance(node.n, int):
         return Range(node.n, node.n)
     else:
         return UNKNOWN_RANGE