Beispiel #1
0
def test_if_content():
    ''' Check that the content of an if gets created successfully. '''
    module = ModuleGen(name="testmodule")
    clause = "a < b"
    if_statement = IfThenGen(module, clause)
    if_statement.add(CommentGen(if_statement, "HELLO"))
    module.add(if_statement)
    lines = str(module.root).splitlines()
    assert "IF (" + clause + ") THEN" in lines[3]
    assert "!HELLO" in lines[4]
    assert "END IF" in lines[5]
Beispiel #2
0
def test_basegen_previous_loop_no_loop():
    '''Check that we raise an error when requesting the position of the
    previous loop if we don't have a loop '''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    # Request the position of the last loop
    # even though we haven't got one
    with pytest.raises(RuntimeError) as err:
        sub.previous_loop()
    assert "no loop found - there is no previous loop" in str(err)
Beispiel #3
0
def test_basegen_last_declaration_no_vars():
    '''Check that we raise an error when requesting the position of the
    last variable declaration if we don't have any variables'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    # Request the position of the last variable declaration
    # even though we haven't got any
    with pytest.raises(RuntimeError) as err:
        sub.last_declaration()
    assert "no variable declarations found" in str(err)
Beispiel #4
0
def test_basegen_append_default():
    ''' Check if no position argument is supplied to BaseGen.add() then it
    defaults to appending '''
    from psyclone.f2pygen import BaseGen
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    BaseGen.add(sub, DeclGen(sub, datatype="integer", entity_decls=["var1"]))
    BaseGen.add(sub, CommentGen(sub, " hello"))
    cindex = line_number(sub.root, "hello")
    assert cindex == 3
Beispiel #5
0
def test_imp_none_in_module():
    ''' test that implicit none can be added to a module in the
    correct location'''
    module = ModuleGen(name="testmodule", implicitnone=False)
    module.add(ImplicitNoneGen(module))
    in_idx = line_number(module.root, "IMPLICIT NONE")
    cont_idx = line_number(module.root, "CONTAINS")
    assert in_idx > -1, "IMPLICIT NONE not found"
    assert cont_idx > -1, "CONTAINS not found"
    assert cont_idx - in_idx == 1, "CONTAINS is not on the line after" +\
        " IMPLICIT NONE"
Beispiel #6
0
def test_imp_none_in_subroutine_with_decs():
    ''' test that implicit none is added before any declaration
    statements in a subroutine when auto (the default) is used for
    insertion '''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sub.add(DeclGen(sub, datatype="integer", entity_decls=["var1"]))
    sub.add(TypeDeclGen(sub, datatype="my_type", entity_decls=["type1"]))
    sub.add(ImplicitNoneGen(module))
    in_idx = line_number(sub.root, "IMPLICIT NONE")
    assert in_idx == 1
Beispiel #7
0
def test_progunitgen_multiple_use2():
    '''Check that we correctly handle the case where the same module
    appears in two use statements but, because the first use is
    specific, the second, generic use is included.

    '''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sub.add(UseGen(sub, name="fred", only=True, funcnames=["astaire"]))
    sub.add(UseGen(sub, name="fred"))
    assert count_lines(sub.root, "USE fred") == 2
Beispiel #8
0
def test_adduse_empty_only():
    ''' Test that the adduse module method works correctly when we specify
    that we want it to be specific but then don't provide a list of
    entities for the only qualifier '''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    from psyclone.f2pygen import adduse
    # Add a use statement with only=True but an empty list of entities
    adduse("fred", sub.root, only=True, funcnames=[])
    assert count_lines(sub.root, "USE fred") == 1
    assert count_lines(sub.root, "USE fred, only") == 0
Beispiel #9
0
def test_basegen_after_index():
    '''Check that we can insert an object using "after_index"'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sub.add(DeclGen(sub, datatype="integer", entity_decls=["var1"]))
    sub.add(DeclGen(sub, datatype="integer", entity_decls=["var2"]))
    sub.add(CommentGen(sub, " hello"), position=["after_index", 1])
    # The code checked by line_number() *includes* the SUBROUTINE
    # statement (which is obviously not a child of the SubroutineGen
    # object) and therefore the index it returns is 1 greater than we
    # might expect.
    assert line_number(sub.root, "hello") == 3
