Reference Guide  2.5.0
codeblock.py
1 # -----------------------------------------------------------------------------
2 # BSD 3-Clause License
3 #
4 # Copyright (c) 2017-2024, Science and Technology Facilities Council.
5 # All rights reserved.
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions are met:
9 #
10 # * Redistributions of source code must retain the above copyright notice, this
11 # list of conditions and the following disclaimer.
12 #
13 # * Redistributions in binary form must reproduce the above copyright notice,
14 # this list of conditions and the following disclaimer in the documentation
15 # and/or other materials provided with the distribution.
16 #
17 # * Neither the name of the copyright holder nor the names of its
18 # contributors may be used to endorse or promote products derived from
19 # this software without specific prior written permission.
20 #
21 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 # POSSIBILITY OF SUCH DAMAGE.
33 # -----------------------------------------------------------------------------
34 # Authors R. W. Ford, A. R. Porter and S. Siso, STFC Daresbury Lab
35 # I. Kavcic, Met Office
36 # J. Henrichs, Bureau of Meteorology
37 # -----------------------------------------------------------------------------
38 
39 ''' This module contains the CodeBlock node implementation.'''
40 
41 from enum import Enum
42 from fparser.two import Fortran2003
43 from fparser.two.utils import walk
44 from psyclone.psyir.nodes.statement import Statement
45 from psyclone.psyir.nodes.datanode import DataNode
46 
47 
49  '''Node representing some generic Fortran code that PSyclone does not
50  attempt to manipulate. As such it is a leaf in the PSyIR and therefore
51  has no children.
52 
53  :param fp2_nodes: list of fparser2 AST nodes representing the Fortran \
54  code constituting the code block.
55  :type fp2_nodes: list of :py:class:`fparser.two.utils.Base`
56  :param structure: argument indicating whether this code block is a \
57  statement or an expression.
58  :type structure: :py:class:`psyclone.psyir.nodes.CodeBlock.Structure`
59  :param parent: the parent node of this code block in the PSyIR.
60  :type parent: :py:class:`psyclone.psyir.nodes.Node`
61  :param annotations: tags that provide additional information about \
62  the node. The node should still be functionally correct when \
63  ignoring these tags.
64  :type annotations: list of str or NoneType
65 
66  '''
67  #: Textual description of the node.
68  _children_valid_format = "<LeafNode>"
69  _text_name = "CodeBlock"
70  _colour = "red"
71  #: The annotations that are supported by this node.
72  #: psy-data-start - this node has replaced a PSyDataNode during the
73  #: lowering of the PSyIR to language level.
74  valid_annotations = ("psy-data-start")
75 
76  class Structure(Enum):
77  '''
78  Enumeration that captures the structure of the code block which
79  may be required when processing.
80 
81  '''
82  # The Code Block comprises one or more Fortran statements
83  # (which themselves may contain expressions).
84  STATEMENT = 1
85  # The Code Block comprises one or more Fortran expressions.
86  EXPRESSION = 2
87 
88  def __init__(self, fp2_nodes, structure, parent=None, annotations=None):
89  super(CodeBlock, self).__init__(parent=parent, annotations=annotations)
90  # Store a list of the parser objects holding the code associated
91  # with this block. We make a copy of the contents of the list because
92  # the list itself is a temporary product of the process of converting
93  # from the fparser2 AST to the PSyIR.
94  self._fp2_nodes = fp2_nodes[:]
95  # Store references back into the fparser2 AST
96  if fp2_nodes:
97  self.ast = self._fp2_nodes[0]
98  self.ast_end = self._fp2_nodes[-1]
99  else:
100  self.ast = None
101  self.ast_end = None
102  # Store the structure of the code block.
103  self._structure = structure
104 
105  def __eq__(self, other):
106  '''
107  Checks whether two nodes are equal. Two CodeBlock nodes are equal
108  if they are the same type, their ast_nodes lists are equal (which
109  means the same instance) and have the same structure.
110 
111  :param object other: the object to check equality to.
112 
113  :returns: whether other is equal to self.
114  :rtype: bool
115  '''
116  is_eq = super().__eq__(other)
117  is_eq = is_eq and self.get_ast_nodesget_ast_nodesget_ast_nodes == other.get_ast_nodes
118  is_eq = is_eq and self.structurestructurestructure == other.structure
119 
120  return is_eq
121 
122  @property
123  def structure(self):
124  '''
125  :returns: whether this code block is a statement or an expression.
126  :rtype: :py:class:`psyclone.psyir.nodes.CodeBlock.Structure`
127 
128  '''
129  return self._structure_structure
130 
131  @property
132  def get_ast_nodes(self):
133  '''
134  :returns: the list of nodes associated with this code block in \
135  the original AST.
136  :rtype: list of subclass of \
137  `:py:classfparser.two.Fortran2003.Base`
138 
139  '''
140  return self._fp2_nodes_fp2_nodes
141 
142  def node_str(self, colour=True):
143  ''' Create a text description of this node in the schedule, optionally
144  including control codes for colour.
145 
146  :param bool colour: whether or not to include control codes for colour.
147 
148  :return: text description of this node.
149  :rtype: str
150  '''
151  return self.coloured_namecoloured_name(colour) + \
152  "[" + str(list(map(type, self._fp2_nodes_fp2_nodes))) + "]"
153 
154  def get_symbol_names(self):
155  '''
156  :returns: the list of symbol names used inside the CodeBock.
157  :rtype: list of str
158  '''
159  parse_tree = self.get_ast_nodesget_ast_nodesget_ast_nodes
160  return [node.string for node in walk(parse_tree, Fortran2003.Name)]
161 
162  def __str__(self):
163  return f"CodeBlock[{len(self._fp2_nodes)} nodes]"
def coloured_name(self, colour=True)
Definition: node.py:453
def walk(self, my_type, stop_type=None, depth=None)
Definition: node.py:1075