2.1 --- a/simplify.py Wed Feb 14 18:33:08 2007 +0100
2.2 +++ b/simplify.py Wed Feb 14 21:57:46 2007 +0100
2.3 @@ -491,8 +491,14 @@
2.4 return result
2.5
2.6 comparison_methods = {
2.7 - "==" : "__eq__", "!=" : "__ne__", "<" : "__lt__", "<=" : "__le__",
2.8 - ">=" : "__ge__", ">" : "__gt__", "is" : None, "is not" : None
2.9 + "==" : ("__eq__", "__ne__"),
2.10 + "!=" : ("__ne__", "__eq__"),
2.11 + "<" : ("__lt__", "__gt__"),
2.12 + "<=" : ("__le__", "__ge__"),
2.13 + ">=" : ("__ge__", "__le__"),
2.14 + ">" : ("__gt__", "__lt__"),
2.15 + "is" : None,
2.16 + "is not" : None
2.17 }
2.18
2.19 def visitCompare(self, compare):
2.20 @@ -529,24 +535,22 @@
2.21
2.22 for op in compare.ops:
2.23 op_name, node = op
2.24 +
2.25 + # Make a new AST-style node to wrap the operation program nodes.
2.26 +
2.27 + new_op = Op(op_name, node)
2.28 expr = self.dispatch(node)
2.29
2.30 # Identify the operation and produce the appropriate method call.
2.31
2.32 - method_name = self.comparison_methods[op_name]
2.33 - if method_name:
2.34 - invocation = InvokeFunction(
2.35 - compare,
2.36 - expr=LoadAttr(
2.37 - expr=previous,
2.38 - name=method_name),
2.39 - args=[expr],
2.40 - star=None,
2.41 - dstar=None)
2.42 + method_names = self.comparison_methods[op_name]
2.43 + if method_names:
2.44 + first_name, alternative_name = method_names
2.45 + invocation = self._visitBinaryOp(new_op, previous, expr, first_name, alternative_name)
2.46
2.47 elif op_name == "is":
2.48 invocation = InvokeFunction(
2.49 - compare,
2.50 + new_op, 1,
2.51 expr=LoadName(name="__is__"),
2.52 args=[previous, expr],
2.53 star=None,
2.54 @@ -554,8 +558,9 @@
2.55
2.56 elif op_name == "is not":
2.57 invocation = Not(
2.58 + new_op, 1,
2.59 expr=InvokeFunction(
2.60 - compare,
2.61 + new_op,
2.62 expr=LoadName(name="__is__"),
2.63 args=[previous, expr],
2.64 star=None,
2.65 @@ -565,7 +570,7 @@
2.66 raise NotImplementedError, op_name
2.67
2.68 nodes.append(StoreTemp(expr=invocation))
2.69 - compare._ops.append(invocation)
2.70 + compare._ops.append(new_op)
2.71
2.72 # Return from the subprogram where the test is not satisfied.
2.73
2.74 @@ -1423,6 +1428,9 @@
2.75 # Convenience methods.
2.76
2.77 def _visitBinary(self, binary, left_name, right_name):
2.78 + return self._visitBinaryOp(binary, self.dispatch(binary.left), self.dispatch(binary.right), left_name, right_name)
2.79 +
2.80 + def _visitBinaryOp(self, binary, left, right, left_name, right_name):
2.81
2.82 """
2.83 Emulate the current mechanisms by producing nodes as follows:
2.84 @@ -1444,8 +1452,8 @@
2.85 ReturnFromBlock(
2.86 expr=InvokeFunction(
2.87 binary,
2.88 - expr=LoadAttr(expr=self.dispatch(binary.left), name=left_name),
2.89 - args=[self.dispatch(binary.right)],
2.90 + expr=LoadAttr(expr=left, name=left_name),
2.91 + args=[right],
2.92 star=None,
2.93 dstar=None)
2.94 )
2.95 @@ -1459,8 +1467,8 @@
2.96 ReturnFromBlock(
2.97 expr=InvokeFunction(
2.98 binary,
2.99 - expr=LoadAttr(expr=self.dispatch(binary.right), name=right_name),
2.100 - args=[self.dispatch(binary.left)],
2.101 + expr=LoadAttr(expr=right, name=right_name),
2.102 + args=[left],
2.103 star=None,
2.104 dstar=None)
2.105 )
3.1 --- a/viewer.py Wed Feb 14 18:33:08 2007 +0100
3.2 +++ b/viewer.py Wed Feb 14 21:57:46 2007 +0100
3.3 @@ -632,14 +632,14 @@
3.4 def visitCompare(self, node):
3.5 self.stream.write("<span class='compare'>\n")
3.6 self.dispatch(node.expr)
3.7 - for (op_name, expr), _op in map(None, node.ops, node._ops):
3.8 + for op in node._ops:
3.9 self.stream.write("<span class='op'>\n")
3.10 - self.stream.write(op_name)
3.11 + self.stream.write(op.name)
3.12 self._popup_start()
3.13 - self._op(op_name, _op)
3.14 + self._op(op)
3.15 self._popup_end()
3.16 self.stream.write("</span>\n")
3.17 - self.dispatch(expr)
3.18 + self.dispatch(op.expr)
3.19 self.stream.write("</span>\n")
3.20
3.21 def visitConst(self, node):
3.22 @@ -905,12 +905,17 @@
3.23 def _popup_end(self):
3.24 self.stream.write("</span>\n")
3.25
3.26 - def _op(self, op_name, op):
3.27 - if op is not None:
3.28 - if isinstance(op, Not):
3.29 - self._invocations(op.expr)
3.30 - else:
3.31 - self._invocations(op)
3.32 + def _op(self, node):
3.33 + self.stream.write("<div class='invocations'>\n")
3.34 + if hasattr(node, "_left_call") and hasattr(node, "_right_call"):
3.35 + self._invocations_list(node._left_call)
3.36 + self._invocations_list(node._right_call)
3.37 + else:
3.38 + _node = node._node
3.39 + if isinstance(_node, Not):
3.40 + _node = _node.expr
3.41 + self._invocations_list(_node)
3.42 + self.stream.write("</div>\n")
3.43
3.44 def _invocations(self, node):
3.45 self.stream.write("<div class='invocations'>\n")