Beispiel #1
0
    def __init__(self,
                 parent,
                 datatype="",
                 entity_decls=None,
                 intent="",
                 pointer=False,
                 attrspec=None):
        if entity_decls is None:
            raise RuntimeError(
                "Cannot create a declaration of a derived-type variable "
                "without specifying the name(s) of the variable(s)")
        # make a copy of entity_decls as we may modify it
        local_entity_decls = entity_decls[:]
        if attrspec is None:
            attrspec = []
        my_attrspec = [spec for spec in attrspec]
        if intent != "":
            my_attrspec.append("intent({0})".format(intent))
        if pointer is not False:
            my_attrspec.append("pointer")
        self._names = local_entity_decls

        reader = FortranStringReader("type(vanillatype) :: vanilla")
        reader.set_mode(True, False)  # free form, strict
        myline = reader.next()

        from fparser.typedecl_statements import Type
        self._typedecl = Type(parent.root, myline)
        self._typedecl.selector = ('', datatype)
        self._typedecl.attrspec = my_attrspec
        self._typedecl.entity_decls = local_entity_decls
        BaseGen.__init__(self, parent, self._typedecl)
Beispiel #2
0
    def add(self, content, position=None, bubble_up=False):
        if position is None:
            position = ["auto"]

        if position[0] == "auto" and bubble_up:
            # There's currently no case where a bubbled-up statement
            # will live within a do loop so bubble it up again.
            self.parent.add(content, bubble_up=True)
            return

        if position[0] == "auto" or position[0] == "append":
            if position[0] == "auto" and bubble_up_type(content):
                # use and declaration statements cannot appear in a do loop
                # so pass on to parent
                self.parent.add(content, bubble_up=True)
                return
            else:
                # append at the end of the loop. This is not a simple
                # append as the last element in the loop is the "end
                # do" so we insert at the penultimate location
                BaseGen.add(self,
                            content,
                            position=["insert",
                                      len(self.root.content) - 1])
        else:
            BaseGen.add(self, content, position=position)
Beispiel #3
0
    def __init__(self, parent, language, position, directive_type, content):

        self._supported_languages = ["omp"]
        self._language = language
        self._directive_type = directive_type

        reader = FortranStringReader("! content\n")
        reader.set_mode(True, True)  # free form, strict
        subline = reader.next()

        if language == "omp":
            my_comment = OMPDirective(parent.root, subline, position,
                                      directive_type)
            my_comment.content = "$omp"
            if position == "end":
                my_comment.content += " end"
            my_comment.content += " " + directive_type
            if content != "":
                my_comment.content += " " + content
        else:
            raise RuntimeError(
                "Error, unsupported directive language. Expecting one of "
                "{0} but found '{1}'".format(str(self._supported_languages),
                                             language))

        BaseGen.__init__(self, parent, my_comment)
Beispiel #4
0
    def __init__(self, parent, content):
        reader = FortranStringReader("! content\n")
        reader.set_mode(True, True)  # free form, strict
        subline = reader.next()

        my_comment = Comment(parent.root, subline)
        my_comment.content = content

        BaseGen.__init__(self, parent, my_comment)
Beispiel #5
0
    def __init__(self, parent, clause):

        reader = FortranStringReader("if (dummy) then\nend if")
        reader.set_mode(True, True)  # free form, strict
        ifthenline = reader.next()
        endifline = reader.next()

        from fparser.block_statements import IfThen, EndIfThen
        my_if = IfThen(parent.root, ifthenline)
        my_if.expr = clause
        my_endif = EndIfThen(my_if, endifline)
        my_if.content.append(my_endif)

        BaseGen.__init__(self, parent, my_if)
Beispiel #6
0
    def __init__(self, parent, variable_name, start, end, step=None):
        reader = FortranStringReader("do i=1,n\nend do")
        reader.set_mode(True, True)  # free form, strict
        doline = reader.next()
        enddoline = reader.next()
        from fparser.block_statements import Do, EndDo
        dogen = Do(parent.root, doline)
        dogen.loopcontrol = variable_name + "=" + start + "," + end
        if step is not None:
            dogen.loopcontrol = dogen.loopcontrol + "," + step
        enddo = EndDo(dogen, enddoline)
        dogen.content.append(enddo)

        BaseGen.__init__(self, parent, dogen)
Beispiel #7
0
    def __init__(self, parent, name="", args=None):

        reader = FortranStringReader("call vanilla(vanilla_arg)")
        reader.set_mode(True, True)  # free form, strict
        myline = reader.next()

        from fparser.block_statements import Call
        self._call = Call(parent.root, myline)
        self._call.designator = name
        if args is None:
            args = []
        self._call.items = args

        BaseGen.__init__(self, parent, self._call)
Beispiel #8
0
 def __init__(self, parent, content):
     from fparser.statements import Deallocate
     reader = FortranStringReader("deallocate(dummy)")
     reader.set_mode(True, False)  # free form, strict
     myline = reader.next()
     self._decl = Deallocate(parent.root, myline)
     if isinstance(content, str):
         self._decl.items = [content]
     elif isinstance(content, list):
         self._decl.items = content
     else:
         raise RuntimeError(
             "DeallocateGen expected the content argument to be a str"
             " or a list, but found {0}".format(type(content)))
     BaseGen.__init__(self, parent, self._decl)
