From 4251d4c7f937c5f92521a6cab0c0dad1a1bc33a8 Mon Sep 17 00:00:00 2001 From: Sei Lisa Date: Fri, 3 Nov 2017 00:12:10 +0100 Subject: [PATCH] Improve CompareTrees. Reorganize into different statements with early return. Add constants, unary operators and binary operators. Check if operator is commutative and check with operands swapped when so. Constant equality is somewhat sketchy at the moment: just compare the values with Python's ==. --- lslopt/lslfoldconst.py | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/lslopt/lslfoldconst.py b/lslopt/lslfoldconst.py index 3ec0812..be35840 100644 --- a/lslopt/lslfoldconst.py +++ b/lslopt/lslfoldconst.py @@ -130,21 +130,49 @@ class foldconst(object): # They MUST be SEF and stable. if 'SEF' not in node1 or 'SEF' not in node2: return False - # So far it's only accepted if both are identifiers or function calls, - # recursively. - return (node1['nt'] == node2['nt'] == 'IDENT' + if node1['t'] != node2['t']: + return False + # It's not complete yet. + nt1 = node1['nt'] + if nt1 == node2['nt']: + if (nt1 == 'IDENT' and node1['name'] == node2['name'] and node1['scope'] == node2['scope'] - or node1['nt'] == node2['nt'] == 'FNCALL' + ): + return True + if (nt1 == 'FNCALL' and node1['name'] == node2['name'] and 'uns' not in self.symtab[0][node1['name']] and all(self.CompareTrees(node1['ch'][i], node2['ch'][i]) for i in xrange(len(node1['ch']))) - or node1['nt'] == node2['nt'] == 'CAST' - and node1['t'] == node2['t'] + ): + return True + if (nt1 == 'CAST' and self.CompareTrees(node1['ch'][0], node2['ch'][0]) - ) + ): + return True + if nt1 == 'CONST' and node1['value'] == node2['value']: + return True + if (nt1 in ('!', '~', 'NEG') + and self.CompareTrees(node1['ch'][0], node2['ch'][0]) + ): + return True + if (nt1 in self.binary_ops + and self.CompareTrees(node1['ch'][0], node2['ch'][0]) + and self.CompareTrees(node1['ch'][1], node2['ch'][1]) + ): + return True + if ((nt1 in ('*', '^', '&', '|', '==') # commutative + or nt1 == '+' + and node1['ch'][0]['t'] not in ('list', 'string') + and node2['ch'][0]['t'] not in ('list', 'string') + ) + and self.CompareTrees(node1['ch'][0], node2['ch'][1]) + and self.CompareTrees(node1['ch'][1], node2['ch'][0]) + ): + return True + return False def FnSEF(self, node): '''Applied to function call nodes, return whether the node corresponds