def test_program_handler(parser):
    '''Test that program handler works with multiple program units of
    different types.

    '''
    code = ("module a\n"
            "end module\n"
            "program b\n"
            "end program b\n"
            "subroutine c\n"
            "end subroutine")
    expected = ("module a\n"
                "  implicit none\n\n"
                "  contains\n\n"
                "end module a\n"
                "program b\n\n\n"
                "end program b\n"
                "subroutine c()\n\n\n"
                "end subroutine c\n")
    processor = Fparser2Reader()
    reader = FortranStringReader(code)
    parse_tree = parser(reader)
    psyir = processor._program_handler(parse_tree, None)
    # Check PSyIR nodes are being created
    assert isinstance(psyir, FileContainer)
    assert psyir.parent is None
    writer = FortranWriter()
    result = writer(psyir)
    assert result == expected
Esempio n. 2
0
def test_parse_derived_type(use_stmt, type_name):
    ''' Check that the fronted correctly creates a DataTypeSymbol of type
    StructureType from the declaration of a derived type. '''
    fake_parent = KernelSchedule("dummy_schedule")
    symtab = fake_parent.symbol_table
    processor = Fparser2Reader()
    reader = FortranStringReader("{0}\n"
                                 "type :: my_type\n"
                                 "  integer :: flag\n"
                                 "  type({1}), private :: grid\n"
                                 "  real, dimension(3) :: posn\n"
                                 "end type my_type\n"
                                 "type(my_type) :: var\n".format(
                                     use_stmt, type_name))
    fparser2spec = Fortran2003.Specification_Part(reader)
    processor.process_declarations(fake_parent, fparser2spec.content, [])
    sym = symtab.lookup("my_type")
    assert isinstance(sym, DataTypeSymbol)
    assert isinstance(sym.datatype, StructureType)
    flag = sym.datatype.lookup("flag")
    assert isinstance(flag.datatype, ScalarType)
    assert flag.visibility == Symbol.Visibility.PUBLIC
    grid = sym.datatype.lookup("grid")
    assert isinstance(grid.datatype, DataTypeSymbol)
    assert isinstance(grid.datatype.datatype, DeferredType)
    assert grid.visibility == Symbol.Visibility.PRIVATE
    posn = sym.datatype.lookup("posn")
    assert isinstance(posn.datatype, ArrayType)
    var = symtab.lookup("var")
    assert var.datatype is sym
Esempio n. 3
0
def test_call_noargs():
    '''Test that fparser2reader transforms a Fortran subroutine call with
    no arguments into the equivalent PSyIR Call node. Also test that a
    new RoutineSymbol is added to the symbol table (with an unresolved
    interface) when one does not already exist. Also test that the
    Call node ast property is set to reference the original fparser2
    call node.

    '''
    reader = FortranStringReader(" call kernel()")
    ast = Fortran2003.Call_Stmt(reader)
    fake_parent = Schedule()
    processor = Fparser2Reader()
    processor.process_nodes(fake_parent, [ast])

    call_node = fake_parent.children[0]
    assert isinstance(call_node, Call)
    assert not call_node.children

    routine_symbol = call_node.routine
    assert isinstance(routine_symbol, RoutineSymbol)
    assert isinstance(routine_symbol.interface, UnresolvedInterface)
    assert routine_symbol.name == "kernel"
    assert routine_symbol in call_node.scope.symbol_table.symbols

    assert (str(call_node)) == "Call[name='kernel']"

    assert call_node.ast == ast
Esempio n. 4
0
def test_array_of_derived_type_ref(f2008_parser):
    ''' Test that the frontend handles a reference to a member of an element
    of an array of derived types. '''
    processor = Fparser2Reader()
    reader = FortranStringReader("subroutine my_sub()\n"
                                 "  use some_mod, only: my_type\n"
                                 "  type(my_type), dimension(3) :: var\n"
                                 "  integer :: idx = 2\n"
                                 "  integer :: start = 2, stop = 3\n"
                                 "  var(1)%flag = 0\n"
                                 "  var(idx)%flag = 0\n"
                                 "  var(start:stop)%flag = 1\n"
                                 "  var(1)%region%start = 1\n"
                                 "  var(1)%region%subgrid(3)%stop = 1\n"
                                 "  var(1)%region%subgrid(3)%data(:) = 1.0\n"
                                 "end subroutine my_sub\n")
    fparser2spec = f2008_parser(reader)
    sched = processor.generate_schedule("my_sub", fparser2spec)
    assert not sched.walk(CodeBlock)
    assignments = sched.walk(Assignment)
    # var(1)%flag
    assign = assignments[0]
    assert isinstance(assign.lhs, ArrayOfStructuresReference)
    assert isinstance(assign.lhs.children[0], Member)
    assert assign.lhs.children[0].name == "flag"
    assert isinstance(assign.lhs.children[1], Literal)
    # var(idx)%flag
    assign = assignments[1]
    assert isinstance(assign.lhs, ArrayOfStructuresReference)
    assert isinstance(assign.lhs.children[0], Member)
    assert isinstance(assign.lhs.children[1], Reference)
    assert assign.lhs.children[1].symbol.name == "idx"
    # var(start:stop)%flag
    assign = assignments[2]
    assert isinstance(assign.lhs, ArrayOfStructuresReference)
    assert isinstance(assign.lhs.member, Member)
    assert isinstance(assign.lhs.indices[0], Range)
    assert isinstance(assign.lhs.indices[0].children[0], Reference)
    assert assign.lhs.indices[0].children[0].symbol.name == "start"
    # var(1)%region%start
    assign = assignments[3]
    assert isinstance(assign.lhs, ArrayOfStructuresReference)
    assert isinstance(assign.lhs.member, StructureMember)
    assert isinstance(assign.lhs.indices[0], Literal)
    assert assign.lhs.member.name == "region"
    assert isinstance(assign.lhs.member.member, Member)
    # var(1)%region%subgrid(3)%stop
    assign = assignments[4]
    assert isinstance(assign.lhs, ArrayOfStructuresReference)
    assert isinstance(assign.lhs.member.member, ArrayOfStructuresMember)
    assert isinstance(assign.lhs.member.member.member, Member)
    assert isinstance(assign.lhs.member.member.indices[0], Literal)
    # var(1)%region%subgrid(3)%data(:)
    assign = assignments[5]
    assert isinstance(assign.lhs, ArrayOfStructuresReference)
    amem = assign.lhs.member.member
    assert isinstance(amem, ArrayOfStructuresMember)
    assert isinstance(amem.member, ArrayMember)
    assert isinstance(amem.indices[0], Literal)
    assert isinstance(amem.member.indices[0], Range)
Esempio n. 5
0
def test_generate_container(parser):
    ''' Test that generate_container creates a PSyIR container with the
    contents of the given fparser2 fortran module.'''
    dummy_module = '''
    module dummy_mod
        use mod1
        use mod2, only: var1
        real :: modvar1
    contains
        subroutine dummy_code(f1, f2, f3)
            real(wp), dimension(:,:), intent(in)  :: f1
            real(wp), dimension(:,:), intent(out)  :: f2
            real(wp), dimension(:,:) :: f3
            f2 = f1 + 1
        end subroutine dummy_code
    end module dummy_mod
    '''
    reader = FortranStringReader(dummy_module)
    ast = parser(reader)
    processor = Fparser2Reader()
    container = processor.generate_container(ast)
    assert isinstance(container, Container)
    assert not container.children
    assert container.symbol_table
    assert container.symbol_table.lookup("modvar1")
    assert container.symbol_table.lookup("var1")
    assert container.symbol_table.lookup("mod1")
    assert container.symbol_table.lookup("mod2")
    assert container.symbol_table.lookup("dummy_code")
