39 '''This module provides management of variable access information.'''
47 '''Given a variable access of the form ``a(i,j)%b(k,l)%c``, the signature
48 of this access is the tuple ``(a,b,c)``. For a simple scalar variable
49 ``a`` the signature would just be ``(a,)``.
50 The signature is the key used in `VariablesAccessInfo`. In order to make
51 sure two different signature objects containing the same variable
52 can be used as a key, this class implements `__hash__` and other special
54 The constructor also supports appending an existing signature to this
55 new signature using the `sub_sig` argument. This is used in
56 StructureReference to assemble the overall signature of a structure
59 :param variable: the variable that is accessed.
60 :type variable: str or tuple of str or list of str
62 :param sub_sig: a signature that is to be added to this new signature.
63 :type sub_sig: :py:class:`psyclone.core.Signature`
66 def __init__(self, variable, sub_sig=None):
68 sub_tuple = sub_sig._signature
72 if isinstance(variable, str):
73 self.
_signature_signature = tuple(variable.split(
"%")) + sub_tuple
74 elif isinstance(variable, tuple):
75 self.
_signature_signature = variable + sub_tuple
76 elif isinstance(variable, list):
77 self.
_signature_signature = tuple(variable) + sub_tuple
78 elif isinstance(variable, Signature):
79 self.
_signature_signature = variable._signature + sub_tuple
82 f
"'{type(variable).__name__}' in Signature "
88 ''':returns: True if this signature represents a structure.
95 ''':returns: the number of components of this signature.
100 def __getitem__(self, indx):
101 if isinstance(indx, slice):
110 def to_language(self, component_indices=None, language_writer=None):
112 '''Converts this signature with the provided indices to a string
113 in the selected language.
115 TODO 1320 This subroutine can be removed when we stop supporting
116 strings - then we can use a PSyIR writer for the ReferenceNode
117 to provide the right string.
119 :param component_indices: the indices for each component of \
121 :type component_indices: None (default is scalar access), or \
122 :py:class:`psyclone.core.component_indices.ComponentIndices`
123 :param language_writer: a backend visitor to convert PSyIR \
124 expressions to a representation in the selected language. \
125 This is used when creating error and warning messages.
126 :type language_writer: None (default is Fortran), or an instance of \
127 :py:class:`psyclone.psyir.backend.language_writer.LanguageWriter`
129 :raises InternalError: if the number of components in this signature \
130 is different from the number of indices in component_indices.
138 if component_indices
is None:
143 if len(self.
_signature_signature) != len(component_indices):
145 f
"components, but component_indices "
146 f
"{component_indices} has "
147 f
"{len(component_indices)}.")
153 if language_writer
is None:
154 writer = DebugWriter()
156 writer = language_writer
161 for i, component
in enumerate(self.
_signature_signature):
162 indices = component_indices[i]
164 out_list.append(component)
173 for dimension
in indices:
174 if isinstance(dimension, Node):
175 index_list.append(dimension)
176 elif isinstance(dimension, int):
177 index_list.append(Literal(str(dimension),
180 ref = Reference(DataSymbol(dimension, INTEGER_TYPE))
181 index_list.append(ref)
182 dims = writer.gen_indices(index_list, component)
184 parenthesis = writer.array_parenthesis
185 out_list.append(component + parenthesis[0] +
190 return writer.structure_character.join(out_list)
194 return f
"Signature({str(self)})"
198 '''This returns a hash value that is independent of the instance.
199 I.e. two instances with the same signature will have the same
206 '''Required in order to use a Signature instance as a key.
207 Compares two objects (one of which might not be a Signature).'''
208 if not hasattr(other,
"_signature"):
210 return self.
_signature_signature == other._signature
214 '''Required for != comparisons of Signatures with python2.
215 Compares two objects (one of which might not be a Signature).'''
216 if not hasattr(other,
"_signature"):
218 return self.
_signature_signature != other._signature
222 '''Required to sort signatures. It just compares the tuples.'''
223 if not isinstance(other, Signature):
224 raise TypeError(f
"'<' not supported between instances of "
225 f
"'Signature' and '{type(other).__name__}'.")
226 return self.
_signature_signature < other._signature
230 '''Required to compare signatures. It just compares the tuples.'''
231 if not isinstance(other, Signature):
232 raise TypeError(f
"'<=' not supported between instances of "
233 f
"'Signature' and '{type(other).__name__}'.")
234 return self.
_signature_signature <= other._signature
238 '''Required to compare signatures. It just compares the tuples.'''
239 if not isinstance(other, Signature):
240 raise TypeError(f
"'>' not supported between instances of "
241 f
"'Signature' and '{type(other).__name__}'.")
242 return self.
_signature_signature > other._signature
246 '''Required to compare signatures. It just compares the tuples.'''
247 if not isinstance(other, Signature):
248 raise TypeError(f
"'>=' not supported between instances of "
249 f
"'Signature' and '{type(other).__name__}'.")
250 return self.
_signature_signature >= other._signature
255 ''':returns: the actual variable name, i.e. the first component of
265 __all__ = [
"Signature"]
def to_language(self, component_indices=None, language_writer=None)