Esempio n. 1
0
    def __init__(self, parent, expr="UNSET", typeselect=False):
        '''
        Construct a SelectionGen for creating a SELECT block

        :param parent: node to which to add this select block as a child
        :type parent: :py:class:`psyclone.f2pygen.BaseGen`
        :param str expr: the CASE expression
        :param bool typeselect: whether or not this is a SELECT TYPE rather
                                than a SELECT CASE
        '''
        self._typeselect = typeselect
        reader = FortranStringReader(
            "SELECT CASE (x)\nCASE (1)\nCASE DEFAULT\nEND SELECT")
        reader.set_format(FortranFormat(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 = SelectType(parent.root, select_line)
        else:
            select = SelectCase(parent.root, select_line)
        endselect = EndSelect(select, end_select_line)
        select.expr = expr
        select.content.append(endselect)
        BaseGen.__init__(self, parent, select)
Esempio n. 2
0
    def __init__(self, parent, name="", args=None, implicitnone=False):
        '''
        :param parent: node in AST to which to add Subroutine as a child
        :type parent: :py:class:`psyclone.f2pygen.BaseGen`
        :param str name: name of the Fortran subroutine
        :param list args: list of arguments accepted by the subroutine
        :param bool implicitnone: whether or not we should specify
                                  "implicit none" for the body of this
                                  subroutine
        '''
        reader = FortranStringReader(
            "subroutine vanilla(vanilla_arg)\nend subroutine")
        reader.set_format(FortranFormat(True, True))  # free form, strict
        subline = reader.next()
        endsubline = reader.next()

        from fparser.one.block_statements import Subroutine, EndSubroutine
        self._sub = Subroutine(parent.root, subline)
        self._sub.name = name
        if args is None:
            args = []
        self._sub.args = args
        endsub = EndSubroutine(self._sub, endsubline)
        self._sub.content.append(endsub)
        ProgUnitGen.__init__(self, parent, self._sub)
        if implicitnone:
            self.add(ImplicitNoneGen(self))
Esempio n. 3
0
def test_multi_stmt_line1():
    '''Check that simple statements separated by ; on a single line are
    correctly split into multiple lines by FortranReaderBase

    '''
    code = "do i=1,10;b=20 ; c=30"
    reader = FortranStringReader(code)
    mode = FortranFormat(True, False)
    reader.set_format(mode)
    line1 = reader.next()
    assert isinstance(line1, Line)
    assert line1.line == "do i=1,10"
    assert line1.span == (1, 1)
    assert line1.label is None
    assert line1.name is None
    assert line1.reader is reader
    line2 = reader.next()
    assert isinstance(line2, Line)
    assert line2.line == "b=20"
    assert line2.span is line1.span
    assert line2.label is None
    assert line2.name is None
    assert line2.reader is reader
    line3 = reader.next()
    assert isinstance(line3, Line)
    assert line3.line == "c=30"
    assert line3.span is line1.span
    assert line3.label is None
    assert line3.name is None
    assert line3.reader is reader
Esempio n. 4
0
    def __init__(self, parent, datatype="", entity_decls=None, intent="",
                 pointer=False, kind="", dimension="", allocatable=False):
        '''
        :param parent: node to which to add this declaration as a child
        :type parent: :py:class:`psyclone.f2pygen.BaseGen`
        :param str datatype: the (intrinsic) type for this declaration
        :param list entity_decls: list of variable names to declare
        :param str intent: the INTENT attribute of this declaration
        :param bool pointer: whether or not this is a pointer declaration
        :param str kind: the KIND attribute to use for this declaration
        :param str dimension: the DIMENSION specifier (i.e. the xx in
                              DIMENSION(xx))
        :param bool allocatable: whether this declaration is for an
                                 ALLOCATABLE quantity

        :raises RuntimeError: if no variable names are specified
        :raises RuntimeError: if datatype is not one of "integer" or "real"
        '''
        if entity_decls is None:
            raise RuntimeError(
                "Cannot create a variable declaration without specifying the "
                "name(s) of the variable(s)")
        fort_fmt = FortranFormat(True, False)  # free form, strict
        if datatype.lower() == "integer":
            reader = FortranStringReader("integer :: vanilla")
            reader.set_format(fort_fmt)
            myline = reader.next()
            self._decl = fparser1.typedecl_statements.Integer(parent.root,
                                                              myline)
        elif datatype.lower() == "real":
            reader = FortranStringReader("real :: vanilla")
            reader.set_format(fort_fmt)
            myline = reader.next()
            self._decl = fparser1.typedecl_statements.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)
Esempio n. 5
0
def adduse(name, parent, only=False, funcnames=None):
    '''
    Adds a use statement with the specified name to the supplied object.
    This routine is required when modifying an existing AST (e.g. when
    modifying a kernel). The classes are used when creating an AST from
    scratch (for the PSy layer).

    :param str name: name of module to USE
    :param parent: node in fparser1 AST to which to add this USE as a child
    :type parent: :py:class:`fparser.one.block_statements.*`
    :param bool only: whether this USE has an "ONLY" clause
    :param list funcnames: list of quantities to follow the "ONLY" clause

    :returns: an fparser1 Use object
    :rtype: :py:class:`fparser.one.block_statements.Use`
    '''
    reader = FortranStringReader("use kern,only : func1_kern=>func1")
    reader.set_format(FortranFormat(True, True))  # free form, strict
    myline = reader.next()

    # find an appropriate place to add in our use statement
    while not (isinstance(parent, fparser1.block_statements.Program) or
               isinstance(parent, fparser1.block_statements.Module) or
               isinstance(parent, fparser1.block_statements.Subroutine)):
        parent = parent.parent
    use = fparser1.block_statements.Use(parent, myline)
    use.name = name
    use.isonly = only
    if funcnames is None:
        funcnames = []
        use.isonly = False
    use.items = funcnames

    parent.content.insert(0, use)
    return use
Esempio n. 6
0
    def __init__(self, parent, clause):
        '''
        :param parent: Node to which to add this IfThen as a child
        :type parent: :py:class:`psyclone.f2pygen.BaseGen`
        :param str clause: the condition, xx, to evaluate in the if(xx)then
        '''
        reader = FortranStringReader("if (dummy) then\nend if")
        reader.set_format(FortranFormat(True, True))  # free form, strict
        ifthenline = reader.next()
        endifline = reader.next()

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

        BaseGen.__init__(self, parent, my_if)
Esempio n. 7
0
def test_include_not_found():
    '''Tests that FortranReaderBase.next() provides the include line when
    the included file is not found.

    '''
    code = "include 'nonexistant.f90'"
    unit_under_test = FortranStringReader(code)
    line = unit_under_test.next()
    assert str(line.line) == code
Esempio n. 8
0
    def __init__(self, parent, variable_name, start, end, step=None):
        '''
        :param parent: the node to which to add this do loop as a child
        :type parent: :py:class:`psyclone.f2pygen.BaseGen`
        :param str variable_name: the name of the loop variable
        :param str start: start value for Do loop
        :param str end: upper-limit of Do loop
        :param str step: increment to use in Do loop
        '''
        reader = FortranStringReader("do i=1,n\nend do")
        reader.set_format(FortranFormat(True, True))  # free form, strict
        doline = reader.next()
        enddoline = reader.next()
        dogen = fparser1.block_statements.Do(parent.root, doline)
        dogen.loopcontrol = variable_name + "=" + start + "," + end
        if step is not None:
            dogen.loopcontrol = dogen.loopcontrol + "," + step
        enddo = fparser1.block_statements.EndDo(dogen, enddoline)
        dogen.content.append(enddo)

        BaseGen.__init__(self, parent, dogen)
Esempio n. 9
0
def test_multi_stmt_line3():
    '''Check that named do loops separated by ; on a single line are correctly
    split into multiple lines by FortranReaderBase

    '''
    code = "name:do i=1,10;name2 : do j=1,10"
    reader = FortranStringReader(code)
    mode = FortranFormat(True, False)
    reader.set_format(mode)
    line1 = reader.next()
    assert isinstance(line1, Line)
    assert line1.line == "do i=1,10"
    assert line1.span == (1, 1)
    assert line1.label is None
    assert line1.name == "name"
    assert line1.reader is reader
    line2 = reader.next()
    assert line2.line == "do j=1,10"
    assert line2.span is line1.span
    assert line2.label is None
    assert line2.name == "name2"
    assert line2.reader is reader
Esempio n. 10
0
def test_multi_stmt_line2():
    '''Check that format statements separated by ; on a single line are
    correctly split into multiple lines by FortranReaderBase

    '''
    code = "10 format(a); 20 format(b)"
    reader = FortranStringReader(code)
    mode = FortranFormat(True, False)
    reader.set_format(mode)
    line1 = reader.next()
    assert isinstance(line1, Line)
    assert line1.line == "format(a)"
    assert line1.span == (1, 1)
    assert line1.label == 10
    assert line1.name is None
    assert line1.reader is reader
    line2 = reader.next()
    assert line2.line == "format(b)"
    assert line2.span is line1.span
    assert line2.label == 20
    assert line2.name is None
    assert line2.reader is reader
Esempio n. 11
0
    def __init__(self, parent, content):
        '''
        :param parent: node in AST to which to add the Comment as a child
        :type parent: :py:class:`psyclone.f2pygen.BaseGen`
        :param str content: the content of the comment
        '''
        reader = FortranStringReader("! content\n")
        reader.set_format(FortranFormat(True, True))  # free form, strict
        subline = reader.next()

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

        BaseGen.__init__(self, parent, my_comment)
Esempio n. 12
0
    def __init__(self, parent, name="", args=None):
        '''
        :param parent: node in AST to which to add CallGen as a child
        :type parent: :py:class:`psyclone.f2pygen.BaseGen`
        :param str name: the name of the routine to call
        :param list args: list of arguments to pass to the call
        '''
        reader = FortranStringReader("call vanilla(vanilla_arg)")
        reader.set_format(FortranFormat(True, True))  # free form, strict
        myline = reader.next()

        from fparser.one.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)
