Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
integer variable with the supplied name. Return None if no
matching variable is found.
:param str name: the name of the integer variable to find.
:returns: value of the specified integer variable or None.
:rtype: str
:raises ParseError: if the RHS of the assignment is not a Name.
'''
# Ensure the Fortran2003 parser is initialised
_ = ParserFactory().create()
for statement, _ in fpapi.walk(self._ktype, -1):
if isinstance(statement, fparser1.typedecl_statements.Integer):
# fparser only goes down to the statement level. We use
# fparser2 to parse the statement itself (eventually we'll
# use fparser2 to parse the whole thing).
assign = Fortran2003.Assignment_Stmt(
statement.entity_decls[0])
if str(assign.items[0]) == name:
if not isinstance(assign.items[2], Fortran2003.Name):
from psyclone.parse import ParseError
raise ParseError(
"get_integer_variable: RHS of assignment is not "
"a variable name: '{0}'".format(str(assign)))
return str(assign.items[2])
return None
# then we skip it
print("Code {0} contains no assignment statements - skipping".
format(name))
return None
if loop:
# Put the loop variable in our mapping
mapping[loop.var_name] = loop.var_name
digraph.add_assignments(assignments, mapping)
if loop and loop.var_name:
for _ in range(1, unroll_factor):
# Increment the loop counter and then add to the DAG again
digraph.add_assignments(
[Assignment_Stmt("{0} = {0} + 1".format(loop.var_name))],
mapping)
digraph.add_assignments(assignments, mapping)
return digraph
:returns: the top-level Loop object in the created loop nest.
:rtype: :py:class:`psyclone.psyir.nodes.Loop`
:raises InternalError: if the parse tree does not have the expected \
structure.
'''
if isinstance(node, Fortran2003.Where_Stmt):
# We have a Where statement. Check that the parse tree has the
# expected structure.
if not len(node.items) == 2:
raise InternalError(
"Expected a Fortran2003.Where_Stmt to have exactly two "
"entries in 'items' but found {0}: {1}".format(
len(node.items), str(node.items)))
if not isinstance(node.items[1], Fortran2003.Assignment_Stmt):
raise InternalError(
"Expected the second entry of a Fortran2003.Where_Stmt "
"items tuple to be an Assignment_Stmt but found: {0}".
format(type(node.items[1]).__name__))
was_single_stmt = True
annotations = ["was_where", "was_single_stmt"]
logical_expr = [node.items[0]]
else:
# We have a Where construct. Check that the first and last
# children are what we expect.
if not isinstance(node.content[0],
Fortran2003.Where_Construct_Stmt):
raise InternalError("Failed to find opening where construct "
"statement in: {0}".format(str(node)))
if not isinstance(node.content[-1], Fortran2003.End_Where_Stmt):
raise InternalError("Failed to find closing end where "
:rtype: str
:raises ParseError: if the RHS of the assignment is not a Name.
'''
# Ensure the Fortran2003 parser is initialised
_ = ParserFactory().create()
# Fortran is not case sensitive so nor is our matching
lower_name = name.lower()
for statement, _ in fpapi.walk(self._ktype):
if isinstance(statement, fparser1.typedecl_statements.Integer):
# fparser only goes down to the statement level. We use
# fparser2 to parse the statement itself (eventually we'll
# use fparser2 to parse the whole thing).
assign = Fortran2003.Assignment_Stmt(
statement.entity_decls[0])
if str(assign.items[0]).lower() == lower_name:
if not isinstance(assign.items[2], Fortran2003.Name):
raise ParseError(
"get_integer_variable: RHS of assignment is not "
"a variable name: '{0}'".format(str(assign)))
return str(assign.items[2]).lower()
return None
:rtype: str
:raises ParseError: if the RHS of the assignment is not a Name.
'''
# Ensure the Fortran2003 parser is initialised
_ = ParserFactory().create()
# Fortran is not case sensitive so nor is our matching
lower_name = name.lower()
for statement, _ in fpapi.walk(self._ktype, -1):
if isinstance(statement, fparser1.typedecl_statements.Integer):
# fparser only goes down to the statement level. We use
# fparser2 to parse the statement itself (eventually we'll
# use fparser2 to parse the whole thing).
assign = Fortran2003.Assignment_Stmt(
statement.entity_decls[0])
if str(assign.items[0]).lower() == lower_name:
if not isinstance(assign.items[2], Fortran2003.Name):
raise ParseError(
"get_integer_variable: RHS of assignment is not "
"a variable name: '{0}'".format(str(assign)))
return str(assign.items[2]).lower()
return None
:raises ParseError: if the number of items in the array constructor \
does not match the extent of the array.
'''
# Ensure the classes are setup for the Fortran2003 parser
_ = ParserFactory().create()
# Fortran is not case sensitive so nor is our matching
lower_name = name.lower()
for statement, _ in fpapi.walk(self._ktype, -1):
if not isinstance(statement, fparser1.typedecl_statements.Integer):
# This isn't an integer declaration so skip it
continue
# fparser only goes down to the statement level. We use fparser2 to
# parse the statement itself.
assign = Fortran2003.Assignment_Stmt(statement.entity_decls[0])
names = walk(assign.children, Fortran2003.Name)
if not names:
raise InternalError("Unsupported assignment statement: '{0}'".
format(str(assign)))
if str(names[0]).lower() != lower_name:
# This is not the variable declaration we're looking for
continue
if not isinstance(assign.children[0], Fortran2003.Part_Ref):
# Not an array declaration
return []
if not isinstance(assign.children[0].children[1],
Fortran2003.Section_Subscript_List):
raise InternalError(
:return: 3-tuple of list of inputs, list of outputs, list of in-outs
:rtype: (list of str, list of str, list of str)
'''
from fparser.two.Fortran2003 import Assignment_Stmt, Part_Ref, \
Data_Ref, If_Then_Stmt, Array_Section
readers = set()
writers = set()
readwrites = set()
# A dictionary of all array accesses that we encounter - used to
# sanity check the readers and writers we identify.
all_array_refs = {}
# Loop over a flat list of all the nodes in the supplied region
for node in walk(nodes):
if isinstance(node, Assignment_Stmt):
# Found lhs = rhs
structure_name_str = None
lhs = node.items[0]
rhs = node.items[2]
# Do RHS first as we cull readers after writers but want to
# keep a = a + ... as the RHS is computed before assigning
# to the LHS
for node2 in walk(rhs):
if isinstance(node2, Part_Ref):
name = node2.items[0].string
if name.upper() not in FORTRAN_INTRINSICS:
if name not in writers:
readers.add(name)
if isinstance(node2, Data_Ref):
# TODO we need a robust implementation - issue #309.
# Keep a list of variables that are assigned to. This
# enables us to update the name by which they are known
# in the graph.
# e.g.:
# a = b + c
# a = a + 1 => a' = a + 1
# a = a*a => a'' = a' * a'
mapping = {}
# Find all of the assignment statements in the code block
if hasattr(parent_node, "items"):
assignments = walk_ast(parent_node.items, [Assignment_Stmt])
if isinstance(parent_node, Assignment_Stmt):
assignments.append(parent_node)
elif hasattr(parent_node, "content"):
assignments = walk_ast(parent_node.content, [Assignment_Stmt])
if not assignments:
# If this subroutine has no assignment statements
# then we skip it
print("Code {0} contains no assignment statements - skipping".
format(name))
return None
if loop:
# Put the loop variable in our mapping
mapping[loop.var_name] = loop.var_name
digraph.add_assignments(assignments, mapping)
if loop and loop.var_name:
for _ in range(1, unroll_factor):