Esempio n. 6
0
def test_handling_literal_precision_1(value, dprecision, intrinsic):
    '''Check that the fparser2 frontend can handle literals with a
    specified precision kind symbol.

    '''
    if intrinsic == ScalarType.Intrinsic.CHARACTER:
        code = "x={0}_{1}".format(dprecision, value)
    else:
        code = "x={0}_{1}".format(value, dprecision)
    reader = FortranStringReader(code)
    astmt = Fortran2003.Assignment_Stmt(reader)
    fake_parent = Schedule()
    # Ensure the symbol table has an entry for "x"
    fake_parent.symbol_table.add(
        DataSymbol("x", ScalarType(ScalarType.Intrinsic.INTEGER, 4)))
    processor = Fparser2Reader()
    processor.process_nodes(fake_parent, [astmt])
    assert not fake_parent.walk(CodeBlock)
    literal = fake_parent.children[0].children[1]
    assert isinstance(literal, Literal)
    assert literal.datatype.intrinsic == intrinsic
    if intrinsic == ScalarType.Intrinsic.BOOLEAN:
        assert ".{0}.".format(literal.value) == value.lower()
    else:
        assert literal.value == value
    assert isinstance(literal.datatype.precision, DataSymbol)
    assert literal.datatype.precision.name == dprecision
    assert isinstance(literal.datatype.precision.datatype, ScalarType)
    assert (literal.datatype.precision.datatype.intrinsic ==
            ScalarType.Intrinsic.INTEGER)
def test_multi_use_stmt():
    ''' Check that we handle the case where different symbols are imported
    from a module in separate USE statements. '''
    fake_parent = KernelSchedule("dummy_schedule")
    processor = Fparser2Reader()
    reader = FortranStringReader("use my_mod, only: some_var\n"
                                 "use this_mod\n"
                                 "use my_mod, only: var1, var2\n"
                                 "use this_mod, only: var3\n")
    fparser2spec = Fortran2003.Specification_Part(reader)
    processor.process_declarations(fake_parent, fparser2spec.content, [])
    symtab = fake_parent.symbol_table
    csymbols = symtab.containersymbols
    # Although there are 4 use statements, there are only 2 modules
    assert len(csymbols) == 2
    my_mod = symtab.lookup("my_mod")
    assert not my_mod.wildcard_import
    # Check that we have accumulated all imports
    import_list = symtab.imported_symbols(my_mod)
    assert len(import_list) == 3
    names = [sym.name for sym in import_list]
    assert sorted(names) == ["some_var", "var1", "var2"]
    this_mod = symtab.lookup("this_mod")
    assert this_mod.wildcard_import
    names = [sym.name for sym in symtab.imported_symbols(this_mod)]
    assert names == ["var3"]
Esempio n. 8
0
def test_derived_type_codeblocks(f2008_parser):
    ''' Check that we create a CodeBlock if we encounter unsupported
    entries in a parse tree describing a derived-type access. We have
    to test with invalid content in two locations. '''
    code = ("subroutine my_sub()\n"
            "  use some_mod, only: my_type\n"
            "  type(my_type), dimension(3) :: var\n"
            "  var(1)%region%subgrid(3)%stop = 1\n"
            "end subroutine my_sub\n")
    processor = Fparser2Reader()
    # First create a valid parse tree.
    reader = FortranStringReader(code)
    fparser2spec = f2008_parser(reader)
    dref = Fortran2003.walk(fparser2spec, Fortran2003.Data_Ref)[0]
    # Now break the Data_Ref instance by modifying its first child. Requesting
    # a subset of items from a tuple appears to generate a new tuple so
    # explicitly create a list and then create a tuple from that.
    item_list = ["hello"] + list(dref.items[1:])
    dref.items = tuple(item_list)
    sched = processor.generate_schedule("my_sub", fparser2spec)
    cblocks = sched.walk(CodeBlock)
    assert len(cblocks) == 1
    assert isinstance(cblocks[0].parent, Assignment)
    # Repeat but this time break the Data_Ref by modifying its second child.
    reader = FortranStringReader(code)
    fparser2spec = f2008_parser(reader)
    dref = Fortran2003.walk(fparser2spec, Fortran2003.Data_Ref)[0]
    dref.items = (dref.items[0], "hello")
    sched = processor.generate_schedule("my_sub", fparser2spec)
    cblocks = sched.walk(CodeBlock)
    assert len(cblocks) == 1
    assert isinstance(cblocks[0].parent, Assignment)
def test_redundant_empty_only_list():
    ''' Check that we drop 'use's with an empty only list if they become
    redundant. #TODO #11 Check for appropriate logging messages here once
    logging is implemented. '''
    fake_parent = KernelSchedule("dummy_schedule")
    processor = Fparser2Reader()
    # Empty only-list followed by wildcard import
    reader = FortranStringReader("use mod1, only:\n" "use mod1\n")
    fparser2spec = Fortran2003.Specification_Part(reader)
    processor.process_declarations(fake_parent, fparser2spec.content, [])
    csym = fake_parent.symbol_table.lookup("mod1")
    assert csym.wildcard_import
    # Wildcard import followed by empty only-list
    reader = FortranStringReader("use mod2\n" "use mod2, only:\n")
    fparser2spec = Fortran2003.Specification_Part(reader)
    processor.process_declarations(fake_parent, fparser2spec.content, [])
    csym = fake_parent.symbol_table.lookup("mod2")
    assert csym.wildcard_import
    # Empty only-list followed by named import
    reader = FortranStringReader("use mod3, only:\n" "use mod3, only: fred\n")
    fparser2spec = Fortran2003.Specification_Part(reader)
    processor.process_declarations(fake_parent, fparser2spec.content, [])
    sym_table = fake_parent.symbol_table
    csym = sym_table.lookup("mod3")
    assert not csym.wildcard_import
    assert sym_table.imported_symbols(csym)[0].name == "fred"
    # Named import followed by empty only-list
    reader = FortranStringReader("use mod4, only: bob\n" "use mod4, only:\n")
    fparser2spec = Fortran2003.Specification_Part(reader)
    processor.process_declarations(fake_parent, fparser2spec.content, [])
    csym = sym_table.lookup("mod4")
    assert not csym.wildcard_import
    assert sym_table.imported_symbols(csym)[0].name == "bob"
Esempio n. 10
0
def test_use_stmt():
    ''' Check that SymbolTable entries are correctly created from
    module use statements. '''
    fake_parent = KernelSchedule("dummy_schedule")
    processor = Fparser2Reader()
    reader = FortranStringReader("use my_mod, only: some_var\n"
                                 "use this_mod\n"
                                 "use other_mod, only: var1, var2\n")
    fparser2spec = Fortran2003.Specification_Part(reader)
    processor.process_declarations(fake_parent, fparser2spec.content, [])

    symtab = fake_parent.symbol_table

    for module_name in ["my_mod", "this_mod", "other_mod"]:
        container = symtab.lookup(module_name)
        assert isinstance(container, ContainerSymbol)
        assert container.name == module_name
        # Container reference is not updated until explicitly requested
        assert not container._reference

    for var in ["some_var", "var1", "var2"]:
        assert symtab.lookup(var).name == var

    assert symtab.lookup("some_var").interface.container_symbol \
        == symtab.lookup("my_mod")
    assert symtab.lookup("var2").interface.container_symbol \
        == symtab.lookup("other_mod")
Esempio n. 11
0
def test_where_ordering(parser):
    ''' Check that the generated schedule has the correct ordering when
    a WHERE construct is processed.

    '''
    reader = FortranStringReader(
        "    subroutine test(zdiv, pbef, paft, zmsk, tmask)\n"
        "      integer, parameter :: wp=1\n"
        "      real :: zsml\n"
        "      integer :: ji, jj, jpjm1, jpim1\n"
        "      real :: zdiv(:,:), pbef(:,:), paft(:,:), zmsk(:,:), "
        "tmask(:,:)\n"
        "      zsml = 1.e-15_wp\n"
        "      DO jj = 2, jpjm1\n"
        "         DO ji = 2, jpim1\n"
        "            zdiv(ji,jj) =  1.0_wp\n"
        "         END DO\n"
        "      END DO\n"
        "      CALL lbc_lnk( zdiv, 'T', 1. )\n"
        "      WHERE( pbef(:,:) == 0._wp .AND. paft(:,:) == 0._wp .AND. "
        "zdiv(:,:) == 0._wp )   ;   zmsk(:,:) = 0._wp\n"
        "      ELSEWHERE;   zmsk(:,:) = 1._wp * tmask(:,:,1)\n"
        "      END WHERE\n"
        "    end subroutine test\n")
    fparser2_tree = parser(reader)
    processor = Fparser2Reader()
    result = processor.generate_schedule("test", fparser2_tree)
    assert isinstance(result[0], Assignment)
    assert isinstance(result[1], Loop)
    assert isinstance(result[2], CodeBlock)
    assert isinstance(result[3], Loop)