Beispiel #10
0
def test_basegen_start_parent_loop_no_loop_dbg():
    '''Check the debug option to the start_parent_loop method when we have
    no loop'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    dgen = DirectiveGen(sub, "omp", "end", "do", "")
    sub.add(dgen)
    call = CallGen(sub, name="testcall", args=["a", "b"])
    sub.add(call)
    with pytest.raises(RuntimeError) as err:
        call.start_parent_loop(debug=True)
    assert "This node has no enclosing Do loop" in str(err)
Beispiel #11
0
def test_adduse_default_funcnames():
    ''' Test that the adduse module method works correctly when we do
    not specify a list of funcnames '''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    call = CallGen(sub, name="testcall", args=["a", "b"])
    sub.add(call)
    from psyclone.f2pygen import adduse
    adduse("fred", call.root)
    gen = str(sub.root)
    expected = ("    SUBROUTINE testsubroutine()\n" "      USE fred\n")
    assert expected in gen
Beispiel #12
0
def test_deallocate_arg_list():
    '''check that a deallocate gets created succesfully with content
    being a list.'''
    module = ModuleGen(name="testmodule")
    content = ["and", "now", "the", "end", "is", "near"]
    content_str = ""
    for idx, name in enumerate(content):
        content_str += name
        if idx + 1 < len(content):
            content_str += ", "
    deallocate = DeallocateGen(module, content)
    module.add(deallocate)
    lines = str(module.root).splitlines()
    assert "DEALLOCATE (" + content_str + ")" in lines[3]
Beispiel #13
0
def test_allocate_arg_list():
    '''check that an allocate gets created succesfully with content being
    a list.'''
    module = ModuleGen(name="testmodule")
    content = ["hello", "how", "are", "you"]
    content_str = ""
    for idx, name in enumerate(content):
        content_str += name
        if idx + 1 < len(content):
            content_str += ", "
    allocate = AllocateGen(module, content)
    module.add(allocate)
    lines = str(module.root).splitlines()
    assert "ALLOCATE (" + content_str + ")" in lines[3]
Beispiel #14
0
def test_if_add_use():
    ''' Check that IfThenGen.add() correctly handles the case
    when it is passed a UseGen object '''
    module = ModuleGen(name="testmodule")
    clause = "a < b"
    if_statement = IfThenGen(module, clause)
    if_statement.add(CommentGen(if_statement, "GOODBYE"))
    if_statement.add(UseGen(if_statement, name="dibna"))
    module.add(if_statement)
    print str(module.root)
    use_line = line_number(module.root, "USE dibna")
    if_line = line_number(module.root, "IF (" + clause + ") THEN")
    # The use statement must come before the if..then block
    assert use_line < if_line
Beispiel #15
0
def test_imp_none_in_module_with_use_and_decs_and_comments():
    ''' test that implicit none is added after any use statements
    and before any declarations in a module in the presence of
    comments when auto (the default) is used for insertion'''
    module = ModuleGen(name="testmodule", implicitnone=False)
    module.add(DeclGen(module, datatype="integer", entity_decls=["var1"]))
    module.add(TypeDeclGen(module, datatype="my_type", entity_decls=["type1"]))
    module.add(UseGen(module, "fred"))
    for idx in [0, 1, 2, 3]:
        module.add(CommentGen(module, " hello " + str(idx)),
                   position=["before_index", 2 * idx])
    module.add(ImplicitNoneGen(module))
    in_idx = line_number(module.root, "IMPLICIT NONE")
    assert in_idx == 3
Beispiel #16
0
def test_adduse():
    ''' Test that the adduse module method works correctly when we use a
    call object as our starting point '''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    call = CallGen(sub, name="testcall", args=["a", "b"])
    sub.add(call)
    from psyclone.f2pygen import adduse
    adduse("fred", call.root, only=True, funcnames=["astaire"])
    gen = str(sub.root)
    expected = ("    SUBROUTINE testsubroutine()\n"
                "      USE fred, ONLY: astaire\n")
    assert expected in gen
Beispiel #17
0
def test_basegen_before_error():
    '''Check that we raise an error when attempting to insert an object
    before another object that is not present in the tree'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sub.add(DeclGen(sub, datatype="integer", entity_decls=["var1"]))
    sub.add(DeclGen(sub, datatype="integer", entity_decls=["var2"]))
    # Create an object but do not add it as a child of sub
    dgen = DeclGen(sub, datatype="real", entity_decls=["rvar1"])
    # Try to add an object before the orphan dgen
    with pytest.raises(RuntimeError) as err:
        sub.add(CommentGen(sub, " hello"), position=["before", dgen])
    assert "Failed to find supplied object" in str(err)
