1.1 --- a/micropython/ast.py Tue Jul 29 00:20:23 2008 +0200
1.2 +++ b/micropython/ast.py Fri Aug 01 01:44:02 2008 +0200
1.3 @@ -702,7 +702,7 @@
1.4
1.5 first = 1
1.6 frame_pos = ncontext
1.7 - max_keyword_pos = 0
1.8 + max_keyword_pos = -1
1.9
1.10 for arg in args:
1.11
1.12 @@ -812,6 +812,9 @@
1.13 # NOTE: Extra keywords are not supported.
1.14 # NOTE: Somehow, the above needs to be combined with * arguments.
1.15
1.16 + if extra_keywords:
1.17 + print "Warning: extra keyword argument(s) %s not handled." % ", ".join([arg.name for arg in extra_keywords])
1.18 +
1.19 # Either test for a complete set of arguments.
1.20
1.21 if target is not None:
1.22 @@ -843,7 +846,12 @@
1.23 # NOTE: the context in use.
1.24
1.25 else:
1.26 - self.new_op(CheckFrame(max(max(employed_positions), max_keyword_pos)))
1.27 +
1.28 + # Only check non-empty frames.
1.29 +
1.30 + if employed_positions or max_keyword_pos >= 0:
1.31 + max_pos = max(max(employed_positions), max_keyword_pos, frame_pos - 1)
1.32 + self.new_op(CheckFrame(max_pos + 1))
1.33
1.34 def _generateCallFuncDefaultArgs(self, target, temp, nargs_min, nargs_max, employed_positions):
1.35
1.36 @@ -908,7 +916,7 @@
1.37 dynamic = function.name is None
1.38
1.39 if dynamic:
1.40 - self.new_op(MakeObject(len(attr_to_default)))
1.41 + self.new_op(MakeObject(("function", len(attr_to_default))))
1.42 temp = self.get_temp()
1.43
1.44 for attr, default in attr_to_default:
1.45 @@ -1050,12 +1058,6 @@
1.46 raise TypeError
1.47 """
1.48
1.49 - end_left_label = self.new_label()
1.50 - right_label = self.new_label()
1.51 - end_right_label = self.new_label()
1.52 - type_error_label = self.new_label()
1.53 - end_label = self.new_label()
1.54 -
1.55 # Evaluate and store the left operand in temporary storage.
1.56
1.57 self.dispatch(node.left)
1.58 @@ -1066,14 +1068,47 @@
1.59 self.dispatch(node.right)
1.60 temp2 = self._optimise_temp_storage()
1.61
1.62 + self._generateBinary(temp1, temp2, left_method, right_method)
1.63 +
1.64 + # Compilation duties...
1.65 +
1.66 + self.discard_temp(temp1)
1.67 + self.discard_temp(temp2)
1.68 +
1.69 + def _generateBinary(self, temp1, temp2, left_method, right_method):
1.70 +
1.71 + right_label = self.new_label()
1.72 + type_error_label = self.new_label()
1.73 + end_label = self.new_label()
1.74 +
1.75 # Left method.
1.76
1.77 + self._generateOpMethod(temp1, temp2, left_method, right_label, end_label)
1.78 +
1.79 + # Right method.
1.80 +
1.81 + self.set_label(right_label)
1.82 + self._generateOpMethod(temp2, temp1, right_method, type_error_label, end_label)
1.83 +
1.84 + # Raise a TypeError.
1.85 +
1.86 + self.set_label(type_error_label)
1.87 + self.load_builtin("TypeError", node)
1.88 + self.new_op(StoreException())
1.89 + self.new_op(RaiseException())
1.90 +
1.91 + self.set_label(end_label)
1.92 +
1.93 + def _generateOpMethod(self, temp1, temp2, method_name, next_method_label, end_label):
1.94 +
1.95 + end_attempt_label = self.new_label()
1.96 +
1.97 self._startCallFunc()
1.98 self.new_op(temp1)
1.99
1.100 - # Get left method on temp1.
1.101 + # Get method on temp1.
1.102
1.103 - self._generateAttr(node, left_method, self.attribute_load_instructions)
1.104 + self._generateAttr(node, method_name, self.attribute_load_instructions)
1.105
1.106 # Add exception handling to the method acquisition instructions where
1.107 # the attribute access cannot be resolved at compile-time.
1.108 @@ -1081,7 +1116,7 @@
1.109 if not self._optimise_known_target():
1.110 self.load_builtin("AttributeError", node)
1.111 self.new_op(CheckException())
1.112 - self.new_op(JumpIfTrue(end_left_label))
1.113 + self.new_op(JumpIfTrue(end_attempt_label))
1.114
1.115 temp_method = self._optimise_temp_storage()
1.116
1.117 @@ -1097,67 +1132,28 @@
1.118 # Don't actually raise an exception.
1.119
1.120 self.new_op(TestIdentityAddress(self.get_builtin("NotImplemented", node)))
1.121 - self.new_op(JumpIfTrue(right_label))
1.122 + self.new_op(JumpIfTrue(next_method_label))
1.123 self.new_op(Jump(end_label))
1.124
1.125 - # End left method attempt.
1.126 + # End method attempt.
1.127
1.128 - self.set_label(end_left_label)
1.129 + self.set_label(end_attempt_label)
1.130 self._endCallFunc() # From the left method call.
1.131
1.132 - # Right method.
1.133 -
1.134 - self.set_label(right_label)
1.135 - self._startCallFunc()
1.136 - self.new_op(temp2)
1.137 -
1.138 - # Get right method on temp2.
1.139 -
1.140 - self._generateAttr(node, right_method, self.attribute_load_instructions)
1.141 -
1.142 - # Add exception handling to the method acquisition instructions where
1.143 - # the attribute access cannot be resolved at compile-time.
1.144 -
1.145 - if not self._optimise_known_target():
1.146 - self.load_builtin("AttributeError", node)
1.147 - self.new_op(CheckException())
1.148 - self.new_op(JumpIfTrue(end_right_label))
1.149 -
1.150 - temp_method = self._optimise_temp_storage()
1.151 -
1.152 - # Add arguments.
1.153 - # NOTE: No support for defaults.
1.154 + def _visitSequence(self, sequence_type, node):
1.155 + self.new_op(MakeObject((sequence_type, len(node.nodes))))
1.156 + temp = self.get_temp()
1.157
1.158 - self.new_op(temp2) # Explicit context as first argument.
1.159 - self.new_op(temp1)
1.160 - self._doCallFunc(temp_method)
1.161 - self._endCallFunc(temp_method)
1.162 -
1.163 - # Test for NotImplemented.
1.164 - # Don't actually raise an exception.
1.165 -
1.166 - self.new_op(TestIdentityAddress(self.get_builtin("NotImplemented", node)))
1.167 - self.new_op(JumpIfTrue(type_error_label))
1.168 - self.new_op(Jump(end_label))
1.169 -
1.170 - # End right method attempt.
1.171 + for i, n in enumerate(node.nodes):
1.172 + self.dispatch(n)
1.173 + self.record_value()
1.174 + self.new_op(temp)
1.175 + self.new_op(StoreAttr(Attr(i, None, None, None)))
1.176 + self.set_source()
1.177 + self.discard_value()
1.178
1.179 - self.set_label(end_right_label)
1.180 - self._endCallFunc() # From the right method call.
1.181 -
1.182 - # Raise a TypeError.
1.183 -
1.184 - self.set_label(type_error_label)
1.185 - self.load_builtin("TypeError", node)
1.186 - self.new_op(StoreException())
1.187 - self.new_op(RaiseException())
1.188 -
1.189 - self.set_label(end_label)
1.190 -
1.191 - # Compilation duties...
1.192 -
1.193 - self.discard_temp(temp1)
1.194 - self.discard_temp(temp2)
1.195 + self.new_op(temp)
1.196 + self.discard_temp(temp)
1.197
1.198 # Concrete visitor methods.
1.199
1.200 @@ -1255,15 +1251,45 @@
1.201 def visitCompare(self, node):
1.202
1.203 """
1.204 + _t1 = node.expr
1.205 + _t1 op1 _t2 and _t2 op2 _t3 and ...
1.206 + """
1.207 +
1.208 + end_label = self.new_label()
1.209 +
1.210 self.dispatch(node.expr)
1.211 + temp2 = self._optimise_temp_storage()
1.212 +
1.213 for op_name, next_node in compare.ops:
1.214 - methods = self.comparison_methods[op_name]
1.215 + left_method, right_method = self.comparison_methods[op_name]
1.216 +
1.217 + temp1 = temp2
1.218 + self.dispatch(next_node)
1.219 + temp2 = self._optimise_temp_storage()
1.220 +
1.221 if methods is not None:
1.222 +
1.223 # Generate method call using evaluated argument and next node.
1.224 +
1.225 + self._generateBinary(temp1, temp2, left_method, right_method)
1.226 +
1.227 + # Test the result and jump to the end label if false.
1.228 +
1.229 + self.new_op(LoadResult())
1.230 + self.new_op(TestBoolean())
1.231 + self.new_op(JumpIfFalse(end_label))
1.232 +
1.233 else:
1.234 - # Deal with the special operators.
1.235 - # Provide short-circuiting.
1.236 - """
1.237 + # NOTE: Deal with the special operators.
1.238 +
1.239 + pass
1.240 +
1.241 + # Compilation duties...
1.242 +
1.243 + self.discard_temp(temp1)
1.244 +
1.245 + self.discard_temp(temp2)
1.246 + self.set_label(end_label)
1.247
1.248 def visitConst(self, node):
1.249 const = self.module.constant_values[node.value]
1.250 @@ -1431,6 +1457,18 @@
1.251
1.252 def visitLambda(self, node):
1.253
1.254 + """
1.255 + Lambda functions can be represented as globally defined functions
1.256 + provided they do not define any default parameter values, since these
1.257 + may defined in a non-global scope.
1.258 +
1.259 + Where defaults are defined, an object must be created and its content
1.260 + defined: the callable member of the object's structure must be set to
1.261 + the lambda function definition; each default must be attached to the
1.262 + object as an attribute, as is the case with normal functions and
1.263 + methods.
1.264 + """
1.265 +
1.266 # Produce the reference to this function when visiting this node from
1.267 # outside.
1.268
1.269 @@ -1460,7 +1498,8 @@
1.270 def visitLeftShift(self, node):
1.271 self._visitBinary(node, "__lshift__", "__rlshift__")
1.272
1.273 - def visitList(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "List")
1.274 + def visitList(self, node):
1.275 + self._visitSequence("list", node)
1.276
1.277 def visitListComp(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "ListComp")
1.278
1.279 @@ -1628,19 +1667,7 @@
1.280 def visitTryFinally(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "TryFinally")
1.281
1.282 def visitTuple(self, node):
1.283 - self.new_op(MakeObject(len(node.nodes)))
1.284 - temp = self.get_temp()
1.285 -
1.286 - for i, n in enumerate(node.nodes):
1.287 - self.dispatch(n)
1.288 - self.record_value()
1.289 - self.new_op(temp)
1.290 - self.new_op(StoreAttr(Attr(i, None, None, None)))
1.291 - self.set_source()
1.292 - self.discard_value()
1.293 -
1.294 - self.new_op(temp)
1.295 - self.discard_temp(temp)
1.296 + self._visitSequence("tuple", node)
1.297
1.298 def visitUnaryAdd(self, node):
1.299 self._visitUnary(node, "__pos__")