Esempio n. 12
0
def process_where(code, fparser_cls, symbols=None):
    '''
    Utility routine to process the supplied Fortran code and return the
    PSyIR and fparser2 parse trees.

    :param str code: Fortran code to process.
    :param type fparser_cls: the fparser2 class to instantiate to \
                             represent the supplied Fortran.
    :param symbols: list of symbol names that must be added to the symbol \
                    table before constructing the PSyIR.
    :type symbols: list of str

    :returns: 2-tuple of a parent PSyIR Schedule and the created instance of \
              the requested fparser2 class.
    :rtype: (:py:class:`psyclone.psyir.nodes.Schedule`, \
             :py:class:`fparser.two.utils.Base`)
    '''
    sched = Schedule()
    if symbols:
        for sym_name in symbols:
            sched.symbol_table.new_symbol(sym_name)
    processor = Fparser2Reader()
    reader = FortranStringReader(code)
    fparser2spec = fparser_cls(reader)

    if fparser_cls is Fortran2003.Execution_Part:
        processor.process_nodes(sched, fparser2spec.content)
    else:
        processor.process_nodes(sched, [fparser2spec])
    return sched, fparser2spec
Esempio n. 13
0
def test_array_notation_rank():
    ''' Check that the _array_notation_rank() utility handles various examples
    of array notation.

    TODO #754 fix test so that 'disable_declaration_check' fixture is not
    required.
    '''
    fake_parent = Schedule()
    processor = Fparser2Reader()
    reader = FortranStringReader("  z1_st(:, 2, :) = ptsu(:, :, 3)")
    fparser2spec = Fortran2003.Assignment_Stmt(reader)
    processor.process_nodes(fake_parent, [fparser2spec])
    assert processor._array_notation_rank(fake_parent[0].lhs) == 2
    reader = FortranStringReader("  z1_st(:, :, 2, :) = ptsu(:, :, :, 3)")
    fparser2spec = Fortran2003.Assignment_Stmt(reader)
    processor.process_nodes(fake_parent, [fparser2spec])
    assert processor._array_notation_rank(fake_parent[1].lhs) == 3
    # We don't support bounds on slices
    reader = FortranStringReader("  z1_st(:, 1:n, 2, :) = ptsu(:, :, :, 3)")
    fparser2spec = Fortran2003.Assignment_Stmt(reader)
    processor.process_nodes(fake_parent, [fparser2spec])
    with pytest.raises(NotImplementedError) as err:
        processor._array_notation_rank(fake_parent[2].lhs)
    assert ("Only array notation of the form my_array(:, :, ...) is "
            "supported." in str(err.value))
Esempio n. 14
0
def test_handling_literal_precision_2(value, dprecision, intrinsic):
    '''Check that the fparser2 frontend can handle literals with a
    specified precision value.

    TODO #754 fix test so that 'disable_declaration_check' fixture is not
    required.
    '''
    if intrinsic == ScalarType.Intrinsic.CHARACTER:
        code = "x={0}_{1}".format(dprecision, value)
    else:
        code = "x={0}_{1}".format(value, dprecision)
    reader = FortranStringReader(code)
    astmt = Fortran2003.Assignment_Stmt(reader)
    fake_parent = Schedule()
    processor = Fparser2Reader()
    processor.process_nodes(fake_parent, [astmt])
    assert not fake_parent.walk(CodeBlock)
    literal = fake_parent.children[0].children[1]
    assert isinstance(literal, Literal)
    assert literal.datatype.intrinsic == intrinsic
    if intrinsic == ScalarType.Intrinsic.BOOLEAN:
        assert ".{0}.".format(literal.value) == value.lower()
    else:
        assert literal.value == value
    assert isinstance(literal.datatype.precision, int)
    assert literal.datatype.precision == dprecision
