Exemplo n.º 1
0
def test_struc_ref_create():
    ''' Tests for the create method. '''
    region_type = symbols.StructureType.create([
        ("startx", symbols.INTEGER_TYPE, symbols.Symbol.Visibility.PUBLIC)
    ])
    region_type_symbol = symbols.DataTypeSymbol("region_type", region_type)
    grid_type = symbols.StructureType.create([
        ("nx", symbols.INTEGER_TYPE, symbols.Symbol.Visibility.PUBLIC),
        ("region", region_type_symbol, symbols.Symbol.Visibility.PRIVATE),
        ("sub_grids", symbols.ArrayType(region_type_symbol, [3]),
         symbols.Symbol.Visibility.PUBLIC),
        ("data", symbols.ArrayType(symbols.REAL_TYPE,
                                   [10, 10]), symbols.Symbol.Visibility.PUBLIC)
    ])
    grid_type_symbol = symbols.DataTypeSymbol("grid_type", grid_type)
    ssym = symbols.DataSymbol("grid", grid_type_symbol)
    # Reference to scalar member of structure
    sref = nodes.StructureReference.create(ssym, ["nx"])
    assert sref.symbol is ssym
    assert len(sref.children) == 1
    assert sref.children[0].name == "nx"
    check_links(sref, sref.children)
    # Reference to scalar member of structure member of structure
    rref = nodes.StructureReference.create(ssym, ["region", "startx"])
    assert rref.children[0].name == "region"
    assert rref.children[0].children[0].name == "startx"
    check_links(rref.children[0], rref.children[0].children)
    # Reference to an element of an array member of the structure
    aref = nodes.StructureReference.create(ssym, [("data", [
        nodes.Literal("1", symbols.INTEGER_TYPE),
        nodes.Literal("5", symbols.INTEGER_TYPE)
    ])])
    assert isinstance(aref.children[0], nodes.ArrayMember)
    assert aref.children[0].name == "data"
    assert isinstance(aref.children[0].children[1], nodes.Literal)
    assert aref.children[0].children[1].value == "5"
    check_links(aref, aref.children)
    check_links(aref.children[0], aref.children[0].children)
    # Reference to an array of structures within a structure
    structarray_ref = nodes.StructureReference.create(
        ssym, [("sub_grids", [nodes.Literal("1", symbols.INTEGER_TYPE)])])
    assert isinstance(structarray_ref.children[0], nodes.ArrayMember)
    # Reference to a scalar member of an element of an array of structures
    # contained in a structure
    dref = nodes.StructureReference.create(
        ssym,
        [("sub_grids", [nodes.Literal("2", symbols.INTEGER_TYPE)]), "startx"])
    assert isinstance(dref.children[0], nodes.ArrayOfStructuresMember)
    assert isinstance(dref.children[0].children[0], nodes.Member)
    assert isinstance(dref.children[0].children[1], nodes.Literal)
    check_links(dref, dref.children)
    check_links(dref.children[0], dref.children[0].children)
def test_asr_create_errors(component_symbol):
    ''' Test the validation checks within the create method. Most validation
    is done within the StructureReference class so there's not much to check
    here. '''
    with pytest.raises(TypeError) as err:
        _ = nodes.ArrayOfStructuresReference.create(1, [], [])
    assert ("'symbol' argument to ArrayOfStructuresReference.create() should "
            "be a DataSymbol but found 'int'" in str(err.value))
    scalar_symbol = symbols.DataSymbol("scalar", symbols.INTEGER_TYPE)
    with pytest.raises(TypeError) as err:
        _ = nodes.ArrayOfStructuresReference.create(scalar_symbol, [], [])
    assert ("ArrayType, DeferredType or UnknownType but symbol 'scalar' has "
            "type 'Scalar" in str(err.value))
    # Missing children (for array-index expressions)
    with pytest.raises(TypeError) as err:
        _ = nodes.ArrayOfStructuresReference.create(component_symbol,
                                                    False, ["hello"])
    assert ("must be a list containing at least one array-index expression "
            "but this is missing for symbol 'grid'" in str(err.value))
    # Missing member(s)
    with pytest.raises(ValueError) as err:
        _ = nodes.ArrayOfStructuresReference.create(
            component_symbol, [nodes.Literal("1", symbols.INTEGER_TYPE)], [])
    assert ("'members' that are being accessed but got an empty list for "
            "symbol 'grid'" in str(err.value))