Beispiel #9
0
 def __init__(self, parent, name="", only=False, funcnames=None):
     reader = FortranStringReader("use kern,only : func1_kern=>func1")
     reader.set_mode(True, True)  # free form, strict
     myline = reader.next()
     root = parent.root
     from fparser.block_statements import Use
     use = Use(root, myline)
     use.name = name
     use.isonly = only
     if funcnames is None:
         funcnames = []
         use.isonly = False
     local_funcnames = funcnames[:]
     use.items = local_funcnames
     BaseGen.__init__(self, parent, use)
Beispiel #10
0
    def __init__(self, parent):

        if not isinstance(parent, ModuleGen) and not isinstance(
                parent, SubroutineGen):
            raise Exception(
                "The parent of ImplicitNoneGen must be a module or a "
                "subroutine, but found {0}".format(type(parent)))
        reader = FortranStringReader("IMPLICIT NONE\n")
        reader.set_mode(True, True)  # free form, strict
        subline = reader.next()

        from fparser.typedecl_statements import Implicit
        my_imp_none = Implicit(parent.root, subline)

        BaseGen.__init__(self, parent, my_imp_none)
Beispiel #11
0
 def __init__(self, parent, lhs="", rhs="", pointer=False):
     if pointer:
         reader = FortranStringReader("lhs=>rhs")
     else:
         reader = FortranStringReader("lhs=rhs")
     reader.set_mode(True, True)  # free form, strict
     myline = reader.next()
     if pointer:
         from fparser.statements import PointerAssignment
         self._assign = PointerAssignment(parent.root, myline)
     else:
         from fparser.statements import Assignment
         self._assign = Assignment(parent.root, myline)
     self._assign.expr = rhs
     self._assign.variable = lhs
     BaseGen.__init__(self, parent, self._assign)
Beispiel #12
0
    def __init__(self,
                 parent,
                 datatype="",
                 entity_decls=None,
                 intent="",
                 pointer=False,
                 kind="",
                 dimension="",
                 allocatable=False):
        if entity_decls is None:
            raise RuntimeError(
                "Cannot create a variable declaration without specifying the "
                "name(s) of the variable(s)")

        if datatype.lower() == "integer":
            from fparser.typedecl_statements import Integer
            reader = FortranStringReader("integer :: vanilla")
            reader.set_mode(True, False)  # free form, strict
            myline = reader.next()
            self._decl = Integer(parent.root, myline)
        elif datatype.lower() == "real":
            from fparser.typedecl_statements import Real
            reader = FortranStringReader("real :: vanilla")
            reader.set_mode(True, False)  # free form, strict
            myline = reader.next()
            self._decl = Real(parent.root, myline)
        else:
            raise RuntimeError(
                "f2pygen:DeclGen:init: Only integer and real are currently"
                " supported and you specified '{0}'".format(datatype))
        # make a copy of entity_decls as we may modify it
        local_entity_decls = entity_decls[:]
        self._decl.entity_decls = local_entity_decls
        my_attrspec = []
        if intent != "":
            my_attrspec.append("intent({0})".format(intent))
        if pointer is not False:
            my_attrspec.append("pointer")
        if allocatable is not False:
            my_attrspec.append("allocatable")
        self._decl.attrspec = my_attrspec
        if dimension != "":
            my_attrspec.append("dimension({0})".format(dimension))
        if kind is not "":
            self._decl.selector = ('', kind)
        BaseGen.__init__(self, parent, self._decl)
Beispiel #13
0
 def add(self, content, position=None):
     if position is None:
         position = ["auto"]
     if position[0] == "auto" or position[0] == "append":
         if position[0] == "auto" and bubble_up_type(content):
             # use and declaration statements cannot appear in an if
             # block so pass on (bubble-up) to parent
             self.parent.add(content, bubble_up=True)
         else:
             # append at the end of the loop. This is not a simple
             # append as the last element in the if is the "end if"
             # so we insert at the penultimate location
             BaseGen.add(self,
                         content,
                         position=["insert",
                                   len(self.root.content) - 1])
     else:
         BaseGen.add(self, content, position=position)
Beispiel #14
0
 def __init__(self, parent, expr="UNSET", typeselect=False):
     ''' construct a ... '''
     from fparser.block_statements import EndSelect
     self._typeselect = typeselect
     reader = FortranStringReader(
         "SELECT CASE (x)\nCASE (1)\nCASE DEFAULT\nEND SELECT")
     reader.set_mode(True, True)  # free form, strict
     select_line = reader.next()
     self._case_line = reader.next()
     self._case_default_line = reader.next()
     end_select_line = reader.next()
     if self._typeselect:
         select = TypeSelect(parent.root, select_line)
     else:
         select = Select(parent.root, select_line)
     endselect = EndSelect(select, end_select_line)
     select.expr = expr
     select.content.append(endselect)
     BaseGen.__init__(self, parent, select)
