# HG changeset patch # User paulb@jeremy # Date 1152984205 -7200 # Node ID 71a4bbee763a2cd066f1b0f70519065c7a85fbf5 # Parent 15fb8711f23010139a38625ed49805c41eb075c1 Added Compare, simplified And processing slightly. diff -r 15fb8711f230 -r 71a4bbee763a simplify.py --- a/simplify.py Sat Jul 15 15:29:26 2006 +0200 +++ b/simplify.py Sat Jul 15 19:23:25 2006 +0200 @@ -31,15 +31,16 @@ A simplifying visitor for AST nodes. Covered: And, AssAttr, AssList, AssName, AssTuple, Assign, AugAssign, Break, - CallFunc, Class, Const, Continue, Dict, Discard, For, From, - Function, Getattr, Global, If, Import, Invert, Keyword, Lambda, - List, Module, Name, Not, Or, Pass, Raise, Return, Stmt, TryExcept, - TryFinally, Tuple, While, UnaryAdd, UnarySub. + CallFunc, Class, Compare, Const, Continue, Dict, Discard, For, + From, Function, Getattr, Global, If, Import, Invert, Keyword, + Lambda, List, Module, Name, Not, Or, Pass, Raise, Return, Slice, + Stmt, Subscript, TryExcept, TryFinally, Tuple, While, UnaryAdd, + UnarySub. - Missing: Add, Assert, Backquote, Bitand, Bitor, Bitxor, Compare, Decorators, - Div, Ellipsis, Exec, FloorDiv, LeftShift, ListComp, ListCompFor, - ListCompIf, Mod, Mul, Power, Print, Printnl, RightShift, - Slice, Sliceobj, Sub, Subscript, Yield. + Missing: Add, Assert, Backquote, Bitand, Bitor, Bitxor, Decorators, Div, + Ellipsis, Exec, FloorDiv, LeftShift, ListComp, ListCompFor, + ListCompIf, Mod, Mul, Power, Print, Printnl, RightShift, Sliceobj, + Sub, Yield. """ def __init__(self): @@ -191,7 +192,55 @@ result.args = args return result - # Logical operators. + # Logical and comparison operations. + + comparison_methods = { + "==" : "__eq__", "!=" : "__ne__", "<" : "__lt__", "<=" : "__le__", + ">=" : "__ge__", ">" : "__gt__", "is" : None, "is not" : None + } + + def visitCompare(self, compare): + + # Make a subprogram for the expression and record it outside the main tree. + + subprogram = Subprogram(name=hex(id(compare)), acquire_locals=1, returns_value=1, params=[], star=None, dstar=None) + self.current_subprograms.append(subprogram) + + # In the subprogram, make instructions which invoke a method on the + # first operand of each operand pair and, if appropriate, return with + # the value from that method. + + nodes = [] + last = compare.ops[-1] + previous = self.dispatch(compare.expr) + for op in compare.ops: + op_name, node = op + expr = self.dispatch(node) + method_name = self.comparison_methods[op_name] + if method_name: + invocation = Invoke(expr=LoadAttr(expr=previous, name=method_name), params=[expr], star=None, dstar=None) + elif op_name == "is": + invocation = Invoke(expr=LoadName(name="__is__"), params=[previous, expr], star=None, dstar=None) + elif op_name == "is not": + invocation = Not(expr=Invoke(expr=LoadName(name="__is__"), params=[previous, expr], star=None, dstar=None)) + else: + raise NotImplementedError, op_name + nodes.append(StoreTemp(expr=invocation)) + if op is not last: + nodes.append(Conditional(test=Not(expr=LoadTemp()), body=[Return(expr=LoadTemp())])) + nodes.append(ReleaseTemp()) + else: + nodes.append(Return(expr=LoadTemp())) + subprogram.code = nodes + + self.current_subprograms.pop() + self.subprograms.append(subprogram) + + # Make an invocation of the subprogram. + + result = Invoke(compare, same_frame=1, star=None, dstar=None, args=[]) + result.expr = LoadRef(ref=subprogram) + return result def visitAnd(self, and_): @@ -210,9 +259,8 @@ expr = self.dispatch(node) if node is not last: nodes.append(StoreTemp(expr=expr)) - invocation = Not(expr=Invoke(expr=LoadAttr(expr=LoadTemp(), name="__true__"), - params=[], star=None, dstar=None)) - nodes.append(Conditional(test=invocation, body=[Return(expr=LoadTemp())])) + invocation = Invoke(expr=LoadAttr(expr=LoadTemp(), name="__true__"), params=[], star=None, dstar=None) + nodes.append(Conditional(test=Not(expr=invocation), body=[Return(expr=LoadTemp())])) nodes.append(ReleaseTemp()) else: nodes.append(Return(expr=expr))