Esempio n. 15
0
def test_call_args(f2008_parser):
    '''Test that fparser2reader transforms a Fortran subroutine call with
    arguments into the equivalent PSyIR Call node.

    '''
    test_code = ("subroutine test()\n"
                 "use my_mod, only : kernel\n"
                 "real :: a,b\n"
                 "  call kernel(1.0, a, (a+b)*2.0, name=\"roo\")\n"
                 "end subroutine")
    reader = FortranStringReader(test_code)
    ptree = f2008_parser(reader)
    processor = Fparser2Reader()
    sched = processor.generate_schedule("test", ptree)

    call_node = sched.children[0]
    assert isinstance(call_node, Call)
    assert len(call_node.children) == 4
    assert isinstance(call_node.children[0], Literal)
    assert call_node.children[0].value == "1.0"
    assert isinstance(call_node.children[1], Reference)
    assert call_node.children[1].name == "a"
    assert isinstance(call_node.children[2], BinaryOperation)
    assert isinstance(call_node.children[3], CodeBlock)

    routine_symbol = call_node.routine
    assert isinstance(routine_symbol, RoutineSymbol)
    assert call_node.routine.name == "kernel"
    assert isinstance(routine_symbol.interface, GlobalInterface)
    assert routine_symbol is call_node.scope.symbol_table.lookup("kernel")

    assert (str(call_node)) == "Call[name='kernel']"
Esempio n. 16
0
def test_number_handler():
    ''' Check that the number_handler raises a NotImplementedError for an
    unrecognised fparser2 node. '''
    processor = Fparser2Reader()
    fake_parent = Schedule()
    reader = FortranStringReader("(1.0, 1.0)")
    with pytest.raises(NotImplementedError):
        processor._number_handler(Fortran2003.Complex_Literal_Constant(reader),
                                  fake_parent)
Esempio n. 17
0
def test_transformation(parser, test_case):
    ''' Check that the transformation works as expected. '''
    input_code, expected = test_cases[test_case]
    trans = FoldConditionalReturnExpressionsTrans()
    processor = Fparser2Reader()
    reader = FortranStringReader(input_code)
    parse_tree = parser(reader)
    subroutine = processor.generate_psyir(parse_tree)
    trans.apply(subroutine)
    writer = FortranWriter()
    assert writer(subroutine) == expected
def test_generate_psyir_error(parser):
    '''Test that generate_psyir raises the expected exception if the
    supplied fparser2 parse tree does not have a Program node as its
    root.'''
    processor = Fparser2Reader()
    reader = FortranStringReader(MODULE_IN)
    parse_tree = parser(reader)
    with pytest.raises(GenerationError) as info:
        _ = processor.generate_psyir(parse_tree.children[0])
    assert ("The Fparser2Reader generate_psyir method expects the root of "
            "the supplied fparser2 tree to be a Program, but found 'Module'"
            in str(info.value))
Esempio n. 19
0
def test_name_clash_use_stmt():
    ''' Check that we raise the expected error if we encounter a module
    with a name that's already taken in the Symbol Table. This is invalid
    Fortran but we need to test the error-handling in PSyclone. '''
    fake_parent = KernelSchedule("dummy_schedule")
    processor = Fparser2Reader()
    reader = FortranStringReader("use my_mod, only: some_var\n"
                                 "use some_var, only: var1, var2\n")
    fparser2spec = Fortran2003.Specification_Part(reader)
    with pytest.raises(SymbolError) as err:
        processor.process_declarations(fake_parent, fparser2spec.content, [])
    assert "Found a USE of module 'some_var' but the symbol" in str(err.value)
def test_subscript_triplet_handler_error():
    ''' Check that the subscript-triplet handler raises the expected error if
    the parent PSyIR node is not of the correct type. '''
    processor = Fparser2Reader()
    fake_parent = Schedule()
    reader = FortranStringReader("x(:) = a")
    fp2node = Execution_Part.match(reader)
    triplet = fp2node[0][0].children[0].children[1].children[0]
    with pytest.raises(InternalError) as err:
        processor._subscript_triplet_handler(triplet, fake_parent)
    assert ("Expected parent PSyIR node to be either a Reference or a Member "
            "but got 'Schedule' when processing ':'" in str(err.value))
