1.1 --- a/micropython/ast.py Fri Jul 18 00:49:53 2008 +0200
1.2 +++ b/micropython/ast.py Fri Jul 18 01:18:22 2008 +0200
1.3 @@ -193,17 +193,16 @@
1.4
1.5 temp_position = self.reserve_temp(1)
1.6 self.new_op(StoreTemp(temp_position))
1.7 - return [LoadTemp(temp_position)]
1.8 + return LoadTemp(temp_position)
1.9
1.10 def reserve_temp(self, n):
1.11 temp_position = self.temp_position
1.12 self.temp_position += n
1.13 return temp_position
1.14
1.15 - def discard_temp(self, instructions):
1.16 - for temp in instructions:
1.17 - if isinstance(temp, LoadTemp):
1.18 - self.temp_position -= 1
1.19 + def discard_temp(self, instruction):
1.20 + if isinstance(instruction, LoadTemp):
1.21 + self.temp_position -= 1
1.22
1.23 # Code writing methods.
1.24
1.25 @@ -220,16 +219,6 @@
1.26 self.code.append(op)
1.27 self.active = op
1.28
1.29 - def new_ops(self, ops):
1.30 -
1.31 - """
1.32 - Add copies of 'ops' to the generated code. This is typically used in
1.33 - connection with sequences of temporary storage instructions.
1.34 - """
1.35 -
1.36 - for op in ops:
1.37 - self.new_op(op.copy())
1.38 -
1.39 def remove_op(self):
1.40
1.41 "Remove the last instruction."
1.42 @@ -392,7 +381,7 @@
1.43 # to be the context, load the context.
1.44
1.45 if context is None or isinstance(context, Instance):
1.46 - self.new_ops(temp)
1.47 + self.new_op(temp)
1.48 self.new_op(LoadContext())
1.49 self.new_op(StoreFrame(0))
1.50
1.51 @@ -573,14 +562,14 @@
1.52 else:
1.53 self.new_op(CheckFrame())
1.54
1.55 - def _doCallFunc(self, instructions):
1.56 + def _doCallFunc(self, instruction):
1.57
1.58 "Make the invocation."
1.59
1.60 - self.new_ops(instructions)
1.61 + self.new_op(instruction)
1.62 self.new_op(JumpWithFrame())
1.63
1.64 - def _endCallFunc(self, instructions=None):
1.65 + def _endCallFunc(self, instruction=None):
1.66
1.67 "Finish the invocation and tidy up afterwards."
1.68
1.69 @@ -589,8 +578,8 @@
1.70
1.71 # Discard any temporary storage instructions.
1.72
1.73 - if instructions is not None:
1.74 - self.discard_temp(instructions)
1.75 + if instruction is not None:
1.76 + self.discard_temp(instruction)
1.77
1.78 def _visitName(self, node, classes):
1.79
1.80 @@ -710,8 +699,6 @@
1.81 If no optimisation can be achieved, a StoreTemp instruction is produced
1.82 and the appropriate LoadTemp instruction is returned.
1.83
1.84 - All returned instructions are provided in a list.
1.85 -
1.86 Restriction: for use only in situations where the source of the
1.87 temporary data will not be disturbed between its first access and its
1.88 subsequent use.
1.89 @@ -722,7 +709,7 @@
1.90
1.91 last = self.last_op()
1.92 self.remove_op()
1.93 - return [last]
1.94 + return last
1.95 else:
1.96 return self.get_temp()
1.97
1.98 @@ -828,7 +815,7 @@
1.99 # Produce the invocation.
1.100
1.101 self._startCallFunc()
1.102 - self.new_ops(temp)
1.103 + self.new_op(temp)
1.104
1.105 # Get the method on temp.
1.106
1.107 @@ -847,7 +834,7 @@
1.108 # Add arguments.
1.109 # NOTE: No support for defaults.
1.110
1.111 - self.new_ops(temp) # Explicit context as first argument.
1.112 + self.new_op(temp) # Explicit context as first argument.
1.113 self._doCallFunc(temp_method)
1.114 self._endCallFunc(temp_method)
1.115 self.new_op(Jump(end_label))
1.116 @@ -905,7 +892,7 @@
1.117 # Left method.
1.118
1.119 self._startCallFunc()
1.120 - self.new_ops(temp1)
1.121 + self.new_op(temp1)
1.122
1.123 # Get left method on temp1.
1.124
1.125 @@ -924,8 +911,8 @@
1.126 # Add arguments.
1.127 # NOTE: No support for defaults.
1.128
1.129 - self.new_ops(temp1) # Explicit context as first argument.
1.130 - self.new_ops(temp2)
1.131 + self.new_op(temp1) # Explicit context as first argument.
1.132 + self.new_op(temp2)
1.133 self._doCallFunc(temp_method)
1.134 self._endCallFunc(temp_method)
1.135
1.136 @@ -945,7 +932,7 @@
1.137
1.138 self.set_label(right_label)
1.139 self._startCallFunc()
1.140 - self.new_ops(temp2)
1.141 + self.new_op(temp2)
1.142
1.143 # Get right method on temp2.
1.144
1.145 @@ -964,8 +951,8 @@
1.146 # Add arguments.
1.147 # NOTE: No support for defaults.
1.148
1.149 - self.new_ops(temp2) # Explicit context as first argument.
1.150 - self.new_ops(temp1)
1.151 + self.new_op(temp2) # Explicit context as first argument.
1.152 + self.new_op(temp1)
1.153 self._doCallFunc(temp_method)
1.154 self._endCallFunc(temp_method)
1.155
1.156 @@ -1143,7 +1130,7 @@
1.157 # Use the iterator to get the next value.
1.158
1.159 self._startCallFunc()
1.160 - self.new_ops(temp_iterator)
1.161 + self.new_op(temp_iterator)
1.162 self._generateAttr(node, "next", self.attr_load_instructions)
1.163 temp = self._generateCallFunc([], node)
1.164 self._doCallFunc(temp)
1.165 @@ -1325,8 +1312,18 @@
1.166 self.dispatch(node.expr1)
1.167
1.168 if node.expr2 is not None:
1.169 + temp = self._optimise_temp_storage()
1.170 +
1.171 self.dispatch(node.expr2)
1.172 - self._doCallFunc()
1.173 + temp_arg = self._optimise_temp_storage()
1.174 +
1.175 + self._startCallFunc()
1.176 + self.new_op(temp_arg)
1.177 + self.new_op(StoreFrame(0))
1.178 + self._doCallFunc(temp)
1.179 + self._endCallFunc(temp)
1.180 +
1.181 + self.discard_temp(temp_arg)
1.182
1.183 self.new_op(RaiseException())
1.184
1.185 @@ -1353,6 +1350,7 @@
1.186
1.187 def visitTryExcept(self, node):
1.188 exit_label = self.new_label()
1.189 + success_label = self.new_label()
1.190 handler_label = self.new_label()
1.191
1.192 self.add_exception_labels(handler_label, exit_label)
1.193 @@ -1360,12 +1358,16 @@
1.194 # Try...
1.195 # Produce the code, then jump to the exit.
1.196
1.197 + self.new_op(PushHandler(handler_label))
1.198 self.dispatch(node.body)
1.199 + self.new_op(PopHandler(handler_label))
1.200 self.new_op(Jump(exit_label))
1.201
1.202 # Start of handlers.
1.203
1.204 self.set_label(handler_label)
1.205 + self.new_op(PopHandler(handler_label))
1.206 +
1.207 for name, assignment, handler in node.handlers:
1.208 next_label = self.new_label()
1.209
1.210 @@ -1393,15 +1395,12 @@
1.211 self.new_op(LoadException())
1.212 self.new_op(RaiseException())
1.213
1.214 - # After exception
1.215 -
1.216 - self.set_label(exit_label)
1.217 -
1.218 # Optional else clause.
1.219
1.220 if node.else_ is not None:
1.221 self.dispatch(node.else_)
1.222
1.223 + self.set_label(exit_label)
1.224 self.drop_exception_labels()
1.225
1.226 def visitTryFinally(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "TryFinally")