Esempio n. 13
0
def test_base_next_good_include(log):
    '''
    Tests that FortranReaderBase.next() causes a message to be logged when a
    file is included.
    '''
    code = "include 'modfile.f95'\nx=2"
    include_directories = [os.path.dirname(__file__)]
    unit_under_test = FortranStringReader(
        code, include_dirs=include_directories, ignore_comments=False)
    line = unit_under_test.next()
    assert str(line)[:19] == "Comment('! Modified"  # First line of inclusion
    assert log.messages['debug'] == []
    assert log.messages['error'] == []
    assert log.messages['warning'] == []
    assert log.messages['critical'] == []
    expected = "    1:include 'modfile.f95' " \
               + "<== including file '{path}/modfile.f95'"
    result = log.messages['info'][0].split('\n')[1]
    assert re.sub("u", "", result) == \
        re.sub("u", "", expected.format(path=include_directories[0]))
Esempio n. 14
0
    def __init__(self, parent):
        '''
        :param parent: node in AST to which to add 'implicit none' as a child
        :type parent: :py:class:`psyclone.f2pygen.ModuleGen` or
                      :py:class:`psyclone.f2pygen.SubroutineGen`

        :raises Exception: if `parent` is not a ModuleGen or SubroutineGen
        '''
        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_format(FortranFormat(True, True))  # free form, strict
        subline = reader.next()

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

        BaseGen.__init__(self, parent, my_imp_none)