Beispiel #18
0
def test_typeselectiongen():
    ''' Check that SelectionGen works as expected for a type '''
    from psyclone.f2pygen import SelectionGen
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sgen = SelectionGen(sub, expr="my_var=>another_var", typeselect=True)
    sub.add(sgen)
    agen = AssignGen(sgen, lhs="happy", rhs=".TRUE.")
    sgen.addcase("fspace", [agen])
    sgen.adddefault()
    gen = str(sub.root)
    print gen
    assert "SELECT TYPE ( my_var=>another_var )" in gen
    assert "TYPE IS ( fspace )" in gen
Beispiel #19
0
def test_do_loop_add_after():
    ''' Test that we correctly generate code for a do loop when adding a
    child to it with position *after* '''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsub")
    module.add(sub)
    dogen = DoGen(sub, "it", "1", "10", step="2")
    sub.add(dogen)
    assign1 = AssignGen(dogen, lhs="happy", rhs=".TRUE.")
    dogen.add(assign1)
    assign2 = AssignGen(dogen, lhs="sad", rhs=".FALSE.")
    dogen.add(assign2, position=["before", assign1.root])
    a1_line = line_number(sub.root, "happy = ")
    a2_line = line_number(sub.root, "sad = ")
    assert a1_line > a2_line
Beispiel #20
0
def test_subroutine_var_with_implicit_none():
    ''' test that a variable is added after an implicit none
    statement in a subroutine'''
    module = ModuleGen(name="testmodule")
    subroutine = SubroutineGen(module,
                               name="testsubroutine",
                               implicitnone=True)
    module.add(subroutine)
    subroutine.add(
        DeclGen(subroutine, datatype="integer", entity_decls=["var1"]))
    idx_var = line_number(subroutine.root, "INTEGER var1")
    idx_imp_none = line_number(subroutine.root, "IMPLICIT NONE")
    print str(module.root)
    assert idx_var - idx_imp_none == 1, \
        "variable declation must be after implicit none"
Beispiel #21
0
def test_add_before():
    ''' add the new code before a particular object '''
    module = ModuleGen(name="testmodule")
    subroutine = SubroutineGen(module, name="testsubroutine")
    module.add(subroutine)
    loop = DoGen(subroutine, "it", "1", "10")
    subroutine.add(loop)
    call = CallGen(subroutine, "testcall")
    subroutine.add(call, position=["before", loop.root])
    lines = str(module.root).splitlines()
    # the call should be inserted before the loop
    print lines
    assert "SUBROUTINE testsubroutine" in lines[3]
    assert "CALL testcall" in lines[4]
    assert "DO it=1,10" in lines[5]
Beispiel #22
0
def test_selectiongen_addcase():
    ''' Check that SelectionGen.addcase() works as expected when no
    content is supplied'''
    from psyclone.f2pygen import SelectionGen
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sgen = SelectionGen(sub, expr="my_var")
    sub.add(sgen)
    sgen.addcase("1")
    gen = str(sub.root)
    print gen
    expected = ("      SELECT CASE ( my_var )\n"
                "        CASE ( 1 )\n"
                "      END SELECT")
    assert expected in gen
Beispiel #23
0
def test_if_with_position_append():
    ''' Check that IfThenGen.add() correctly uses the position
    argument when *append* is specified. '''
    module = ModuleGen(name="testmodule")
    clause = "a < b"
    if_statement = IfThenGen(module, clause)
    com1 = CommentGen(if_statement, "HELLO")
    if_statement.add(com1)
    if_statement.add(CommentGen(if_statement, "GOODBYE"), position=["append"])
    module.add(if_statement)
    print str(module.root)
    lines = str(module.root).splitlines()
    assert "IF (" + clause + ") THEN" in lines[3]
    assert "!HELLO" in lines[4]
    assert "!GOODBYE" in lines[5]
    assert "END IF" in lines[6]
Beispiel #24
0
    def gen(self):
        '''
        Generate PSy code for the Dynamo0.1 api.

        :rtype: ast

        '''
        from psyclone.f2pygen import ModuleGen, UseGen

        # create an empty PSy layer module
        psy_module = ModuleGen(self.name)
        # include the lfric module
        lfric_use = UseGen(psy_module, name="lfric")
        psy_module.add(lfric_use)
        # add all invoke specific information
        self.invokes.gen_code(psy_module)
        return psy_module.root
