Ejemplo n.º 1
0
 def visit_Attribute(self, node):
     """ Compute typing for an attribute node. """
     obj, path = attr_to_path(node)
     assert not obj.isliteral() or obj.return_type, "Constants are known."
     # If no type is given, use a decltype
     if obj.return_type:
         self.result[node] = obj.return_type
     else:
         self.result[node] = DeclType('::'.join(path) + '{}')
Ejemplo n.º 2
0
Archivo: types.py Proyecto: yws/pythran
 def visit_Attribute(self, node):
     """ Compute typing for an attribute node. """
     obj, path = attr_to_path(node)
     # If no type is given, use a decltype
     if obj.isliteral():
         typename = pytype_to_ctype(obj.signature)
         self.result[node] = NamedType(typename)
     else:
         self.result[node] = DeclType('::'.join(path) + '{}')
Ejemplo n.º 3
0
    def visit_List(self, node):
        if not node.elts:  # empty list
            return "pythonic::__builtin__::functor::list{}()"
        else:
            elts = [self.visit(n) for n in node.elts]
            elts_type = [DeclType(elt) for elt in elts]
            elts_type = CombinedTypes(*elts_type)

            # constructor disambiguation, clang++ workaround
            if len(elts) == 1:
                elts.append('pythonic::types::single_value()')

            node_type = ListType(elts_type)
            return "{0}({{{1}}})".format(Assignable(node_type),
                                         ", ".join(elts))
Ejemplo n.º 4
0
    def visit_Attribute(self, node):
        """ Compute typing for an attribute node. """
        def get_intrinsic_path(modules, attr):
            """ Get function path and intrinsic from an ast.Attributs.  """
            if isinstance(attr, ast.Name):
                return modules[attr.id], (attr.id, )
            elif isinstance(attr, ast.Attribute):
                module, path = get_intrinsic_path(modules, attr.value)
                return module[attr.attr], path + (attr.attr, )

        # Get the intrinsic object and its path as path is use in Pythonic
        # hierarchy and obj may give additional information
        obj, path = get_intrinsic_path(MODULES, node)
        path = ('pythonic', ) + path
        assert not obj.isliteral() or obj.return_type, "Constants are known."
        # If no type is given, use a decltype
        if obj.return_type:
            self.result[node] = obj.return_type
        else:
            self.result[node] = DeclType('::'.join(path[:-1]) + '::proxy::' +
                                         path[-1] + '()')
Ejemplo n.º 5
0
    def visit_For(self, node):
        """
        Create For representation for Cxx generation.

        Examples
        --------
        >> for i in xrange(10):
        >>     ... work ...

        Becomes

        >> typename returnable<decltype(__builtin__.xrange(10))>::type __iterX
           = __builtin__.xrange(10);
        >> ... possible container size reservation ...
        >> for (auto&& i: __iterX)
        >>     ... the work ...

        This function also handle assignment for local variables.

        We can notice that three kind of loop are possible:
        - Normal for loop on iterator
        - Autofor loop.
        - Normal for loop using integer variable iteration
        Kind of loop used depend on OpenMP, yield use and variable scope.
        """
        if not isinstance(node.target, ast.Name):
            raise PythranSyntaxError(
                "Using something other than an identifier as loop target",
                node.target)
        target = self.visit(node.target)

        # Handle the body of the for loop
        loop_body = Block([self.visit(stmt) for stmt in node.body])

        # Declare local variables at the top of the loop body
        loop_body = self.process_locals(node, loop_body, node.target.id)
        iterable = self.visit(node.iter)

        if self.can_use_c_for(node):
            header, loop = self.gen_c_for(node, target, loop_body)
        else:

            if self.can_use_autofor(node):
                header = []
                self.ldecls = {
                    d
                    for d in self.ldecls if d.id != node.target.id
                }
                autofor = AutoFor(target, iterable, loop_body)
                loop = [self.process_omp_attachements(node, autofor)]
            else:
                # Iterator declaration
                local_iter = "__iter{0}".format(len(self.break_handlers))
                local_iter_decl = Assignable(DeclType(iterable))

                self.handle_omp_for(node, local_iter)

                # For yield function, iterable is globals.
                if self.yields:
                    self.extra_declarations.append((
                        local_iter,
                        local_iter_decl,
                    ))
                    local_iter_decl = ""

                # Assign iterable
                # For C loop, it avoids issues
                # if the upper bound is assigned in the loop
                header = [
                    Statement("{0} {1} = {2}".format(local_iter_decl,
                                                     local_iter, iterable))
                ]
                loop = self.gen_for(node, target, local_iter, loop_body)

        # For xxxComprehension, it is replaced by a for loop. In this case,
        # pre-allocate size of container.
        for comp in metadata.get(node, metadata.Comprehension):
            header.append(
                Statement("pythonic::utils::reserve({0},{1})".format(
                    comp.target, iterable)))

        return Block(header + loop)