コード例 #1
0
def test_imp_none_in_subroutine():
    ''' test that implicit none can be added to a subroutine '''
    module = ModuleGen(name="testmodule")
    subroutine = SubroutineGen(module, name="testsubroutine")
    module.add(subroutine)
    subroutine.add(ImplicitNoneGen(subroutine))
    assert 'IMPLICIT NONE' in str(subroutine.root)
コード例 #2
0
def test_basegen_start_parent_loop_omp_end_dbg(capsys):
    '''Check the debug option to the start_parent_loop method when we have
    an OpenMP end directive'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    dgen = DirectiveGen(sub, "omp", "end", "do", "")
    sub.add(dgen)
    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.block_statements.Do'>\n"
                "The type of parent is <class "
                "'fparser.block_statements.Subroutine'>\n"
                "Finding the loops position in its parent ...\n"
                "The loop's index is  1\n"
                "The type of the object at the index is <class "
                "'fparser.block_statements.Do'>\n"
                "If preceding node is a directive then move back one\n"
                "preceding node is a directive so find out what type ...\n")

    assert expected in out
コード例 #3
0
def test_progunitgen_multiple_use1():
    '''Check that we correctly handle the case where duplicate use statements
    are added but one is specific'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sub.add(UseGen(sub, name="fred"))
    sub.add(UseGen(sub, name="fred", only=True, funcnames=["astaire"]))
    assert count_lines(sub.root, "USE fred") == 1
コード例 #4
0
def test_progunitgen_multiple_generic_use():
    '''Check that we correctly handle the case where duplicate use statements
    are added'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sub.add(UseGen(sub, name="fred"))
    sub.add(UseGen(sub, name="fred"))
    assert count_lines(sub.root, "USE fred") == 1
コード例 #5
0
def test_do_loop_with_increment():
    ''' Test that we correctly generate code for a do loop with
    non-unit increment '''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsub")
    module.add(sub)
    dogen = DoGen(sub, "it", "1", "10", step="2")
    sub.add(dogen)
    count = count_lines(sub.root, "DO it=1,10,2")
    assert count == 1
コード例 #6
0
def test_imp_none_in_subroutine_already_exists():
    ''' test that implicit none is not added to a subroutine when
    one already exists'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine", implicitnone=True)
    module.add(sub)
    sub.add(ImplicitNoneGen(sub))
    count = count_lines(sub.root, "IMPLICIT NONE")
    assert count == 1, \
        "There should only be one instance of IMPLICIT NONE"
コード例 #7
0
def test_imp_none_exception_if_wrong_parent():
    ''' test that an exception is thrown if implicit none is added
    and the parent is not a module or a subroutine '''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    dogen = DoGen(sub, "i", "1", "10")
    sub.add(dogen)
    with pytest.raises(Exception):
        dogen.add(ImplicitNoneGen(dogen))
コード例 #8
0
def test_basegen_first():
    '''Check that we can insert an object as the first child'''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sub.add(DeclGen(sub, datatype="integer",
                    entity_decls=["var1"]))
    sub.add(CommentGen(sub, " hello"), position=["first"])
    cindex = line_number(sub.root, "hello")
    assert cindex == 1
コード例 #9
0
def test_basegen_append():
    '''Check that we can append an object to 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(CommentGen(sub, " hello"), position=["append"])
    cindex = line_number(sub.root, "hello")
    assert cindex == 3
コード例 #10
0
def test_typedeclgen_names():
    ''' Check that the names method of TypeDeclGen works as expected '''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    dgen = TypeDeclGen(sub, datatype="my_type",
                       entity_decls=["type1"])
    sub.add(dgen)
    names = dgen.names
    assert len(names) == 1
    assert names[0] == "type1"
コード例 #11
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
コード例 #12
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)
    adduse("fred", call.root)
    gen = str(sub.root)
    expected = ("    SUBROUTINE testsubroutine()\n"
                "      USE fred\n")
    assert expected in gen
コード例 #13
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)
コード例 #14
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)
    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
コード例 #15
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"
コード例 #16
0
def test_typeselectiongen():
    ''' Check that SelectionGen works as expected for a type '''
    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
コード例 #17
0
def test_selectiongen_addcase():
    ''' Check that SelectionGen.addcase() works as expected when no
    content is supplied'''
    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
コード例 #18
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
コード例 #19
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]
コード例 #20
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"
コード例 #21
0
def test_imp_none_in_subroutine_with_use_and_decs_and_comments():
    ''' test that implicit none is added after any use statements
    and before any declarations in a subroutine in the presence of
    comments 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(UseGen(sub, "fred"))
    for idx in [0, 1, 2, 3]:
        sub.add(CommentGen(sub, " hello "+str(idx)),
                position=["before_index", 2*idx])
    sub.add(ImplicitNoneGen(sub))
    in_idx = line_number(sub.root, "IMPLICIT NONE")
    assert in_idx == 3
コード例 #22
0
def test_decl_no_replication_types():
    '''Check that the same array variable will only get declared once in
    a module and a subroutine'''
    variable_name = "arg_name"
    datatype = "field_type"
    module = ModuleGen(name="testmodule")
    module.add(TypeDeclGen(module, datatype=datatype,
                           entity_decls=[variable_name]))
    module.add(TypeDeclGen(module, datatype=datatype,
                           entity_decls=[variable_name]))
    subroutine = SubroutineGen(module, name="testsubroutine")
    module.add(subroutine)
    subroutine.add(TypeDeclGen(subroutine, datatype=datatype,
                               entity_decls=[variable_name]))
    subroutine.add(TypeDeclGen(subroutine, datatype=datatype,
                               entity_decls=[variable_name]))
    generated_code = str(module.root)
    assert generated_code.count(variable_name) == 2
コード例 #23
0
def test_selectiongen():
    ''' Check that SelectionGen works as expected '''
    module = ModuleGen(name="testmodule")
    sub = SubroutineGen(module, name="testsubroutine")
    module.add(sub)
    sgen = SelectionGen(sub, expr="my_var")
    sub.add(sgen)
    agen = AssignGen(sgen, lhs="happy", rhs=".TRUE.")
    sgen.addcase("1", [agen])
    # TODO how do we specify what happens in the default case?
    sgen.adddefault()
    gen = str(sub.root)
    print gen
    expected = ("SELECT CASE ( my_var )\n"
                "CASE ( 1 )\n"
                "        happy = .TRUE.\n"
                "CASE DEFAULT\n"
                "      END SELECT")
    assert expected in gen
    assert False
コード例 #24
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.block_statements.Do'>\n"
                "The type of parent is <class "
                "'fparser.block_statements.Subroutine'>\n"
                "Finding the loops position in its parent ...\n"
                "The loop's index is  0\n")
    assert expected in out
コード例 #25
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"]
コード例 #26
0
def test_imp_none_in_subroutine_with_use_and_decs():
    ''' test that implicit none is added after any use statements
    and before any declarations 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(UseGen(sub, "fred"))
    sub.add(ImplicitNoneGen(sub))
    in_idx = line_number(sub.root, "IMPLICIT NONE")
    assert in_idx == 2
コード例 #27
0
def test_typedeclgen_multiple_use2():
    '''Check that we do not correctly handle the case where data of a
    different type with the same name 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_type2",
                        entity_decls=datanames))
    gen = str(sub.root)
    print gen
    expected = (
        "      TYPE(my_type2) type1, type2\n"
        "      TYPE(my_type) type1")
    assert expected in gen
    # check input data is not modified
    assert datanames == ["type1", "type2"]
コード例 #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"]
コード例 #29
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
コード例 #30
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)