Beispiel #25
0
def test_imp_none_in_module_with_use_and_decs():
    ''' test that implicit none is added after any use statements
    and before any declarations in a module when auto (the
    default) is used for insertion'''
    module = ModuleGen(name="testmodule", implicitnone=False)
    module.add(DeclGen(module, datatype="integer", entity_decls=["var1"]))
    module.add(TypeDeclGen(module, datatype="my_type", entity_decls=["type1"]))
    module.add(UseGen(module, "fred"))
    module.add(ImplicitNoneGen(module))
    in_idx = line_number(module.root, "IMPLICIT NONE")
    assert in_idx == 2
Beispiel #26
0
def test_progunit_multiple_use3():
    '''Check that we correctly handle the case where the same module is
    specified in two UseGen objects statements both of which are
    specific and they have overlapping variable names.

    '''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    funcnames = ["a", "b", "c"]
    sub.add(UseGen(sub, name="fred", only=True, funcnames=funcnames))
    funcnames = ["c", "d"]
    sub.add(UseGen(sub, name="fred", only=True, funcnames=funcnames))
    gen = str(sub.root)
    expected = ("      USE fred, ONLY: d\n" "      USE fred, ONLY: a, b, c")
    assert expected in gen
    assert count_lines(sub.root, "USE fred") == 2
    # ensure that the input list does not get modified
    assert funcnames == ["c", "d"]
Beispiel #27
0
def test_subroutine_var_intent_in_with_directive():
    ''' test that a variable declared as intent in is added before
    a directive in a subroutine'''
    module = ModuleGen(name="testmodule")
    subroutine = SubroutineGen(module,
                               name="testsubroutine",
                               implicitnone=False)
    module.add(subroutine)
    subroutine.add(DirectiveGen(subroutine, "omp", "begin", "parallel", ""))
    subroutine.add(
        DeclGen(subroutine,
                datatype="integer",
                intent="in",
                entity_decls=["var1"]))
    idx_par = line_number(subroutine.root, "!$omp parallel")
    idx_var = line_number(subroutine.root, "INTEGER, intent(in) :: var1")
    print str(module.root)
    assert idx_par - idx_var == 1, \
        "variable declaration must be before directive"
Beispiel #28
0
def test_declgen_multiple_use2():
    '''Check that we don't correctly handle the case where data of a
    different type has already been delared. '''

    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    # first declaration
    datanames = ["data1"]
    sub.add(DeclGen(sub, datatype="real", entity_decls=datanames))
    gen = str(sub.root)
    # second declaration
    datanames = ["data1", "data2"]
    sub.add(DeclGen(sub, datatype="integer", entity_decls=datanames))
    gen = str(sub.root)
    print gen
    expected = ("      INTEGER data1, data2\n" "      REAL data1")
    assert expected in gen
    # check input data is not modified
    assert datanames == ["data1", "data2"]
Beispiel #29
0
def test_typedeclgen_multiple_use():
    '''Check that we correctly handle the case where data of the same type
    has already been declared. '''

    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    # first declaration
    datanames = ["type1"]
    sub.add(TypeDeclGen(sub, datatype="my_type", entity_decls=datanames))
    gen = str(sub.root)
    # second declaration
    datanames = ["type1", "type2"]
    sub.add(TypeDeclGen(sub, datatype="my_type", entity_decls=datanames))
    gen = str(sub.root)
    print gen
    expected = ("      TYPE(my_type) type2\n" "      TYPE(my_type) type1")
    assert expected in gen
    # check input data is not modified
    assert datanames == ["type1", "type2"]
Beispiel #30
0
def test_basegen_start_parent_loop_dbg(capsys):
    '''Check the debug option to the start_parent_loop method'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    loop = DoGen(sub, "it", "1", "10")
    sub.add(loop)
    call = CallGen(loop, "testcall")
    loop.add(call)
    call.start_parent_loop(debug=True)
    out, _ = capsys.readouterr()
    print out
    expected = ("Parent is a do loop so moving to the parent\n"
                "The type of the current node is now <class "
                "'fparser.one.block_statements.Do'>\n"
                "The type of parent is <class "
                "'fparser.one.block_statements.Subroutine'>\n"
                "Finding the loops position in its parent ...\n"
                "The loop's index is  0\n")
    assert expected in out