Esempio n. 21
0
def test_use_no_only_list():
    ''' Check that we create the correct Symbol Table entry for a use
    statement that has an 'only' clause but no list of imported symbols. '''
    fake_parent = KernelSchedule("dummy_schedule")
    processor = Fparser2Reader()
    reader = FortranStringReader("use my_mod, only: some_var\n"
                                 "use some_mod, only:\n")
    fparser2spec = Fortran2003.Specification_Part(reader)
    processor.process_declarations(fake_parent, fparser2spec.content, [])
    some_mod = fake_parent.symbol_table.lookup("some_mod")
    assert not some_mod.wildcard_import
    assert fake_parent.symbol_table.imported_symbols(some_mod) == []
Esempio n. 22
0
def test_missing_derived_type():
    ''' Check that the fronted raises an error if it encounters a variable
    of a derived type that cannot be resolved. '''
    fake_parent = KernelSchedule("dummy_schedule")
    processor = Fparser2Reader()
    reader = FortranStringReader("type(my_type) :: var")
    fparser2spec = Fortran2003.Specification_Part(reader)
    # This should raise an error because there's no Container from which
    # the definition of 'my_type' can be brought into scope.
    with pytest.raises(SymbolError) as err:
        processor.process_declarations(fake_parent, fparser2spec.content, [])
    assert "No Symbol found for name 'my_type'" in str(err.value)
def test_subroutine_handler(parser, fortran_writer, code, expected):
    '''Test that subroutine_handler handles valid Fortran subroutines.'''

    processor = Fparser2Reader()
    reader = FortranStringReader(code)
    parse_tree = parser(reader)
    subroutine = parse_tree.children[0]
    psyir = processor._subroutine_handler(subroutine, None)
    # Check the expected PSyIR nodes are being created
    assert isinstance(psyir, Routine)
    assert psyir.parent is None
    result = fortran_writer(psyir)
    assert expected == result
Esempio n. 24
0
def test_derived_type_ref(f2008_parser):
    ''' Check that the frontend handles a references to a member of
    a derived type. '''
    processor = Fparser2Reader()
    reader = FortranStringReader(
        "subroutine my_sub()\n"
        "  use some_mod, only: my_type\n"
        "  type(my_type) :: var\n"
        "  var%flag = 0\n"
        "  var%region%start = 1\n"
        "  var%region%subgrid(3)%stop = 1\n"
        "  var%region%subgrid(3)%data(:) = 1.0\n"
        "  var%region%subgrid(3)%data(var%start:var%stop) = 1.0\n"
        "end subroutine my_sub\n")
    fparser2spec = f2008_parser(reader)
    sched = processor.generate_schedule("my_sub", fparser2spec)
    assert not sched.walk(CodeBlock)
    assignments = sched.walk(Assignment)
    # var%flag
    assign = assignments[0]
    assert isinstance(assign.lhs, StructureReference)
    assert isinstance(assign.lhs.children[0], Member)
    assert assign.lhs.children[0].name == "flag"
    # var%region%start
    assign = assignments[1]
    assert isinstance(assign.lhs, StructureReference)
    assert isinstance(assign.lhs.children[0], StructureMember)
    assert assign.lhs.children[0].name == "region"
    assert isinstance(assign.lhs.children[0].children[0], Member)
    assert assign.lhs.children[0].children[0].name == "start"
    # var%region%subgrid(3)%stop
    assign = assignments[2]
    amem = assign.lhs.children[0].children[0]
    assert isinstance(amem, ArrayOfStructuresMember)
    assert isinstance(amem.children[0], Member)
    assert isinstance(amem.children[1], Literal)
    assert amem.children[0].name == "stop"
    # var%region%subgrid(3)%data(:)
    assign = assignments[3]
    amem = assign.lhs.member.member
    assert isinstance(amem, ArrayOfStructuresMember)
    assert isinstance(amem.member, ArrayMember)
    assert isinstance(amem.member.indices[0], Range)
    assign = assignments[4]
    # var%region%subgrid(3)%data(var%start:var%stop)
    amem = assign.lhs.member.member.member
    assert isinstance(amem, ArrayMember)
    assert isinstance(amem.indices[0], Range)
    assert isinstance(amem.indices[0].children[0], StructureReference)
    assert isinstance(amem.indices[0].children[0].member, Member)
    assert amem.indices[0].children[0].member.name == "start"
