Example #1
0
    def get_type(self, env=None):
        if isinstance(self.op, Op.ArrayRef):
            if isinstance(self.left, SymbolRef) and env is not None \
                    and env._has_key(self.left.name):
                type = env._lookup(self.left.name)._dtype_
                return get_c_type_from_numpy_dtype(type)()

        # FIXME: integer promotions and stuff like that
        if hasattr(self.left, 'get_type'):
            left_type = self.left.get_type()
        elif isinstance(self.left, SymbolRef) and env is not None \
                and env._has_key(self.left.name):
            left_type = env._lookup(self.left.name)
        elif hasattr(self.left, 'type'):
            left_type = self.left.type
        else:
            left_type = None
        if hasattr(self.right, 'get_type'):
            right_type = self.right.get_type()
        elif isinstance(self.right, SymbolRef) and env is not None \
                and env._has_key(self.right.name):
            right_type = env._lookup(self.right.name)
        elif hasattr(self.right, 'type'):
            right_type = self.right.type
        else:
            right_type = None
        if isinstance(self.op, Op.ArrayRef):
            ptr_type = left_type._type_
            return ptr_type() if hasattr(ptr_type, '__call__') else left_type
        return get_common_ctype(
            filter(lambda x: x is not None, [right_type, left_type]))
Example #2
0
    def get_type(self, env=None):
        if isinstance(self.op, Op.ArrayRef):
            if isinstance(self.left, SymbolRef) and env is not None \
                    and env._has_key(self.left.name):
                type = env._lookup(self.left.name)._dtype_
                return get_c_type_from_numpy_dtype(type)()

        # FIXME: integer promotions and stuff like that
        if hasattr(self.left, 'get_type'):
            left_type = self.left.get_type()
        elif isinstance(self.left, SymbolRef) and env is not None \
                and env._has_key(self.left.name):
            left_type = env._lookup(self.left.name)
        elif hasattr(self.left, 'type'):
            left_type = self.left.type
        else:
            left_type = None
        if hasattr(self.right, 'get_type'):
            right_type = self.right.get_type()
        elif isinstance(self.right, SymbolRef) and env is not None \
                and env._has_key(self.right.name):
            right_type = env._lookup(self.right.name)
        elif hasattr(self.right, 'type'):
            right_type = self.right.type
        else:
            right_type = None
        return get_common_ctype(filter(lambda x: x is not None, [right_type,
                                                                 left_type]))
Example #3
0
 def get_type(self, env=None):
     # FIXME: integer promotions and stuff like that
     if hasattr(self.left, 'get_type'):
         left_type = self.left.get_type()
     elif isinstance(self.left, SymbolRef) and env is not None \
             and env._has_key(self.left.name):
         left_type = env._lookup(self.left.name)
     elif hasattr(self.left, 'type'):
         left_type = self.left.type
     else:
         left_type = None
     if hasattr(self.right, 'get_type'):
         right_type = self.right.get_type()
     elif isinstance(self.right, SymbolRef) and env is not None \
             and env._has_key(self.right.name):
         right_type = env._lookup(self.right.name)
     elif hasattr(self.right, 'type'):
         right_type = self.right.type
     else:
         right_type = None
     return get_common_ctype(
         filter(lambda x: x is not None, [right_type, left_type]))
Example #4
0
 def test_coercion(self):
     types = (ctypes.c_long, ctypes.c_double, ctypes.c_int)
     self.assertEqual(get_common_ctype(types), ctypes.c_double)
Example #5
0
 def visit_List(self, node):
     elts = [self.visit(elt) for elt in node.elts]
     types = [get_type(elt) for elt in elts]
     array_type = get_common_ctype(types)
     return Array(type=ctypes.POINTER(array_type)(), body=elts)
Example #6
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
Example #7
0
 def visit_List(self, node):
     elts = [self.visit(elt) for elt in node.elts]
     types = [get_type(elt) for elt in elts]
     array_type = get_common_ctype(types)
     return Array(type=ctypes.POINTER(array_type)(), body=elts)
Example #8
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