1.1 --- a/micropython/ast.py Sun Sep 21 21:48:17 2008 +0200
1.2 +++ b/micropython/ast.py Mon Sep 22 01:32:54 2008 +0200
1.3 @@ -1248,7 +1248,7 @@
1.4 raise TypeError
1.5 """
1.6
1.7 - end_call_label = self.new_label()
1.8 + type_error_label = self.new_label()
1.9 end_label = self.new_label()
1.10
1.11 # Evaluate and store the operand in temporary storage.
1.12 @@ -1256,9 +1256,6 @@
1.13 self.dispatch(node.expr)
1.14 temp = self.optimiser.optimise_temp_storage()
1.15
1.16 - # Produce the invocation.
1.17 -
1.18 - self._startCallFunc()
1.19 self.new_op(temp)
1.20
1.21 # Get the method on temp.
1.22 @@ -1266,7 +1263,7 @@
1.23 self._generateAttr(node, method, self.attribute_load_instructions)
1.24 temp_method = self.optimiser.optimise_temp_storage()
1.25
1.26 - self._handleAttributeError(node, end_call_label)
1.27 + self._handleAttributeError(node, type_error_label)
1.28
1.29 # Add arguments.
1.30 # NOTE: No support for defaults.
1.31 @@ -1278,19 +1275,23 @@
1.32 self._endCallFunc(temp_method)
1.33 self.new_op(Jump(end_label))
1.34
1.35 - # End method attempt.
1.36 -
1.37 - self.set_label(end_call_label)
1.38 - self._endCallFunc() # From the method call.
1.39 + # Store the result.
1.40 +
1.41 + temp_out = self.get_temp()
1.42
1.43 # Raise a TypeError.
1.44
1.45 + self.set_label(type_error_label)
1.46 self.load_builtin("TypeError", node)
1.47 self.new_op(StoreException())
1.48 self.new_op(RaiseException())
1.49
1.50 self.set_label(end_label)
1.51
1.52 + # Produce the result.
1.53 +
1.54 + self.new_op(temp_out)
1.55 +
1.56 # Compilation duties...
1.57
1.58 self.discard_temp(temp)
1.59 @@ -1323,7 +1324,11 @@
1.60 self.dispatch(node.right)
1.61 temp2 = self.optimiser.optimise_temp_storage()
1.62
1.63 - self._generateBinary(node, temp1, temp2, left_method, right_method)
1.64 + temp_out = self._generateBinary(node, temp1, temp2, left_method, right_method)
1.65 +
1.66 + # Produce the result.
1.67 +
1.68 + self.new_op(temp_out)
1.69
1.70 # Compilation duties...
1.71
1.72 @@ -1345,12 +1350,13 @@
1.73
1.74 # Left method.
1.75
1.76 - self._generateOpMethod(node, temp1, temp2, left_method, right_label, end_label)
1.77 + temp_out = self._generateOpMethod(node, temp1, temp2, left_method, right_label, end_label)
1.78 + self.discard_temp(temp_out) # NOTE: Will re-use the same storage.
1.79
1.80 # Right method.
1.81
1.82 self.set_label(right_label)
1.83 - self._generateOpMethod(node, temp2, temp1, right_method, type_error_label, end_label)
1.84 + temp_out = self._generateOpMethod(node, temp2, temp1, right_method, type_error_label, end_label)
1.85
1.86 # Raise a TypeError.
1.87
1.88 @@ -1360,6 +1366,7 @@
1.89 self.new_op(RaiseException())
1.90
1.91 self.set_label(end_label)
1.92 + return temp_out
1.93
1.94 def _generateOpMethod(self, node, temp1, temp2, method_name, next_method_label, end_label):
1.95
1.96 @@ -1393,6 +1400,10 @@
1.97 self._doCallFunc(temp_method)
1.98 self._endCallFunc(temp_method)
1.99
1.100 + # Store the result.
1.101 +
1.102 + temp_out = self.get_temp()
1.103 +
1.104 # Test for NotImplemented.
1.105 # Don't actually raise an exception.
1.106
1.107 @@ -1403,6 +1414,7 @@
1.108 # End method attempt.
1.109
1.110 self.set_label(end_attempt_label)
1.111 + return temp_out
1.112
1.113 def _handleAttributeError(self, node, end_call_label):
1.114
1.115 @@ -1556,7 +1568,50 @@
1.116
1.117 visitAssTuple = visitAssList
1.118
1.119 - def visitAugAssign(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "AugAssign")
1.120 + def visitAugAssign(self, node):
1.121 + use_binary_label = self.new_label()
1.122 + end_label = self.new_label()
1.123 +
1.124 + # Evaluate the expression.
1.125 +
1.126 + self.dispatch(node.expr)
1.127 + temp2 = self.optimiser.optimise_temp_storage()
1.128 +
1.129 + # Evaluate the target.
1.130 +
1.131 + self.dispatch(node.node)
1.132 + temp1 = self.optimiser.optimise_temp_storage()
1.133 +
1.134 + # Find the augmented assignment method and attempt to use it.
1.135 +
1.136 + aug_method, (left_method, right_method) = self.augassign_methods[node.op]
1.137 + temp_out = self._generateOpMethod(node, temp1, temp2, aug_method, use_binary_label, end_label)
1.138 + self.discard_temp(temp_out) # NOTE: Will re-use the same storage.
1.139 +
1.140 + # Where no such method exists, use the binary operator methods.
1.141 +
1.142 + self.set_label(use_binary_label)
1.143 + temp_out = self._generateBinary(node, temp1, temp2, left_method, right_method)
1.144 +
1.145 + # Assign the result to the name.
1.146 +
1.147 + self.set_label(end_label)
1.148 + self.new_op(temp_out)
1.149 + self.record_value(1)
1.150 +
1.151 + if isinstance(node.node, compiler.ast.Name):
1.152 + self.visitAssName(node.node)
1.153 + elif isinstance(node.node, compiler.ast.Getattr):
1.154 + self.visitAssAttr(node.node)
1.155 + else:
1.156 + raise TranslationNotImplementedError(self.module.full_name(), node, "AugAssign(Slice or Subscript)")
1.157 +
1.158 + self.discard_value()
1.159 +
1.160 + # Compilation duties...
1.161 +
1.162 + self.discard_temp(temp1)
1.163 + self.discard_temp(temp2)
1.164
1.165 def visitBackquote(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Backquote")
1.166
1.167 @@ -1614,8 +1669,6 @@
1.168 """
1.169
1.170 end_label = self.new_label()
1.171 - temp_pos = self.reserve_temp()
1.172 - temp_result = LoadTemp(temp_pos)
1.173
1.174 self.dispatch(node.expr)
1.175 temp2 = self.optimiser.optimise_temp_storage()
1.176 @@ -1638,9 +1691,9 @@
1.177
1.178 # Generate method call using evaluated argument and next node.
1.179
1.180 - self._generateBinary(node, temp1, temp2, left_method, right_method)
1.181 - self.new_op(StoreTemp(temp_pos))
1.182 + temp_result = self._generateBinary(node, temp1, temp2, left_method, right_method)
1.183 self._generateTestBoolean(node, temp_result)
1.184 + self.discard_temp(temp_result)
1.185
1.186 else:
1.187 # Deal with the special operators.
1.188 @@ -1673,8 +1726,9 @@
1.189 self._doCallFunc(temp_method)
1.190 self._endCallFunc(temp_method)
1.191
1.192 - self.new_op(StoreTemp(temp_pos))
1.193 + temp_result = self.get_temp()
1.194 self._generateTestBoolean(node, temp_result)
1.195 + self.discard_temp(temp_result)
1.196
1.197 if op_name.find("not") != -1:
1.198 self.new_op(InvertBoolean())
1.199 @@ -1689,7 +1743,6 @@
1.200 self.discard_temp(temp1)
1.201
1.202 self.discard_temp(temp2)
1.203 - self.discard_temp(temp_result)
1.204 self.set_label(end_label)
1.205
1.206 # Yield the appropriate value.
1.207 @@ -2176,4 +2229,18 @@
1.208 "not in" : None
1.209 }
1.210
1.211 + augassign_methods = {
1.212 + "+=" : ("__iadd__", ("__add__", "__radd__")),
1.213 + "-=" : ("__isub__", ("__sub__", "__rsub__")),
1.214 + "*=" : ("__imul__", ("__mul__", "__rmul__")),
1.215 + "/=" : ("__idiv__", ("__div__", "__rdiv__")),
1.216 + "%=" : ("__imod__", ("__mod__", "__rmod__")),
1.217 + "**=" : ("__ipow__", ("__pow__", "__rpow__")),
1.218 + "<<=" : ("__ilshift__", ("__lshift__", "__rlshift__")),
1.219 + ">>=" : ("__irshift__", ("__rshift__", "__rrshift__")),
1.220 + "&=" : ("__iand__", ("__and__", "__rand__")),
1.221 + "^=" : ("__ixor__", ("__xor__", "__rxor__")),
1.222 + "|=" : ("__ior__", ("__or__", "__ror__"))
1.223 + }
1.224 +
1.225 # vim: tabstop=4 expandtab shiftwidth=4