Exemplo n.º 3
0
def test_am_create():
    ''' Test the create method of ArrayMember. '''
    amem = nodes.ArrayMember.create("subdomains", [
        nodes.Literal("1", symbols.INTEGER_TYPE),
        nodes.Literal("2", symbols.INTEGER_TYPE)
    ])
    assert isinstance(amem, nodes.ArrayMember)
    assert len(amem.children) == 2
    assert isinstance(amem.indices[1], nodes.Literal)
    assert amem.indices[1].parent is amem

    with pytest.raises(GenerationError) as err:
        nodes.ArrayMember.create("subdomains",
                                 nodes.Literal("1", symbols.INTEGER_TYPE))
    assert ("indices argument in create method of ArrayMember class should be "
            "a list but found 'Literal'" in str(err.value))
Exemplo n.º 4
0
def test_asmr_create():
    ''' Test the create method of ArrayOfStructuresMember. '''
    asmr = nodes.ArrayOfStructuresMember.create(
        "regions", [nodes.Literal("3", symbols.INTEGER_TYPE)],
        nodes.Member("sub_mesh"))
    assert len(asmr.children) == 2
    assert isinstance(asmr.children[0], nodes.Member)
    assert asmr.children[1].value == "3"
Exemplo n.º 5
0
def test_am_validate_child():
    ''' Test the _validate_child method of ArrayMember. '''
    idx = nodes.Literal("3", symbols.INTEGER_TYPE)
    amr = nodes.ArrayMember("sub_mesh")
    with pytest.raises(GenerationError) as err:
        amr.addchild("wrong")
    assert "'str' can't be child 0 of 'ArrayMember'" in str(err.value)
    amr.addchild(idx)
    assert amr.children[0] is idx
def test_ast_str():
    ''' Test that the __str__ method of the StructureReference class works OK
    when we have an ArrayOfStructuresReference. '''
    grid_type = symbols.StructureType.create([
        ("nx", symbols.INTEGER_TYPE, symbols.Symbol.Visibility.PUBLIC)])
    grid_type_symbol = symbols.DataTypeSymbol("grid_type", grid_type)
    grid_array_type = symbols.ArrayType(grid_type_symbol, [5])
    ssym = symbols.DataSymbol("grid", grid_array_type)
    asref = nodes.ArrayOfStructuresReference.create(
        ssym, [nodes.Literal("2", symbols.INTEGER_TYPE)], ["nx"])
    assert (str(asref) == "ArrayOfStructuresReference[name:'grid']\n"
            "Member[name:'nx']\n"
            "Literal[value:'2', Scalar<INTEGER, UNDEFINED>]")
Exemplo n.º 7
0
def test_asmr_indices():
    ''' Test the indices property of ArrayOfStructuresMember. '''
    asmr = nodes.ArrayOfStructuresMember.create(
        "regions", [nodes.Literal("3", symbols.INTEGER_TYPE)],
        nodes.Member("sub_mesh"))
    indices = asmr.indices
    assert len(indices) == 1
    assert isinstance(indices[0], nodes.Literal)
    assert indices[0].value == "3"
    # Break the children of the node to check that we get the expected
    # error.
    asmr._children = [asmr._children[0]]
    with pytest.raises(InternalError) as err:
        asmr.indices
    assert ("must have one or more children representing array-index "
            "expressions but found none" in str(err.value))
    asmr._children = [asmr._children[0], "hello"]
    with pytest.raises(InternalError) as err:
        asmr.indices
    assert ("malformed or incomplete: child 1 must represent an array-index "
            "expression but found 'str' instead of psyir.nodes.DataNode or "
            "Range" in str(err.value))
