1.1 --- a/micropython/ast.py Sat Aug 23 02:41:55 2008 +0200
1.2 +++ b/micropython/ast.py Sat Aug 23 21:57:29 2008 +0200
1.3 @@ -235,8 +235,7 @@
1.4 sequence of access instructions.
1.5 """
1.6
1.7 - temp_position = self.reserve_temp()
1.8 - position_in_frame = self.unit.local_usage + temp_position
1.9 + position_in_frame = self.reserve_temp()
1.10 self.new_op(StoreTemp(position_in_frame))
1.11 return LoadTemp(position_in_frame)
1.12
1.13 @@ -247,12 +246,16 @@
1.14 temp_position = max(self.temp_positions) + 1
1.15 self.temp_positions.add(temp_position)
1.16 self.max_temp_position = max(self.max_temp_position, temp_position)
1.17 - return temp_position
1.18 + return self.unit.local_usage + temp_position # position in frame
1.19
1.20 def discard_temp(self, instruction=None):
1.21 if isinstance(instruction, LoadTemp):
1.22 - position_in_frame = instruction.attr - self.unit.local_usage
1.23 - self.temp_positions.remove(position_in_frame)
1.24 + temp_position = instruction.attr - self.unit.local_usage
1.25 + self.free_temp(temp_position)
1.26 +
1.27 + def free_temp(self, temp_position):
1.28 + if temp_position in self.temp_positions:
1.29 + self.temp_positions.remove(temp_position)
1.30
1.31 # Code writing methods.
1.32
1.33 @@ -313,6 +316,13 @@
1.34 except IndexError:
1.35 return None
1.36
1.37 + def clear_active(self):
1.38 +
1.39 + "Prevent incorrect optimisation."
1.40 +
1.41 + self.active = None
1.42 + self.active_value = None
1.43 +
1.44 # Optimisation tests.
1.45
1.46 def _should_optimise_constant_storage(self):
1.47 @@ -1302,15 +1312,13 @@
1.48 self.new_op(temp)
1.49 self.discard_temp(temp)
1.50
1.51 - def _generateTestBoolean(self, node):
1.52 + def _generateTestBoolean(self, node, temp):
1.53
1.54 """
1.55 Generate a test of the boolean status of the current value for the given
1.56 program 'node'.
1.57 """
1.58
1.59 - temp = self._optimise_temp_storage()
1.60 -
1.61 # Get method on temp.
1.62 # NOTE: Using __bool__ instead of __nonzero__.
1.63
1.64 @@ -1324,6 +1332,8 @@
1.65 self._doCallFunc(temp_method)
1.66 self._endCallFunc(temp_method)
1.67
1.68 + self.discard_temp(temp_method)
1.69 +
1.70 # Convert result to boolean (a StoreBoolean operation).
1.71
1.72 self.new_op(TestIdentityAddress(self.get_builtin("True", node)))
1.73 @@ -1353,20 +1363,28 @@
1.74 self._visitBinary(node, "__add__", "__radd__")
1.75
1.76 def visitAnd(self, node):
1.77 - next_label = self.new_label()
1.78 + end_label = self.new_label()
1.79 + temp_pos = self.reserve_temp()
1.80 + temp = LoadTemp(temp_pos)
1.81
1.82 for n in node.nodes[:-1]:
1.83 self.dispatch(n)
1.84 - self._generateTestBoolean(n)
1.85 - self.new_op(JumpIfFalse(next_label))
1.86 + self.new_op(StoreTemp(temp_pos))
1.87 +
1.88 + self._generateTestBoolean(n, temp)
1.89 + self.new_op(JumpIfFalse(end_label))
1.90
1.91 self.dispatch(node.nodes[-1])
1.92 - self.set_label(next_label)
1.93 + self.new_op(StoreTemp(temp_pos))
1.94 +
1.95 + self.set_label(end_label)
1.96
1.97 # Prevent incorrect optimisation.
1.98
1.99 - self.active = None
1.100 - self.active_value = None
1.101 + self.clear_active()
1.102 +
1.103 + self.new_op(temp)
1.104 + self.discard_temp(temp)
1.105
1.106 def visitAssert(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Assert")
1.107
1.108 @@ -1449,6 +1467,8 @@
1.109 """
1.110
1.111 end_label = self.new_label()
1.112 + temp_pos = self.reserve_temp()
1.113 + temp_result = LoadTemp(temp_pos)
1.114
1.115 self.dispatch(node.expr)
1.116 temp2 = self._optimise_temp_storage()
1.117 @@ -1472,7 +1492,8 @@
1.118 # Generate method call using evaluated argument and next node.
1.119
1.120 self._generateBinary(node, temp1, temp2, left_method, right_method)
1.121 - self._generateTestBoolean(node)
1.122 + self.new_op(StoreTemp(temp_pos))
1.123 + self._generateTestBoolean(node, temp_result)
1.124
1.125 else:
1.126 # Deal with the special operators.
1.127 @@ -1504,7 +1525,9 @@
1.128 self._endCallFuncArgs(2)
1.129 self._doCallFunc(temp_method)
1.130 self._endCallFunc(temp_method)
1.131 - self._generateTestBoolean(node)
1.132 +
1.133 + self.new_op(StoreTemp(temp_pos))
1.134 + self._generateTestBoolean(node, temp_result)
1.135
1.136 if op_name.find("not") != -1:
1.137 self.new_op(InvertBoolean())
1.138 @@ -1519,6 +1542,7 @@
1.139 self.discard_temp(temp1)
1.140
1.141 self.discard_temp(temp2)
1.142 + self.discard_temp(temp_result)
1.143 self.set_label(end_label)
1.144
1.145 # Yield the appropriate value.
1.146 @@ -1758,34 +1782,42 @@
1.147 self._visitName(node, self.name_load_instructions)
1.148
1.149 def visitNot(self, node):
1.150 - next_label = self.new_label()
1.151 - true_label = self.new_label()
1.152 -
1.153 self.dispatch(node.expr)
1.154 - self._generateTestBoolean(node.expr)
1.155 +
1.156 + temp = self._optimise_temp_storage()
1.157 + self._generateTestBoolean(node.expr, temp)
1.158 + self.discard_temp(temp)
1.159 +
1.160 self.new_op(InvertBoolean())
1.161 self._generateLoadBoolean(node)
1.162
1.163 # Prevent incorrect optimisation.
1.164
1.165 - self.active = None
1.166 - self.active_value = None
1.167 + self.clear_active()
1.168
1.169 def visitOr(self, node):
1.170 - next_label = self.new_label()
1.171 + end_label = self.new_label()
1.172 + temp_pos = self.reserve_temp()
1.173 + temp = LoadTemp(temp_pos)
1.174
1.175 for n in node.nodes[:-1]:
1.176 self.dispatch(n)
1.177 - self._generateTestBoolean(n)
1.178 - self.new_op(JumpIfTrue(next_label))
1.179 + self.new_op(StoreTemp(temp_pos))
1.180 +
1.181 + self._generateTestBoolean(n, temp)
1.182 + self.new_op(JumpIfTrue(end_label))
1.183
1.184 self.dispatch(node.nodes[-1])
1.185 - self.set_label(next_label)
1.186 + self.new_op(StoreTemp(temp_pos))
1.187 +
1.188 + self.set_label(end_label)
1.189
1.190 # Prevent incorrect optimisation.
1.191
1.192 - self.active = None
1.193 - self.active_value = None
1.194 + self.clear_active()
1.195 +
1.196 + self.new_op(temp)
1.197 + self.discard_temp(temp)
1.198
1.199 def visitPass(self, node): pass
1.200
1.201 @@ -1933,8 +1965,7 @@
1.202
1.203 # Prevent incorrect optimisation.
1.204
1.205 - self.active = None
1.206 - self.active_value = None
1.207 + self.clear_active()
1.208
1.209 def visitWith(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "With")
1.210