1.1 --- a/micropython/ast.py Sun May 11 18:43:58 2008 +0200
1.2 +++ b/micropython/ast.py Sun May 11 21:50:30 2008 +0200
1.3 @@ -699,6 +699,65 @@
1.4 def dispatch(self, node, *args):
1.5 return ASTVisitor.dispatch(self, node, *args)
1.6
1.7 + def _visitUnary(self, node, method):
1.8 +
1.9 + """
1.10 + _t = node.expr
1.11 + try:
1.12 + _result = _t.__pos__()
1.13 + except AttributeError:
1.14 + raise TypeError
1.15 + """
1.16 +
1.17 + end_call_label = self.new_label()
1.18 + end_label = self.new_label()
1.19 +
1.20 + # Evaluate and store the operand in temporary storage.
1.21 +
1.22 + self.dispatch(node.expr)
1.23 + temp = self._optimise_temp_storage()
1.24 +
1.25 + # Produce the invocation.
1.26 +
1.27 + self._startCallFunc()
1.28 + self.new_ops(temp)
1.29 +
1.30 + # Get the method on temp.
1.31 +
1.32 + self._generateAttr(node, method, (LoadAddress, LoadAttr, LoadAttrIndex))
1.33 +
1.34 + # Add exception handling to the method acquisition instructions where
1.35 + # the attribute access cannot be resolved at compile-time.
1.36 +
1.37 + if not self._optimise_known_target():
1.38 + self.dispatch(compiler.ast.Name("AttributeError"))
1.39 + self.new_op(CheckException())
1.40 + self.new_op(JumpIfTrue(end_call_label))
1.41 +
1.42 + temp_method = self._optimise_temp_storage()
1.43 +
1.44 + # Add arguments.
1.45 +
1.46 + self.new_ops(temp) # Explicit context as first argument.
1.47 + self._endCallFunc(temp_method)
1.48 + self.new_op(Jump(end_label))
1.49 +
1.50 + # End method attempt.
1.51 +
1.52 + self.set_label(end_call_label)
1.53 + self.new_op(DropFrame()) # From the method call.
1.54 +
1.55 + # Raise a TypeError.
1.56 +
1.57 + self.dispatch(compiler.ast.Name("TypeError"))
1.58 + self.new_op(RaiseException())
1.59 +
1.60 + self.set_label(end_label)
1.61 +
1.62 + # Compilation duties...
1.63 +
1.64 + self.discard_temp(temp)
1.65 +
1.66 def _visitBinary(self, node, left_method, right_method):
1.67
1.68 """
1.69 @@ -719,6 +778,7 @@
1.70
1.71 end_left_label = self.new_label()
1.72 right_label = self.new_label()
1.73 + end_right_label = self.new_label()
1.74 type_error_label = self.new_label()
1.75 end_label = self.new_label()
1.76
1.77 @@ -787,7 +847,7 @@
1.78 if not self._optimise_known_target():
1.79 self.dispatch(compiler.ast.Name("AttributeError"))
1.80 self.new_op(CheckException())
1.81 - self.new_op(JumpIfTrue(type_error_label))
1.82 + self.new_op(JumpIfTrue(end_right_label))
1.83
1.84 temp_method = self._optimise_temp_storage()
1.85
1.86 @@ -806,6 +866,11 @@
1.87 self.new_op(JumpIfTrue(type_error_label))
1.88 self.new_op(Jump(end_label))
1.89
1.90 + # End right method attempt.
1.91 +
1.92 + self.set_label(end_right_label)
1.93 + self.new_op(DropFrame()) # From the right method call.
1.94 +
1.95 # Raise a TypeError.
1.96
1.97 self.set_label(type_error_label)
1.98 @@ -845,11 +910,14 @@
1.99
1.100 def visitBackquote(self, node): pass
1.101
1.102 - def visitBitand(self, node): pass
1.103 + def visitBitand(self, node):
1.104 + self._visitBinary(node, "__and__", "__rand__")
1.105
1.106 - def visitBitor(self, node): pass
1.107 + def visitBitor(self, node):
1.108 + self._visitBinary(node, "__or__", "__ror__")
1.109
1.110 - def visitBitxor(self, node): pass
1.111 + def visitBitxor(self, node):
1.112 + self._visitBinary(node, "__xor__", "__rxor__")
1.113
1.114 def visitBreak(self, node):
1.115 next_label, exit_label = self.get_loop_labels()
1.116 @@ -1035,13 +1103,15 @@
1.117
1.118 def visitImport(self, node): pass
1.119
1.120 - def visitInvert(self, node): pass
1.121 + def visitInvert(self, node):
1.122 + self._visitUnary(node, "__invert__")
1.123
1.124 def visitKeyword(self, node): pass
1.125
1.126 def visitLambda(self, node): pass
1.127
1.128 - def visitLeftShift(self, node): pass
1.129 + def visitLeftShift(self, node):
1.130 + self._visitBinary(node, "__lshift__", "__rlshift__")
1.131
1.132 def visitList(self, node): pass
1.133
1.134 @@ -1073,7 +1143,8 @@
1.135
1.136 def visitPass(self, node): pass
1.137
1.138 - def visitPower(self, node): pass
1.139 + def visitPower(self, node):
1.140 + self._visitBinary(node, "__pow__", "__rpow__")
1.141
1.142 def visitPrint(self, node): pass
1.143
1.144 @@ -1088,7 +1159,8 @@
1.145 self.dispatch(compiler.ast.Name("None"))
1.146 self.new_op(Return())
1.147
1.148 - def visitRightShift(self, node): pass
1.149 + def visitRightShift(self, node):
1.150 + self._visitBinary(node, "__rshift__", "__rrshift__")
1.151
1.152 def visitSlice(self, node): pass
1.153
1.154 @@ -1102,13 +1174,6 @@
1.155 def visitSubscript(self, node): pass
1.156
1.157 def visitTryExcept(self, node):
1.158 -
1.159 - """
1.160 - Enter try block.
1.161 - Dispatch to code.
1.162 -
1.163 - """
1.164 -
1.165 exit_label = self.new_label()
1.166 handler_label = self.new_label()
1.167
1.168 @@ -1164,9 +1229,11 @@
1.169
1.170 def visitTuple(self, node): pass
1.171
1.172 - def visitUnaryAdd(self, node): pass
1.173 + def visitUnaryAdd(self, node):
1.174 + self._visitUnary(node, "__pos__")
1.175
1.176 - def visitUnarySub(self, node): pass
1.177 + def visitUnarySub(self, node):
1.178 + self._visitUnary(node, "__neg__")
1.179
1.180 def visitWhile(self, node):
1.181 exit_label = self.new_label()