40 ''' This module contains the Routine node implementation.'''
51 A sub-class of a Schedule that represents a subroutine, function or
54 :param str name: the name of this routine.
55 :param bool is_program: whether this Routine represents the entry point \
56 into a program (e.g. Fortran Program or C main()).
57 :param kwargs: additional keyword arguments provided to the super class.
58 :type kwargs: unwrapped dict.
60 :raises TypeError: if any of the supplied arguments are of the wrong type.
64 _children_valid_format =
"[Statement]*"
65 _text_name =
"Routine"
67 def __init__(self, name, is_program=False, **kwargs):
68 super().__init__(**kwargs)
71 self.
_name_name =
None
75 if not isinstance(is_program, bool):
76 raise TypeError(f
"Routine argument 'is_program' must be a bool "
77 f
"but got '{type(is_program).__name__}'")
82 Checks whether two nodes are equal. Two Routine nodes are equal
83 if they have the same name, same return symbol, same properties and
84 the inherited __eq__ is True.
86 :param object other: the object to check equality to.
88 :returns: whether other is equal to self.
91 is_eq = super().
__eq__(other)
99 def create(cls, name, symbol_table, children, is_program=False,
100 return_symbol_name=None):
102 '''Create an instance of the supplied class given a name, a symbol
103 table and a list of child nodes. This is implemented as a classmethod
104 so that it is able to act as a Factory for subclasses - e.g. it
105 will create a KernelSchedule if called from KernelSchedule.create().
107 :param str name: the name of the Routine (or subclass).
108 :param symbol_table: the symbol table associated with this Routine.
109 :type symbol_table: :py:class:`psyclone.psyGen.SymbolTable`
110 :param children: a list of PSyIR nodes contained in the Routine.
111 :type children: list of :py:class:`psyclone.psyir.nodes.Node`
112 :param bool is_program: whether this Routine represents the entry \
113 point into a program (i.e. Fortran Program or C main()).
114 :param str return_symbol_name: name of the symbol that holds the \
115 return value of this routine (if any). Must be present in the \
116 supplied symbol table.
118 :returns: an instance of `cls`.
119 :rtype: :py:class:`psyclone.psyGen.Routine` or subclass
121 :raises TypeError: if the arguments to the create method \
122 are not of the expected type.
125 if not isinstance(name, str):
127 f
"name argument in create method of Routine class "
128 f
"should be a string but found '{type(name).__name__}'.")
129 if not isinstance(symbol_table, SymbolTable):
131 f
"symbol_table argument in create method of Routine class "
132 f
"should be a SymbolTable but found "
133 f
"'{type(symbol_table).__name__}'.")
134 if not isinstance(children, list):
136 f
"children argument in create method of Routine class "
137 f
"should be a list but found '{type(children).__name__}'.")
138 for child
in children:
139 if not isinstance(child, Node):
141 f
"child of children argument in create method of "
142 f
"Routine class should be a PSyIR Node but "
143 f
"found '{type(child).__name__}'.")
145 routine = cls(name, is_program=is_program, symbol_table=symbol_table)
146 routine.children = children
147 if return_symbol_name:
148 routine.return_symbol = routine.symbol_table.lookup(
149 return_symbol_name, scope_limit=routine)
153 ''' Returns the name of this node with (optional) control codes
154 to generate coloured output in a terminal that supports it.
156 :param bool colour: whether or not to include colour control codes.
158 :returns: description of this node, possibly coloured.
166 :returns: the name of this node in the dag.
174 :returns: the name of this Routine.
177 return self.
_name_name
180 def name(self, new_name):
182 Sets a new name for the Routine.
184 TODO #1200 this node should only hold a reference to the corresponding
185 RoutineSymbol and get its name from there.
187 :param str new_name: new name for the Routine.
189 :raises TypeError: if new_name is not a string.
190 :raises KeyError: if there already is a different named symbol with \
191 the 'own_routine_tag' in the symbol_table.
194 if not isinstance(new_name, str):
195 raise TypeError(f
"Routine name must be a str but got "
196 f
"'{type(new_name).__name__}'")
201 if not self.
_name_name:
206 'own_routine_symbol', scope_limit=self)
207 if existing_symbol.name.lower() == new_name.lower():
208 self.
_name_name = new_name
212 f
"Can't assign '{new_name}' as the routine name because "
213 f
"its symbol table contains a symbol ({existing_symbol}) "
214 f
"already tagged as 'own_routine_symbol'.")
216 self.
_name_name = new_name
221 tag=
'own_routine_symbol')
222 elif self.
_name_name != new_name:
224 self.
_name_name = new_name
230 result += str(entity) +
"\n"
235 def is_program(self):
237 :returns: whether this Routine represents the entry point into a \
238 program (e.g. is a Fortran Program or a C main()).
244 def return_symbol(self):
246 :returns: the symbol which will hold the return value of this Routine \
247 or None if the Routine is not a function.
248 :rtype: :py:class:`psyclone.psyir.symbols.DataSymbol` or NoneType
252 @return_symbol.setter
253 def return_symbol(self, value):
255 Setter for the return-symbol of this Routine node.
257 :param value: the symbol holding the value that the routine returns.
258 :type value: :py:class:`psyclone.psyir.symbols.DataSymbol`
260 :raises TypeError: if the supplied value is not a DataSymbol.
261 :raises KeyError: if the supplied symbol is not a local entry in the \
262 symbol table of this Routine.
264 if not isinstance(value, DataSymbol):
265 raise TypeError(f
"Routine return-symbol should be a DataSymbol "
266 f
"but found '{type(value).__name__}'.")
269 f
"For a symbol to be a return-symbol, it must be present in "
270 f
"the symbol table of the Routine but '{value.name}' is not.")
277 def _refine_copy(self, other):
278 ''' Refine the object attributes when a shallow copy is not the most
279 appropriate operation during a call to the copy() method.
281 :param other: object we are copying from.
282 :type other: :py:class:`psyclone.psyir.node.Routine`
285 super()._refine_copy(other)
286 if other.return_symbol
is not None:
288 other.return_symbol.name)
292 __all__ = [
"Routine"]
def node_str(self, colour=True)
def coloured_name(self, colour=True)
def return_symbol(self, value)
def node_str(self, colour=True)
def create(cls, name, symbol_table, children, is_program=False, return_symbol_name=None)