Exemplo n.º 8
0
def test_asr_create(component_symbol):
    ''' Check the create method. '''
    int_one = nodes.Literal("1", symbols.INTEGER_TYPE)
    # Reference to scalar member of structure in array of structures
    asref = nodes.ArrayOfStructuresReference.create(component_symbol,
                                                    [int_one], ["nx"])
    assert isinstance(asref.children[0], nodes.Member)
    assert isinstance(asref.children[1], nodes.Literal)
    check_links(asref, asref.children)
    # Reference to member of structure member of structure in array of
    # structures
    asref = nodes.ArrayOfStructuresReference.create(component_symbol,
                                                    [int_one],
                                                    ["region", "startx"])
    assert isinstance(asref.children[0], nodes.StructureMember)
    assert isinstance(asref.children[0].children[0], nodes.Member)
    # Reference to range of structures
    lbound = nodes.BinaryOperation.create(
        nodes.BinaryOperation.Operator.LBOUND,
        nodes.Reference(component_symbol), int_one)
    ubound = nodes.BinaryOperation.create(
        nodes.BinaryOperation.Operator.UBOUND,
        nodes.Reference(component_symbol), int_one)
    my_range = nodes.Range.create(lbound, ubound)
    asref = nodes.ArrayOfStructuresReference.create(component_symbol,
                                                    [my_range], ["nx"])
    assert isinstance(asref.children[0], nodes.Member)
    assert isinstance(asref.children[1], nodes.Range)
    check_links(asref, asref.children)
    check_links(asref.children[1], asref.children[1].children)
    # Reference to a symbol of DeferredType
    ssym = symbols.DataSymbol("grid", symbols.DeferredType())
    asref = nodes.ArrayOfStructuresReference.create(ssym, [int_one],
                                                    ["region", "startx"])
    assert isinstance(asref.symbol.datatype, symbols.DeferredType)
    assert isinstance(asref.children[0], nodes.StructureMember)
    assert isinstance(asref.children[0].children[0], nodes.Member)
Exemplo n.º 9
0
def test_am_is_lower_upper_bound():
    ''' Test the is_lower/upper_bound methods of ArrayMember. '''
    one = nodes.Literal("1", symbols.INTEGER_TYPE)
    two = nodes.Literal("2", symbols.INTEGER_TYPE)
    amem1 = nodes.ArrayMember.create(
        "subdomains",
        [one.copy(), nodes.Literal("2", symbols.INTEGER_TYPE)])
    assert amem1.is_lower_bound(0) is False
    assert amem1.is_upper_bound(0) is False
    grid_type = symbols.DataTypeSymbol("grid_type", symbols.DeferredType())
    sym = symbols.DataSymbol("grid_var", grid_type)
    ref = nodes.StructureReference.create(sym, ["data"])
    # Start and stop for the range are binary operators but not the right ones
    start = nodes.operation.BinaryOperation.create(
        nodes.operation.BinaryOperation.Operator.UBOUND, ref.copy(),
        one.copy())
    stop = nodes.operation.BinaryOperation.create(
        nodes.operation.BinaryOperation.Operator.LBOUND, ref.copy(),
        one.copy())
    my_range = nodes.Range.create(start, stop)
    sref = nodes.StructureReference.create(sym, [("data", [my_range])])
    amem2 = sref.walk(nodes.ArrayMember)[0]
    assert amem2.is_lower_bound(0) is False
    assert amem2.is_upper_bound(0) is False
    # Correct binary operators but wrong types of operand
    start = nodes.operation.BinaryOperation.create(
        nodes.operation.BinaryOperation.Operator.LBOUND, one.copy(),
        one.copy())
    stop = nodes.operation.BinaryOperation.create(
        nodes.operation.BinaryOperation.Operator.UBOUND, one.copy(),
        one.copy())
    my_range = nodes.Range.create(start, stop)
    sref = nodes.StructureReference.create(sym, [("data", [my_range])])
    amem2 = sref.walk(nodes.ArrayMember)[0]
    assert amem2.is_lower_bound(0) is False
    assert amem2.is_upper_bound(0) is False
    # Correct start and stop arguments to Range
    start = nodes.operation.BinaryOperation.create(
        nodes.operation.BinaryOperation.Operator.LBOUND, ref.copy(),
        one.copy())
    stop = nodes.operation.BinaryOperation.create(
        nodes.operation.BinaryOperation.Operator.UBOUND, ref.copy(),
        one.copy())
    my_range = nodes.Range.create(start, stop)
    sref = nodes.StructureReference.create(sym, [("data", [my_range])])
    amem2 = sref.walk(nodes.ArrayMember)[0]
    assert amem2.is_lower_bound(0) is True
    assert amem2.is_upper_bound(0) is True
    # Range in a dimension other than the first
    start = nodes.operation.BinaryOperation.create(
        nodes.operation.BinaryOperation.Operator.LBOUND, ref.copy(),
        two.copy())
    stop = nodes.operation.BinaryOperation.create(
        nodes.operation.BinaryOperation.Operator.UBOUND, ref.copy(),
        two.copy())
    my_range = nodes.Range.create(start, stop)
    sref = nodes.StructureReference.create(sym,
                                           [("data", [one.copy(), my_range])])
    amem2 = sref.walk(nodes.ArrayMember)[0]
    assert amem2.is_lower_bound(0) is False
    assert amem2.is_upper_bound(0) is False
    assert amem2.is_lower_bound(1) is True
    assert amem2.is_upper_bound(1) is True
