179def simplifyExpr(expr, add=None, sub=None):
181 Simplify a numeric expression by combining constants.
186 Expression to simplify (e.g., '1+I+2+JI-I').
188 Expression to add to the result.
190 Expression to subtract from the result.
195 Simplified expression string.
199 >>> simplifyExpr('1+1+I+JI-I')
201 >>> simplifyExpr('X+1', add='Y')
206 - Only handles addition and subtraction.
207 - Does not simplify expressions within parentheses.
211 if re.search(
r'\([^()]*[+-][^()]*\)', expr):
212 raise NotImplementedError(
"Expression cannot (yet) contain + or - sign inside " +
213 f
"parenthesis: {expr}")
218 :return: a list of (sign, abs(value))
221 splt = re.split(
'([+-])', expr.replace(
' ',
'').upper())
225 if len(splt) % 2 == 1:
229 splt = [(splt[2 * i], splt[2 * i + 1])
for i
in range(len(splt) // 2)]
236 splt += [(
'-' if sign ==
'+' else '+', elem)
for (sign, elem)
in split(sub)]
238 for sign, elem
in splt.copy():
239 if (
'+', elem)
in splt
and (
'-', elem)
in splt:
240 splt.remove((
'+', elem))
241 splt.remove((
'-', elem))
244 for i, (sign, elem)
in enumerate(splt.copy()):
249 result = str((1
if splt[found][0] ==
'+' else -1) * int(splt[found][1]) +
250 (1
if sign ==
'+' else -1) * int(elem))
251 splt[found] = split(str(result))[0]
254 splt.sort(key=
''.join)
259 result =
' '.join(s[0] +
' ' + s[1]
for s
in splt)
260 if result.startswith(
'+'):
262 return result.lstrip(
' ')
266def createArrayBounds(lowerBoundstr, upperBoundstr, context):
268 Return a lower-bound and upper-bound node
269 :param lowerBoundstr: string for the fortran lower bound of an array
270 :param upperBoundstr: string for the fortran upper bound of an array
271 :param context: 'DO' for DO loops
272 'DOCONCURRENT' for DO CONCURRENT loops
275 lowerBound = createElem(
'lower-bound')
276 lowerBound.insert(0, createExprPart(lowerBoundstr))
277 upperBound = createElem(
'upper-bound')
278 upperBound.insert(0, createExprPart(upperBoundstr))
280 lowerBound.tail =
', '
281 elif context
in (
'DOCONCURRENT',
'ARRAY'):
282 lowerBound.tail =
':'
284 raise PYFTError(f
'Context unknown in createArrayBounds: {context}')
285 return lowerBound, upperBound