184def simplifyExpr(expr, add=None, sub=None):
186 Simplify a numeric expression by combining constants.
191 Expression to simplify (e.g., '1+I+2+JI-I').
193 Expression to add to the result.
195 Expression to subtract from the result.
200 Simplified expression string.
204 >>> simplifyExpr('1+1+I+JI-I')
206 >>> simplifyExpr('X+1', add='Y')
211 - Only handles addition and subtraction.
212 - Does not simplify expressions within parentheses.
216 if re.search(
r'\([^()]*[+-][^()]*\)', expr):
217 raise NotImplementedError(
"Expression cannot (yet) contain + or - sign inside " +
218 f
"parenthesis: {expr}")
223 :return: a list of (sign, abs(value))
226 splt = re.split(
'([+-])', expr.replace(
' ',
'').upper())
230 if len(splt) % 2 == 1:
234 splt = [(splt[2 * i], splt[2 * i + 1])
for i
in range(len(splt) // 2)]
241 splt += [(
'-' if sign ==
'+' else '+', elem)
for (sign, elem)
in split(sub)]
243 for sign, elem
in splt.copy():
244 if (
'+', elem)
in splt
and (
'-', elem)
in splt:
245 splt.remove((
'+', elem))
246 splt.remove((
'-', elem))
249 for i, (sign, elem)
in enumerate(splt.copy()):
254 result = str((1
if splt[found][0] ==
'+' else -1) * int(splt[found][1]) +
255 (1
if sign ==
'+' else -1) * int(elem))
256 splt[found] = split(str(result))[0]
259 splt.sort(key=
''.join)
264 result =
' '.join(s[0] +
' ' + s[1]
for s
in splt)
265 if result.startswith(
'+'):
267 return result.lstrip(
' ')
271def createArrayBounds(lowerBoundstr, upperBoundstr, context):
273 Return a lower-bound and upper-bound node
274 :param lowerBoundstr: string for the fortran lower bound of an array
275 :param upperBoundstr: string for the fortran upper bound of an array
276 :param context: 'DO' for DO loops
277 'DOCONCURRENT' for DO CONCURRENT loops
280 lowerBound = createElem(
'lower-bound')
281 lowerBound.insert(0, createExprPart(lowerBoundstr))
282 upperBound = createElem(
'upper-bound')
283 upperBound.insert(0, createExprPart(upperBoundstr))
285 lowerBound.tail =
', '
286 elif context
in (
'DOCONCURRENT',
'ARRAY'):
287 lowerBound.tail =
':'
289 raise PYFTError(f
'Context unknown in createArrayBounds: {context}')
290 return lowerBound, upperBound