Exemplo n.º 10
0
def test_am_matching_access():
    ''' Test the _matching_access method of ArrayMember. '''
    one = nodes.Literal("1", symbols.INTEGER_TYPE)
    two = nodes.Literal("2", symbols.INTEGER_TYPE)
    amem1 = nodes.ArrayMember.create(
        "subdomains",
        [one.copy(), nodes.Literal("2", symbols.INTEGER_TYPE)])
    # Check when the ArrayMember has no parent Reference
    result = amem1._matching_access(
        nodes.Reference(symbols.DataSymbol("fake", symbols.INTEGER_TYPE)))
    assert result is False
    grid_type = symbols.DataTypeSymbol("grid_type", symbols.DeferredType())
    sym1 = symbols.DataSymbol("grid_var", grid_type)
    sym2 = symbols.DataSymbol("grid_var2", grid_type)
    ref1 = nodes.StructureReference.create(sym1, ["data"])
    # Reference is to a different symbol
    ref2 = nodes.StructureReference.create(sym2, [("data", [one.copy()])])
    assert ref2.member._matching_access(ref1) is False
    # Reference is to a different member of the same symbol
    ref2 = nodes.StructureReference.create(sym1, [("xvals", [one.copy()])])
    assert ref2.member._matching_access(ref1) is False
    ref1 = nodes.StructureReference.create(sym1, [("data", [one.copy()]),
                                                  ("xobs", [one.copy()])])
    ref2 = nodes.StructureReference.create(sym1, [("data", [one.copy()])])
    assert ref2.member._matching_access(ref1) is True
    ref2 = nodes.StructureReference.create(sym1, [("data", [one.copy()]),
                                                  ("yobs", [one.copy()])])
    amem = ref2.member.member  # "yobs"
    assert amem._matching_access(ref1) is False
    # The same 'signature' (a%b%c) but where b is an array access in one
    # case. This may not be possible in Fortran but we need to exercise
    # all conditions.
    ref1 = nodes.StructureReference.create(sym1,
                                           [("a", [one.copy()]), "b", "c"])
    ref2 = nodes.StructureReference.create(sym1, [("a", [one.copy()]),
                                                  ("b", [one.copy()]),
                                                  ("c", [one.copy()])])
    amem = ref2.walk(nodes.ArrayMember)[0]
    assert amem._matching_access(ref1) is False
    # Same 'signature' but with one array access having more dimensions.
    ref1 = nodes.StructureReference.create(sym1, [("a", [one.copy()]),
                                                  ("b", [one.copy()]),
                                                  ("c", [one.copy()])])
    ref2 = nodes.StructureReference.create(
        sym1, [("a", [one.copy()]), ("b", [one.copy(), one.copy()]),
               ("c", [one.copy()])])
    amem = ref2.walk(nodes.ArrayMember)[0]
    assert amem._matching_access(ref1) is False
    # Same 'signature' but with one array access having a different index.
    ref1 = nodes.StructureReference.create(
        sym1, [("a", [one.copy()]), ("b", [one.copy(), one.copy()]),
               ("c", [one.copy()])])
    ref2 = nodes.StructureReference.create(
        sym1, [("a", [one.copy()]), ("b", [one.copy(), two.copy()]),
               ("c", [one.copy()])])
    amem = ref2.walk(nodes.ArrayMember)[0]
    assert amem._matching_access(ref1) is False
    # Reference to an element of the same array
    ref1 = nodes.StructureReference.create(sym1, ["data"])
    ref2 = nodes.StructureReference.create(sym1, [("data", [one.copy()])])
    assert ref2.member._matching_access(ref1) is True
    # Reference to an ArrayOfStructures
    array_sym = symbols.DataSymbol("grids",
                                   symbols.ArrayType(grid_type, [two.copy()]))
    ref1 = nodes.ArrayOfStructuresReference.create(array_sym, [one.copy()],
                                                   ["data"])
    assert ref1._matching_access(nodes.Reference(array_sym))
    # member being compared is not at the bottom of a derived-type access
    ref1 = nodes.StructureReference.create(sym1, [("a", [one.copy()]),
                                                  ("b", [one.copy()]),
                                                  ("d", [one.copy()])])
    ref2 = nodes.StructureReference.create(sym1, [("a", [one.copy()]),
                                                  ("b", [one.copy()]),
                                                  ("c", [one.copy()])])
    amem = ref2.member.member
    assert amem.name == "b"
    assert amem._matching_access(ref1)