Esempio n. 25
0
def test_broken_use(monkeypatch):
    ''' Check that we raise the expected error if we encounter an unrecognised
    parse tree for a USE statement. '''
    fake_parent = KernelSchedule("dummy_schedule")
    processor = Fparser2Reader()
    reader = FortranStringReader("use some_mod, only:\n")
    fparser2spec = Fortran2003.Specification_Part(reader)
    # Break the parse tree so that instead of ", ONLY:" it has "hello"
    monkeypatch.setattr(
        fparser2spec.content[0], "items",
        [None, None, Fortran2003.Name('my_mod'), 'hello', None])
    with pytest.raises(NotImplementedError) as err:
        processor.process_declarations(fake_parent, fparser2spec.content, [])
    assert "unsupported USE statement: 'USE my_modhello'" in str(err.value)
Esempio n. 26
0
def test_module_handler(parser, code, expected):
    '''Test that module_handler handles valid Fortran modules.
    '''
    processor = Fparser2Reader()
    reader = FortranStringReader(code)
    parse_tree = parser(reader)
    module = parse_tree.children[0]
    psyir = processor._module_handler(module, None)
    # Check the expected PSyIR nodes are being created
    assert isinstance(psyir, Container)
    assert psyir.parent is None
    writer = FortranWriter()
    result = writer(psyir)
    assert expected == result
Esempio n. 27
0
def test_generate_psyir(parser, code, expected, node_class):
    '''Test that generate_psyir generates PSyIR from an fparser2 parse
    tree.

    '''
    processor = Fparser2Reader()
    reader = FortranStringReader(code)
    parse_tree = parser(reader)
    psyir = processor.generate_psyir(parse_tree)
    # Check the expected PSyIR nodes are being created
    assert isinstance(psyir, node_class)
    writer = FortranWriter()
    result = writer(psyir)
    assert result == expected
Esempio n. 28
0
def test_public_private_symbol_error(parser):
    ''' Check that we raise the expected error when a symbol is listed as
    being both PUBLIC and PRIVATE. (fparser2 doesn't check for this.) '''
    processor = Fparser2Reader()
    reader = FortranStringReader("module modulename\n"
                                 "private\n"
                                 "public var3\n"
                                 "private var4, var3\n"
                                 "end module modulename")
    fparser2spec = parser(reader)
    with pytest.raises(GenerationError) as err:
        processor.generate_container(fparser2spec)
    assert ("Symbols ['var3'] appear in access statements with both PUBLIC "
            "and PRIVATE" in str(err.value))
Esempio n. 29
0
def test_multiple_access_stmt_error(parser):
    ''' Check that we raise the expected error when we encounter multiple
    access statements. (fparser2 doesn't check for this.) '''
    processor = Fparser2Reader()
    reader = FortranStringReader("module modulename\n"
                                 "private\n"
                                 "public var3\n"
                                 "private\n"
                                 "end module modulename")
    fparser2spec = parser(reader)
    with pytest.raises(GenerationError) as err:
        processor.generate_container(fparser2spec)
    assert ("Module 'modulename' contains more than one access statement with"
            in str(err.value))
Esempio n. 30
0
def test_size(expression, parser):
    ''' Basic test that the SIZE intrinsic is recognised and represented
    in the PSyIR. '''
    from fparser.two.Fortran2003 import Execution_Part
    from psyclone.psyGen import Schedule, Assignment, BinaryOperation, \
        Reference, Literal
    fake_parent = Schedule()
    processor = Fparser2Reader()
    reader = FortranStringReader(expression)
    fp2intrinsic = Execution_Part(reader).content[0]
    processor.process_nodes(fake_parent, [fp2intrinsic], None)
    assert isinstance(fake_parent[0], Assignment)
    assert isinstance(fake_parent[0].rhs, BinaryOperation)
    assert isinstance(fake_parent[0].rhs.children[0], Reference)
    assert isinstance(fake_parent[0].rhs.children[1], Literal)