Esempio n. 15
0
 def __init__(self, parent, lhs="", rhs="", pointer=False):
     '''
     :param parent: the node to which to add this assignment as a child
     :type parent: :py:class:`psyclone.f2pygen.BaseGen`
     :param str lhs: the LHS of the assignment expression
     :param str rhs: the RHS of the assignment expression
     :param bool pointer: whether or not this is a pointer assignment
     '''
     if pointer:
         reader = FortranStringReader("lhs=>rhs")
     else:
         reader = FortranStringReader("lhs=rhs")
     reader.set_format(FortranFormat(True, True))  # free form, strict
     myline = reader.next()
     if pointer:
         self._assign = fparser1.statements.PointerAssignment(parent.root,
                                                              myline)
     else:
         self._assign = fparser1.statements.Assignment(parent.root, myline)
     self._assign.expr = rhs
     self._assign.variable = lhs
     BaseGen.__init__(self, parent, self._assign)
Esempio n. 16
0
    def __init__(self, parent, content):
        '''
        :param parent: node to which to add this DEALLOCATE as a child
        :type parent: :py:class:`psyclone.f2pygen.BaseGen`
        :param content: string or list of variables to deallocate
        :type content: list of strings or a single string

        :raises RuntimeError: if `content` is not of correct type
        '''
        reader = FortranStringReader("deallocate(dummy)")
        reader.set_format(FortranFormat(True, False))  # free form, strict
        myline = reader.next()
        self._decl = fparser1.statements.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)
Esempio n. 17
0
 def __init__(self, parent, name="", only=False, funcnames=None):
     '''
     :param parent: node in AST to which to add UseGen as a child
     :type parent: :py:class:`psyclone.f2pygen.BaseGen`
     :param str name: name of the module to USE
     :param bool only: whether this USE has an ONLY clause
     :param list funcnames: list of names to follow ONLY clause
     '''
     reader = FortranStringReader("use kern,only : func1_kern=>func1")
     reader.set_format(FortranFormat(True, True))  # free form, strict
     myline = reader.next()
     root = parent.root
     from fparser.one.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)
Esempio n. 18
0
    def __init__(self, parent, language, position, directive_type, content):
        '''
        :param parent: node in AST to which to add directive as a child
        :type parent: :py:class:`psyclone.f2pygen.BaseGen`
        :param str language: the type of directive (e.g. OMP or ACC)
        :param str position: "end" if this is the end of a directive block
        :param str directive_type: the directive itself (e.g. "PARALLEL DO")
        :param str content: any additional arguments to add to the directive
                            (e.g. "PRIVATE(ji)")

        :raises RuntimeError: if an unrecognised directive language is
                              specified
        '''
        self._supported_languages = ["omp"]
        self._language = language
        self._directive_type = directive_type

        reader = FortranStringReader("! content\n")
        reader.set_format(FortranFormat(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)
Esempio n. 19
0
    def __init__(self, parent, datatype="", entity_decls=None, intent="",
                 pointer=False, attrspec=None):
        '''
        :param parent: the node to which to add this type delcn as a child
        :type parent: :py:class:`psyclone.f2pygen.BaseGen`
        :param str datatype: the derived type
        :param list entity_decls: List of variable names to declare
        :param str intent: the intent attribute for the declaration
        :param bool pointer: whether or not this is a pointer declaration
        :param attrspec: list of other attributes to add to declaration

        :raises RuntimeError: if no variable names are specified
        '''
        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_format(FortranFormat(True, False))  # free form, strict
        myline = reader.next()

        self._typedecl = fparser1.typedecl_statements.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)