39 ''' This module contains the DataSymbol and its interfaces.'''
47 Symbol identifying a data element. It contains information about:
48 the datatype, the shape (in column-major order) and the interface
49 to that symbol (i.e. Local, Global, Argument).
51 :param str name: name of the symbol.
52 :param datatype: data type of the symbol.
53 :type datatype: :py:class:`psyclone.psyir.symbols.DataType`
54 :param bool is_constant: whether this DataSymbol is a compile-time
55 constant (default is False). If True then an `initial_value` must
57 :param initial_value: sets a fixed known expression as an initial
58 value for this DataSymbol. If `is_constant` is True then this
59 Symbol will always have this value. If the value is None then this
60 symbol does not have an initial value (and cannot be a constant).
61 Otherwise it can receive PSyIR expressions or Python intrinsic types
62 available in the TYPE_MAP_TO_PYTHON map. By default it is None.
63 :type initial_value: Optional[item of TYPE_MAP_TO_PYTHON |
64 :py:class:`psyclone.psyir.nodes.Node`]
65 :param kwargs: additional keyword arguments provided by
66 :py:class:`psyclone.psyir.symbols.TypedSymbol`
67 :type kwargs: unwrapped dict.
70 def __init__(self, name, datatype, is_constant=False, initial_value=None,
72 super().__init__(name, datatype)
76 initial_value=initial_value,
79 def _process_arguments(self, **kwargs):
80 ''' Process the arguments for the constructor and the specialise
81 methods. In this case the initial_value and is_constant arguments.
83 :param kwargs: keyword arguments which can be:\n
84 :param bool is_constant: whether this DataSymbol is a compile-time
85 constant (default is False). If True then an `initial_value`
86 must also be provided.\n
87 :param initial_value: sets a fixed known expression as an initial
88 value for this DataSymbol. If `is_constant` is True then this
89 Symbol will always have this value. If the value is None then
90 this symbol does not have an initial value (and cannot be a
91 constant). Otherwise it can receive PSyIR expressions or Python
92 intrinsic types available in the TYPE_MAP_TO_PYTHON map. By
94 :type initial_value: Optional[item of TYPE_MAP_TO_PYTHON |
95 :py:class:`psyclone.psyir.nodes.Node`]\n
96 and the arguments in :py:class:`psyclone.psyir.symbols.TypedSymbol`
97 :type kwargs: unwrapped dict.
99 :raises ValueError: if the symbol is a run-time constant but is not
100 given an initial value.
101 :raises ValueError: if the symbol is a run-time constant and an
102 interface other than StaticInterface is specified.
104 new_initial_value =
None
105 new_is_constant_value =
None
113 if "initial_value" in kwargs:
114 new_initial_value = kwargs.pop(
"initial_value")
115 if not hasattr(self,
'_initial_value'):
121 if "is_constant" in kwargs:
122 new_is_constant_value = kwargs.pop(
"is_constant")
123 if not hasattr(self,
'_is_constant'):
131 interface_supplied =
"interface" in kwargs
133 super()._process_arguments(**kwargs)
137 if new_initial_value
is not None:
142 if new_is_constant_value
is not None:
152 def is_constant(self):
154 :returns: Whether the symbol is a compile-time constant (True) or
161 def is_constant(self, value):
163 :param bool value: whether or not this symbol is a compile-time
166 :raises ValueError: if `value` is True but this symbol does not have an
167 initial value or an import or unresolved interface.
178 f
"DataSymbol '{self.name}' cannot be a constant because it"
179 f
" does not have an initial value or an import or "
180 f
"unresolved interface.")
184 def initial_value(self):
186 :returns: the initial value associated with this symbol (if any).
187 :rtype: :py:class:`psyclone.psyir.nodes.Node`
192 @initial_value.setter
193 def initial_value(self, new_value):
195 :param new_value: set or change the initial value associated
196 with this DataSymbol. If the value is None then this symbol does
197 not have an initial value (and cannot be a constant). Otherwise it
198 can receive PSyIR expressions or Python intrinsic types available
199 in the TYPE_MAP_TO_PYTHON map.
200 :type new_value: Optional[item of TYPE_MAP_TO_PYTHON |
201 :py:class:`psyclone.psyir.nodes.Node`]
203 :raises ValueError: if a non-None value is provided and 1) this
204 DataSymbol instance represents an argument, or 2) this
205 DataSymbol instance is not a scalar (as the shape attribute is
206 not empty), or 3) an initial value is provided but the type of
207 the value is not supported, or 4) the type of the value
208 provided is not compatible with the datatype of this DataSymbol
209 instance, or 5) the provided PSyIR expression is unsupported.
210 :raises ValueError: if a None value is provided and this DataSymbol
211 represents a constant and is not imported.
216 CodeBlock, IntrinsicCall)
220 if new_value
is not None:
223 f
"Error setting initial value for symbol '{self.name}'. "
224 f
"A DataSymbol with an ArgumentInterface can not have an "
227 (ScalarType, ArrayType, UnsupportedType)):
229 f
"Error setting initial value for symbol '{self.name}'. "
230 f
"A DataSymbol with an initial value must be a scalar or "
231 f
"an array or of UnsupportedType but found "
232 f
"'{type(self.datatype).__name__}'.")
234 if isinstance(new_value, Node):
235 for node
in new_value.walk(Node):
236 if not isinstance(node, (Literal, Operation, Reference,
237 CodeBlock, IntrinsicCall)):
239 f
"Error setting initial value for symbol "
240 f
"'{self.name}'. PSyIR static expressions can only"
241 f
" contain PSyIR Literal, Operation, Reference,"
242 f
" IntrinsicCall or CodeBlock nodes but found: "
244 new_initial_value = new_value
251 if not isinstance(new_value, lookup):
253 f
"Error setting initial value for symbol "
254 f
"'{self.name}'. This DataSymbol instance datatype is "
255 f
"'{self.datatype}' meaning the initial value should "
256 f
"be '{lookup}' but found '{type(new_value)}'.")
276 parent = Assignment()
277 parent.addchild(Reference(self))
278 parent.addchild(new_initial_value)
283 f
"DataSymbol '{self.name}' is a constant and not imported "
284 f
"and therefore must have an initial value but got None")
291 ret += f
", initial_value={self.initial_value}"
293 ret +=
", constant=True"
297 '''Create and return a copy of this object. Any references to the
298 original will not be affected so the copy will not be referred
299 to by any other object.
301 :returns: An object with the same properties as this symbol object.
302 :rtype: :py:class:`psyclone.psyir.symbols.DataSymbol`
308 new_init_value =
None
312 initial_value=new_init_value)
315 '''Replace all properties in this object with the properties from
316 symbol_in, apart from the name (which is immutable) and visibility.
318 :param symbol_in: the symbol from which the properties are copied.
319 :type symbol_in: :py:class:`psyclone.psyir.symbols.DataSymbol`
321 :raises TypeError: if the argument is not the expected type.
324 if not isinstance(symbol_in, DataSymbol):
325 raise TypeError(f
"Argument should be of type 'DataSymbol' but "
326 f
"found '{type(symbol_in).__name__}'.")
def is_constant(self, value)
def initial_value(self, new_value)
def _process_arguments(self, **kwargs)
def copy_properties(self, symbol_in)
def visibility(self, value)
def _process_arguments(self, visibility=None, interface=None)
def interface(self, value)
def datatype(self, value)
def _process_arguments(self, **kwargs)