1.1 --- a/simplify.py Fri Feb 23 00:12:44 2007 +0100
1.2 +++ b/simplify.py Fri Feb 23 01:29:50 2007 +0100
1.3 @@ -48,15 +48,16 @@
1.4 A simplifying visitor for AST nodes.
1.5
1.6 Covered: Add, And, Assert, AssAttr, AssList, AssName, AssTuple, Assign,
1.7 - AugAssign, Break, CallFunc, Class, Compare, Const, Continue, Dict,
1.8 - Discard, Div, FloorDiv, For, From, Function, Getattr, Global, If,
1.9 - Import, Invert, Keyword, Lambda, List, ListComp, ListCompFor,
1.10 - ListCompIf, Mod, Module, Mul, Name, Not, Or, Pass, Power, Print,
1.11 - Printnl, Raise, Return, Slice, Sliceobj, Stmt, Sub, Subscript,
1.12 - TryExcept, TryFinally, Tuple, While, UnaryAdd, UnarySub.
1.13 + AugAssign, Bitand, Break, CallFunc, Class, Compare, Const,
1.14 + Continue, Dict, Discard, Div, FloorDiv, For, From, Function,
1.15 + Getattr, Global, If, Import, Invert, Keyword, Lambda, List,
1.16 + ListComp, ListCompFor, ListCompIf, Mod, Module, Mul, Name, Not, Or,
1.17 + Pass, Power, Print, Printnl, Raise, Return, Slice, Sliceobj, Stmt,
1.18 + Sub, Subscript, TryExcept, TryFinally, Tuple, While, UnaryAdd,
1.19 + UnarySub.
1.20
1.21 - Missing: Backquote, Bitand, Bitor, Bitxor, Decorators, Ellipsis,
1.22 - Exec, LeftShift, RightShift, Yield.
1.23 + Missing: Backquote, Bitor, Bitxor, Decorators, Ellipsis, Exec, LeftShift,
1.24 + RightShift, Yield.
1.25 """
1.26
1.27 def __init__(self, builtins=0):
1.28 @@ -457,6 +458,95 @@
1.29
1.30 return result
1.31
1.32 + def visitBitand(self, bitand):
1.33 +
1.34 + """
1.35 + Make a subprogram for the 'bitand' node and record its contents inside the
1.36 + subprogram. Convert...
1.37 +
1.38 + Bitand (node)
1.39 + (node)
1.40 + ...
1.41 +
1.42 + ...to:
1.43 +
1.44 + Subprogram -> Conditional (test) -> ReturnFromBlock ...
1.45 + (else) -> Conditional (test) -> ReturnFromBlock ...
1.46 + (else) -> ...
1.47 + """
1.48 +
1.49 + subprogram = Subprogram(name=None, module=self.module, internal=1, returns_value=1, params=[], star=None, dstar=None)
1.50 + self.current_subprograms.append(subprogram)
1.51 +
1.52 + # In the subprogram, make instructions which store each operand, test
1.53 + # for each operand's truth status, and if appropriate return from the
1.54 + # subprogram with the value of the operand.
1.55 +
1.56 + last = bitand.nodes[-1]
1.57 + results = nodes = []
1.58 +
1.59 + # Start by storing the first operand.
1.60 +
1.61 + nodes += [
1.62 + StoreTemp(expr=self.dispatch(bitand.nodes[0]))
1.63 + ]
1.64 +
1.65 + # For viewing purposes, record invocations on the AST node.
1.66 +
1.67 + bitand._ops = []
1.68 +
1.69 + for node in bitand.nodes[1:]:
1.70 +
1.71 + # Make a new AST-style node to wrap the operation program nodes.
1.72 +
1.73 + new_op = Op("&", node)
1.74 + bitand._ops.append(new_op)
1.75 +
1.76 + # Generate the operation involving the previous result and the
1.77 + # current operand.
1.78 +
1.79 + expr = self._visitBinaryOp(new_op, LoadTemp(), self.dispatch(node), "__and__", "__rand__")
1.80 +
1.81 + # Return from the subprogram where the test is not satisfied.
1.82 +
1.83 + if node is not last:
1.84 + nodes += [
1.85 + StoreTemp(expr=expr),
1.86 + Conditional(
1.87 + test=self._visitNot(LoadTemp()),
1.88 + body=[
1.89 + ReturnFromBlock(
1.90 + expr=LoadTemp()
1.91 + )
1.92 + ],
1.93 + else_=[
1.94 + # Subsequent operations go here!
1.95 + ]
1.96 + )
1.97 + ]
1.98 +
1.99 + # Put subsequent operations in the else section of this conditional.
1.100 +
1.101 + nodes = nodes[-1].else_
1.102 +
1.103 + # For the last operation, return the result.
1.104 +
1.105 + else:
1.106 + nodes.append(ReturnFromBlock(expr=expr))
1.107 +
1.108 + # Finish the subprogram definition.
1.109 +
1.110 + subprogram.code = results
1.111 +
1.112 + self.current_subprograms.pop()
1.113 + self.subprograms.append(subprogram); self.subnames[subprogram.full_name()] = subprogram
1.114 +
1.115 + # Make an invocation of the subprogram.
1.116 +
1.117 + result = InvokeBlock(bitand, 1, produces_result=1)
1.118 + result.expr = LoadRef(ref=subprogram)
1.119 + return result
1.120 +
1.121 def visitBreak(self, break_):
1.122 result = ReturnFromBlock(break_, 1)
1.123 return result
1.124 @@ -567,6 +657,8 @@
1.125 # Make a new AST-style node to wrap the operation program nodes.
1.126
1.127 new_op = Op(op_name, node)
1.128 + compare._ops.append(new_op)
1.129 +
1.130 expr = self.dispatch(node)
1.131
1.132 # Identify the operation and produce the appropriate method call.
1.133 @@ -624,7 +716,6 @@
1.134 raise NotImplementedError, op_name
1.135
1.136 nodes.append(StoreTemp(expr=invocation))
1.137 - compare._ops.append(new_op)
1.138
1.139 # Return from the subprogram where the test is not satisfied.
1.140
1.141 @@ -1594,6 +1685,15 @@
1.142
1.143 return result
1.144
1.145 + # NOTE: Not actually supported.
1.146 + # NOTE: Virtually the same as visitReturn...
1.147 +
1.148 + def visitYield(self, yield_):
1.149 + result = Yield(yield_, 1,
1.150 + expr=self.dispatch(yield_.value)
1.151 + )
1.152 + return result
1.153 +
1.154 # Convenience methods.
1.155
1.156 def _visitBinary(self, binary, left_name, right_name):