Beispiel #15
0
    def add(self, content, position=None, bubble_up=False):
        '''Specialise the add method to provide module and subroutine
           specific intelligent adding of use statements, implicit
           none statements and declarations if the position argument
           is set to auto (which is the default)'''

        # By default the position is 'auto'. We set it up this way for
        # safety because in python, default arguments are instantiated
        # as objects at the time of definition. If this object is
        # subsequently modified then the value of the default argument
        # is modified for subsequent calls of this routine.
        if position is None:
            position = ["auto"]

        # For an object to be added to another we require that they
        # share a common ancestor. This means that the added object must
        # have the current object or one of its ancestors as an ancestor.
        # Loop over the ancestors of this object (starting with itself)
        self_ancestor = self.root
        while self_ancestor:
            # Loop over the ancestors of the object being added
            obj_parent = content.root.parent
            while (obj_parent != self_ancestor
                   and getattr(obj_parent, 'parent', None)):
                obj_parent = obj_parent.parent
            if obj_parent == self_ancestor:
                break
            # Object being added is not an ancestor of the current
            # self_ancestor so move one level back up the tree and
            # try again
            if getattr(self_ancestor, 'parent', None):
                self_ancestor = self_ancestor.parent
            else:
                break

        if obj_parent != self_ancestor:
            raise RuntimeError(
                "Cannot add '{0}' to '{1}' because it is not a descendant "
                "of it or of any of its ancestors.".format(
                    str(content), str(self)))

        if bubble_up:
            # If content has been passed on (is being bubbled up) then change
            # its parent to be this object
            content.root.parent = self.root

        import fparser
        if position[0] != "auto":
            # position[0] is not 'auto' so the baseclass can deal with it
            BaseGen.add(self, content, position)
        else:
            # position[0] == "auto" so insert in a context sensitive way
            if isinstance(content, DeclGen) or \
               isinstance(content, TypeDeclGen):

                if isinstance(content, DeclGen):
                    # have I already been declared?
                    for child in self._children:
                        if isinstance(child, DeclGen):
                            # is this declaration the same type as me?
                            if child.root.name == content.root.name:
                                # we are modifying the list so we need
                                # to iterate over a copy
                                for var_name in content.root.entity_decls[:]:
                                    for child_name in child.root.entity_decls:
                                        if var_name.lower() == \
                                           child_name.lower():
                                            content.root.entity_decls.\
                                                remove(var_name)
                                            if not content.root.entity_decls:
                                                # return as all variables in
                                                # this declaration already
                                                # exist
                                                return
                if isinstance(content, TypeDeclGen):
                    # have I already been declared?
                    for child in self._children:
                        if isinstance(child, TypeDeclGen):
                            # is this declaration the same type as me?
                            if child.root.selector[1] == \
                               content.root.selector[1]:
                                # we are modifying the list so we need
                                # to iterate over a copy
                                for var_name in content.root.entity_decls[:]:
                                    for child_name in child.root.entity_decls:
                                        if var_name.lower() == \
                                           child_name.lower():
                                            content.root.entity_decls.\
                                                remove(var_name)
                                            if not content.root.entity_decls:
                                                # return as all variables in
                                                # this declaration already
                                                # exist
                                                return

                index = 0
                # skip over any use statements
                index = self._skip_use_and_comments(index)
                # skip over implicit none if it exists
                index = self._skip_imp_none_and_comments(index)
                # skip over any declarations which have an intent
                try:
                    intent = True
                    while intent:
                        intent = False
                        for attr in self.root.content[index].attrspec:
                            if attr.find("intent") == 0:
                                intent = True
                                index += 1
                                break
                except AttributeError:
                    pass
            elif isinstance(content.root, fparser.statements.Use):
                # have I already been declared?
                for child in self._children:
                    if isinstance(child, UseGen):
                        if child.root.name == content.root.name:
                            # found an existing use with the same name
                            if not child.root.isonly and not \
                               content.root.isonly:
                                # both are generic use statements so
                                # skip this declaration
                                return
                            if child.root.isonly and not content.root.isonly:
                                # new use is generic and existing use
                                # is specific so we can safely add
                                pass
                            if not child.root.isonly and content.root.isonly:
                                # existing use is generic and new use
                                # is specific so we can skip this
                                # declaration
                                return
                            if child.root.isonly and content.root.isonly:
                                # we are modifying the list so we need
                                # to iterate over a copy
                                for new_name in content.root.items[:]:
                                    for existing_name in child.root.items:
                                        if existing_name.lower() == \
                                           new_name.lower():
                                            content.root.items.remove(new_name)
                                            if not content.root.items:
                                                return
                index = 0
            elif isinstance(content, ImplicitNoneGen):
                # does implicit none already exist?
                for child in self._children:
                    if isinstance(child, ImplicitNoneGen):
                        return
                # skip over any use statements
                index = 0
                index = self._skip_use_and_comments(index)
            else:
                index = len(self.root.content) - 1
            self.root.content.insert(index, content.root)
            self._children.append(content)
Beispiel #16
0
 def __init__(self, parent, sub):
     BaseGen.__init__(self, parent, sub)