Ejemplo n.º 1
0
    def visit_For(self, node):
        """restricted, for now, to range as iterator with long-type args"""
        if isinstance(node, ast.For) and \
           isinstance(node.iter, ast.Call) and \
           isinstance(node.iter.func, ast.Name) and \
           node.iter.func.id == 'range':
            Range = node.iter
            nArgs = len(Range.args)
            if nArgs == 1:
                stop = self.visit(Range.args[0])
                start, step = Constant(0), Constant(1)
            elif nArgs == 2:
                start, stop = map(self.visit, Range.args)
                step = Constant(1)
            elif nArgs == 3:
                start, stop, step = map(self.visit, Range.args)
            else:
                raise Exception("Cannot convert a for...range with %d args." % nArgs)

            # TODO allow any expressions castable to Long type
            assert isinstance(stop.get_type(), c_long), "Can only convert range's with stop values of Long type."
            assert isinstance(start.get_type(), c_long), "Can only convert range's with start values of Long type."
            assert isinstance(step.get_type(), c_long), "Can only convert range's with step values of Long type."

            target = SymbolRef(node.target.id, c_long())
            for_loop = For(
                Assign(target, start),
                Lt(target.copy(), stop),
                AddAssign(target.copy(), step),
                [self.visit(stmt) for stmt in node.body],
            )
            return for_loop
        node.body = list(map(self.visit, node.body))
        return node
Ejemplo n.º 2
0
 def visit_AugAssign(self, node):
     op = type(node.op)
     target = self.visit(node.target)
     value = self.visit(node.value)
     if op is ast.Add:
         return AddAssign(target, value)
     elif op is ast.Sub:
         return SubAssign(target, value)
     elif op is ast.Mult:
         return MulAssign(target, value)
     elif op is ast.Div:
         return DivAssign(target, value)
     # TODO: Error?
     return node
Ejemplo n.º 3
0
    def visit_For(self, node):
        """restricted, for now, to range as iterator with long-type args"""
        if isinstance(node, ast.For) and \
           isinstance(node.iter, ast.Call) and \
           isinstance(node.iter.func, ast.Name) and \
           node.iter.func.id in ('range', 'xrange'):
            Range = node.iter
            nArgs = len(Range.args)
            if nArgs == 1:
                stop = self.visit(Range.args[0])
                start, step = Constant(0), Constant(1)
            elif nArgs == 2:
                start, stop = map(self.visit, Range.args)
                step = Constant(1)
            elif nArgs == 3:
                start, stop, step = map(self.visit, Range.args)
            else:
                raise Exception("Cannot convert a for...range with %d args." %
                                nArgs)

            #  check no-op conditions.
            if all(isinstance(item, Constant) for item in (start, stop, step)):
                if step.value == 0:
                    raise ValueError("range() step argument must not be zero")
                elif start.value == stop.value or \
                        (start.value < stop.value and step.value < 0) or \
                        (start.value > stop.value and step.value > 0):
                    return None

            if not all(
                    isinstance(item, CtreeNode)
                    for item in (start, stop, step)):
                node.body = list(map(self.visit, node.body))
                return node

            # TODO allow any expressions castable to Long type
            target_types = [c_long]
            for el in (stop, start, step):
                #  typed item to try and guess type off of. Imperfect right now.
                if hasattr(el, 'get_type'):
                    # TODO take the proper class instead of the last; if start,
                    # end are doubles, but step is long, target is double
                    t = el.get_type()
                    assert any(
                        isinstance(t, klass)
                        for klass in [c_byte, c_int, c_long, c_short]
                    ), "Can only convert ranges with integer/long \
                         start/stop/step values"

                    target_types.append(type(t))
            target_type = get_common_ctype(target_types)()

            target = SymbolRef(node.target.id, target_type)
            op = Lt
            if hasattr(start, 'value') and hasattr(stop, 'value') and \
                    start.value > stop.value:
                op = Gt
            for_loop = For(
                Assign(target, start),
                op(target.copy(), stop),
                AddAssign(target.copy(), step),
                [self.visit(stmt) for stmt in node.body],
            )
            return for_loop
        node.body = list(map(self.visit, node.body))
        return node