1.1 --- a/simplify.py Sat Jul 15 20:43:50 2006 +0200
1.2 +++ b/simplify.py Sun Jul 16 01:33:02 2006 +0200
1.3 @@ -155,22 +155,6 @@
1.4 result.traceback = self.dispatch(raise_.expr3)
1.5 return result
1.6
1.7 - def visitIf(self, if_):
1.8 - result = If(if_, else_=[])
1.9 - tests = []
1.10 - for compare, stmt in if_.tests:
1.11 - # Produce something like...
1.12 - # expr.__true__() ? body
1.13 - test = Conditional(else_=[], test=Invoke(
1.14 - expr=LoadAttr(expr=self.dispatch(compare), name="__true__"),
1.15 - params=[], star=None, dstar=None))
1.16 - test.body = self.dispatch(stmt)
1.17 - tests.append(test)
1.18 - result.tests = tests
1.19 - if if_.else_ is not None:
1.20 - result.else_ = self.dispatch(if_.else_)
1.21 - return result
1.22 -
1.23 def _visitBuiltin(self, builtin, name):
1.24 result = Invoke(builtin, expr=LoadName(name=name))
1.25 result.args = self.dispatches(builtin.nodes)
1.26 @@ -192,7 +176,95 @@
1.27 result.args = args
1.28 return result
1.29
1.30 - # Logical and comparison operations.
1.31 + # Logical and comparison operations plus chained statements.
1.32 +
1.33 + def visitIf(self, if_):
1.34 +
1.35 + # Make a subprogram for the statement and record it outside the main tree.
1.36 +
1.37 + subprogram = Subprogram(name=hex(id(if_)), acquire_locals=1, returns_value=0, params=[], star=None, dstar=None)
1.38 + self.current_subprograms.append(subprogram)
1.39 +
1.40 + # In the subprogram, make conditionals for each test plus statement,
1.41 + # adding a return onto the end of each statement block.
1.42 +
1.43 + nodes = []
1.44 + for compare, stmt in if_.tests:
1.45 + # Produce something like...
1.46 + # expr.__true__() ? body
1.47 + test = Conditional(else_=[], test=Invoke(
1.48 + expr=LoadAttr(expr=self.dispatch(compare), name="__true__"),
1.49 + args=[], star=None, dstar=None))
1.50 + test.body = self.dispatch(stmt) + [Return()]
1.51 + nodes.append(test)
1.52 +
1.53 + # Add the compound statement from any else clause to the end.
1.54 +
1.55 + if if_.else_ is not None:
1.56 + nodes += self.dispatch(if_.else_)
1.57 +
1.58 + subprogram.code = nodes
1.59 +
1.60 + self.current_subprograms.pop()
1.61 + self.subprograms.append(subprogram)
1.62 +
1.63 + # Make an invocation of the subprogram.
1.64 +
1.65 + result = Invoke(compare, same_frame=1, star=None, dstar=None, args=[])
1.66 + result.expr = LoadRef(ref=subprogram)
1.67 + return result
1.68 +
1.69 + def _visitTryExcept(self, tryexcept):
1.70 +
1.71 + # Make a subprogram for the statement and record it outside the main tree.
1.72 +
1.73 + subprogram = Subprogram(name=hex(id(tryexcept)), acquire_locals=1, returns_value=0, params=[], star=None, dstar=None)
1.74 + self.current_subprograms.append(subprogram)
1.75 +
1.76 + # In the subprogram, make conditionals for each test plus statement,
1.77 + # adding a return onto the end of each statement block.
1.78 +
1.79 + nodes = []
1.80 + for spec, assign, stmt in tryexcept.handlers:
1.81 +
1.82 + # If no specification exists, produce an unconditional block.
1.83 +
1.84 + if spec is None:
1.85 + nodes += self.dispatch(stmt)
1.86 +
1.87 + # Produce something like...
1.88 + # isinstance(<exc>, <spec>)
1.89 +
1.90 + else:
1.91 + new_spec = self.dispatch(spec)
1.92 + test = Conditional(body=[], else_=[], test=Invoke(expr=LoadName(name="isinstance"), args=[LoadExc(), new_spec], star=None, dstar=None))
1.93 + if assign is not None:
1.94 + test.body.append(Assign(code=[StoreTemp(expr=LoadExc()), self.dispatch(assign), ReleaseTemp()]))
1.95 + test.body += self.dispatch(stmt) + [Return()]
1.96 + nodes.append(test)
1.97 +
1.98 + # Add a raise operation to deal with unhandled exceptions.
1.99 +
1.100 + nodes.append(Raise(expr=LoadExc()))
1.101 + subprogram.code = nodes
1.102 +
1.103 + self.current_subprograms.pop()
1.104 + self.subprograms.append(subprogram)
1.105 +
1.106 + # Make an invocation of the subprogram.
1.107 +
1.108 + result = Invoke(same_frame=1, star=None, dstar=None, args=[])
1.109 + result.expr = LoadRef(ref=subprogram)
1.110 + return result
1.111 +
1.112 + def visitTryExcept(self, tryexcept):
1.113 + result = Try(tryexcept, body=[], else_=[], finally_=[])
1.114 + if tryexcept.body is not None:
1.115 + result.body = self.dispatch(tryexcept.body)
1.116 + if tryexcept.else_ is not None:
1.117 + result.else_ = self.dispatch(tryexcept.else_)
1.118 + result.handler = self._visitTryExcept(tryexcept)
1.119 + return result
1.120
1.121 comparison_methods = {
1.122 "==" : "__eq__", "!=" : "__ne__", "<" : "__lt__", "<=" : "__le__",
1.123 @@ -586,7 +658,7 @@
1.124
1.125 test = Conditional(else_=[])
1.126 test.test = Invoke(expr=LoadAttr(expr=self.dispatch(while_.test), name="__true__"),
1.127 - params=[], star=None, dstar=None)
1.128 + args=[], star=None, dstar=None)
1.129
1.130 # Inside the conditional, add a recursive invocation to the subprogram
1.131 # if the test condition was satisfied.
1.132 @@ -614,13 +686,17 @@
1.133 subprogram = Subprogram(name=hex(id(for_)), acquire_locals=1, returns_value=0, params=[], star=None, dstar=None)
1.134 self.current_subprograms.append(subprogram)
1.135
1.136 + if for_.else_ is not None:
1.137 + else_stmt = self.dispatch(for_.else_)
1.138 + else:
1.139 + else_stmt = []
1.140 +
1.141 # Wrap the assignment in a try...except statement.
1.142
1.143 - try_except = Try(body=[], handlers=[], else_=[], finally_=[])
1.144 - except_spec = Invoke(expr=LoadName(name="Tuple"), params=[LoadName(name="StopIteration")])
1.145 - stopiteration = Except(spec=except_spec)
1.146 - stopiteration.code = self.dispatch(for_.else_)
1.147 - try_except.handlers = [stopiteration]
1.148 + try_except = Try(body=[], else_=[], finally_=[])
1.149 + try_except.handler = Conditional(test=Invoke(expr=LoadName(name="isinstance"),
1.150 + args=[LoadExc(), LoadName(name="StopIteration")], star=None, dstar=None),
1.151 + body=else_stmt, else_=[Raise(expr=LoadExc())])
1.152
1.153 assign = Assign()
1.154 assign.code = [
1.155 @@ -653,27 +729,6 @@
1.156
1.157 # Exception node transformations.
1.158
1.159 - def visitTryExcept(self, tryexcept):
1.160 - result = Try(tryexcept, body=[], handlers=[], else_=[], finally_=[])
1.161 - if tryexcept.body is not None:
1.162 - result.body = self.dispatch(tryexcept.body)
1.163 - if tryexcept.else_ is not None:
1.164 - result.else_ = self.dispatch(tryexcept.else_)
1.165 - handlers = []
1.166 - for spec, assign, stmt in tryexcept.handlers:
1.167 - get_exc = Assign()
1.168 - get_exc.code = [StoreTemp(expr=LoadExc())]
1.169 - if assign is not None:
1.170 - get_exc.code.append(self.dispatch(assign))
1.171 - get_exc.code.append(ReleaseTemp())
1.172 - handler = Except()
1.173 - if spec is not None:
1.174 - handler.spec = self.dispatch(spec)
1.175 - handler.code = [get_exc] + self.dispatch(stmt)
1.176 - handlers.append(handler)
1.177 - result.handlers = handlers
1.178 - return result
1.179 -
1.180 def visitTryFinally(self, tryfinally):
1.181 result = Try(tryfinally, body=[], handlers=[], else_=[], finally_=[])
1.182 if tryfinally.body is not None: