1.1 --- a/micropython/ast.py Sun Sep 28 23:14:54 2008 +0200
1.2 +++ b/micropython/ast.py Mon Sep 29 00:00:04 2008 +0200
1.3 @@ -1251,9 +1251,57 @@
1.4
1.5 # Concrete visitor methods.
1.6
1.7 + # Binary operators.
1.8 +
1.9 def visitAdd(self, node):
1.10 self._visitBinary(node, "__add__", "__radd__")
1.11
1.12 + def visitBitand(self, node):
1.13 + self._visitBinary(node, "__and__", "__rand__")
1.14 +
1.15 + def visitBitor(self, node):
1.16 + self._visitBinary(node, "__or__", "__ror__")
1.17 +
1.18 + def visitBitxor(self, node):
1.19 + self._visitBinary(node, "__xor__", "__rxor__")
1.20 +
1.21 + def visitDiv(self, node):
1.22 + self._visitBinary(node, "__div__", "__rdiv__")
1.23 +
1.24 + def visitFloorDiv(self, node):
1.25 + self._visitBinary(node, "__floordiv__", "__rfloordiv__")
1.26 +
1.27 + def visitLeftShift(self, node):
1.28 + self._visitBinary(node, "__lshift__", "__rlshift__")
1.29 +
1.30 + def visitMod(self, node):
1.31 + self._visitBinary(node, "__mod__", "__rmod__")
1.32 +
1.33 + def visitMul(self, node):
1.34 + self._visitBinary(node, "__mul__", "__rmul__")
1.35 +
1.36 + def visitPower(self, node):
1.37 + self._visitBinary(node, "__pow__", "__rpow__")
1.38 +
1.39 + def visitRightShift(self, node):
1.40 + self._visitBinary(node, "__rshift__", "__rrshift__")
1.41 +
1.42 + def visitSub(self, node):
1.43 + self._visitBinary(node, "__sub__", "__rsub__")
1.44 +
1.45 + # Unary operators.
1.46 +
1.47 + def visitInvert(self, node):
1.48 + self._visitUnary(node, "__invert__")
1.49 +
1.50 + def visitUnaryAdd(self, node):
1.51 + self._visitUnary(node, "__pos__")
1.52 +
1.53 + def visitUnarySub(self, node):
1.54 + self._visitUnary(node, "__neg__")
1.55 +
1.56 + # Logical operators.
1.57 +
1.58 def visitAnd(self, node):
1.59 end_label = self.new_label()
1.60 temp_pos = self.reserve_temp()
1.61 @@ -1278,7 +1326,201 @@
1.62 self.new_op(temp)
1.63 self.discard_temp(temp)
1.64
1.65 - def visitAssert(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Assert")
1.66 + def visitNot(self, node):
1.67 + self.dispatch(node.expr)
1.68 +
1.69 + temp = self.optimiser.optimise_temp_storage()
1.70 + self._generateTestBoolean(node.expr, temp)
1.71 + self.discard_temp(temp)
1.72 +
1.73 + self.new_op(InvertBoolean())
1.74 + self._generateLoadBoolean(node)
1.75 +
1.76 + # Prevent incorrect optimisation.
1.77 +
1.78 + self.optimiser.reset()
1.79 +
1.80 + def visitOr(self, node):
1.81 + end_label = self.new_label()
1.82 + temp_pos = self.reserve_temp()
1.83 + temp = LoadTemp(temp_pos)
1.84 +
1.85 + for n in node.nodes[:-1]:
1.86 + self.dispatch(n)
1.87 + self.new_op(StoreTemp(temp_pos))
1.88 +
1.89 + self._generateTestBoolean(n, temp)
1.90 + self.new_op(JumpIfTrue(end_label))
1.91 +
1.92 + self.dispatch(node.nodes[-1])
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.optimiser.reset()
1.100 +
1.101 + self.new_op(temp)
1.102 + self.discard_temp(temp)
1.103 +
1.104 + # Comparisons.
1.105 +
1.106 + def visitCompare(self, node):
1.107 +
1.108 + """
1.109 + _t1 = node.expr
1.110 + _t1 op1 _t2 and _t2 op2 _t3 and ...
1.111 + """
1.112 +
1.113 + end_label = self.new_label()
1.114 +
1.115 + self.dispatch(node.expr)
1.116 + temp2 = self.optimiser.optimise_temp_storage()
1.117 +
1.118 + last_op = node.ops[-1]
1.119 +
1.120 + for op in node.ops:
1.121 + op_name, next_node = op
1.122 + methods = self.comparison_methods[op_name]
1.123 +
1.124 + temp1 = temp2
1.125 + self.dispatch(next_node)
1.126 + temp2 = self.optimiser.optimise_temp_storage()
1.127 +
1.128 + # Use the appropriate mechanism, setting the boolean status for the
1.129 + # comparison.
1.130 +
1.131 + if methods is not None:
1.132 + left_method, right_method = methods
1.133 +
1.134 + # Generate method call using evaluated argument and next node.
1.135 +
1.136 + temp_result = self._generateBinary(node, temp1, temp2, left_method, right_method)
1.137 + self.new_op(temp_result)
1.138 + self._generateTestBoolean(node, temp_result)
1.139 + self.discard_temp(temp_result)
1.140 +
1.141 + else:
1.142 + # Deal with the special operators.
1.143 +
1.144 + if op_name.startswith("is"):
1.145 + self.new_op(temp1)
1.146 + self.record_value()
1.147 + self.new_op(temp2)
1.148 + self.new_op(TestIdentity())
1.149 + self.set_source()
1.150 + self.discard_value()
1.151 +
1.152 + elif op_name.endswith("in"):
1.153 + self._startCallFunc()
1.154 + self.new_op(temp2)
1.155 +
1.156 + # Get method on temp2.
1.157 +
1.158 + self._generateAttr(node, "__contains__", self.attribute_load_instructions)
1.159 + temp_method = self.optimiser.optimise_temp_storage()
1.160 +
1.161 + # Add arguments.
1.162 + # NOTE: No support for defaults.
1.163 +
1.164 + self.new_op(temp2)
1.165 + self.new_op(StoreFrame(0))
1.166 + self.new_op(temp1)
1.167 + self.new_op(StoreFrame(1))
1.168 + self._endCallFuncArgs(2)
1.169 + self._doCallFunc(temp_method)
1.170 + self._endCallFunc(temp_method)
1.171 +
1.172 + temp_result = self.get_temp()
1.173 + self._generateTestBoolean(node, temp_result)
1.174 + self.discard_temp(temp_result)
1.175 +
1.176 + if op_name.find("not") != -1:
1.177 + self.new_op(InvertBoolean())
1.178 +
1.179 + # Test the result and jump to the end label if false.
1.180 +
1.181 + if op is not last_op:
1.182 + self.new_op(JumpIfFalse(end_label))
1.183 +
1.184 + # Compilation duties...
1.185 +
1.186 + self.discard_temp(temp1)
1.187 +
1.188 + self.discard_temp(temp2)
1.189 + self.set_label(end_label)
1.190 +
1.191 + # Yield the appropriate value.
1.192 +
1.193 + self._generateLoadBoolean(node)
1.194 +
1.195 + # Expressions.
1.196 +
1.197 + def visitBackquote(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Backquote")
1.198 +
1.199 + def visitCallFunc(self, node):
1.200 +
1.201 + """
1.202 + Evaluate positional arguments, evaluate and store keyword arguments in
1.203 + the correct location, then invoke the function.
1.204 + """
1.205 +
1.206 + # Mark the frame, evaluate the target, generate the call.
1.207 +
1.208 + self._startCallFunc()
1.209 + self.dispatch(node.node)
1.210 + temp, target = self._generateCallFunc(node.args, node)
1.211 + self._doCallFunc(temp, target)
1.212 + self._endCallFunc(temp, target)
1.213 +
1.214 + def visitConst(self, node):
1.215 + const = self.module.constant_values[node.value]
1.216 + self.new_op(LoadConst(const))
1.217 +
1.218 + def visitDict(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Dict")
1.219 +
1.220 + def visitEllipsis(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Ellipsis")
1.221 +
1.222 + def visitExec(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Exec")
1.223 +
1.224 + def visitExpression(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Expression")
1.225 +
1.226 + def visitGenExpr(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "GenExpr")
1.227 +
1.228 + def visitGenExprFor(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "GenExprFor")
1.229 +
1.230 + def visitGenExprIf(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "GenExprIf")
1.231 +
1.232 + def visitGenExprInner(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "GenExprInner")
1.233 +
1.234 + def visitGetattr(self, node):
1.235 + self._visitAttr(node, self.attribute_load_instructions)
1.236 +
1.237 + def visitList(self, node):
1.238 + self._generateSequence("list", node)
1.239 +
1.240 + def visitListComp(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "ListComp")
1.241 +
1.242 + def visitListCompFor(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "ListCompFor")
1.243 +
1.244 + def visitListCompIf(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "ListCompIf")
1.245 +
1.246 + def visitName(self, node):
1.247 + if node.name == "None":
1.248 + const = self.module.constant_values[None]
1.249 + self.new_op(LoadConst(const))
1.250 + else:
1.251 + self._visitName(node, self.name_load_instructions)
1.252 +
1.253 + def visitSlice(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Slice")
1.254 +
1.255 + def visitSubscript(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Subscript")
1.256 +
1.257 + def visitTuple(self, node):
1.258 + self._generateSequence("tuple", node)
1.259 +
1.260 + # Definitions.
1.261
1.262 def visitAssign(self, node):
1.263
1.264 @@ -1383,36 +1625,6 @@
1.265 self.discard_temp(temp1)
1.266 self.discard_temp(temp2)
1.267
1.268 - def visitBackquote(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Backquote")
1.269 -
1.270 - def visitBitand(self, node):
1.271 - self._visitBinary(node, "__and__", "__rand__")
1.272 -
1.273 - def visitBitor(self, node):
1.274 - self._visitBinary(node, "__or__", "__ror__")
1.275 -
1.276 - def visitBitxor(self, node):
1.277 - self._visitBinary(node, "__xor__", "__rxor__")
1.278 -
1.279 - def visitBreak(self, node):
1.280 - next_label, exit_label = self.get_loop_labels()
1.281 - self.new_op(Jump(exit_label))
1.282 -
1.283 - def visitCallFunc(self, node):
1.284 -
1.285 - """
1.286 - Evaluate positional arguments, evaluate and store keyword arguments in
1.287 - the correct location, then invoke the function.
1.288 - """
1.289 -
1.290 - # Mark the frame, evaluate the target, generate the call.
1.291 -
1.292 - self._startCallFunc()
1.293 - self.dispatch(node.node)
1.294 - temp, target = self._generateCallFunc(node.args, node)
1.295 - self._doCallFunc(temp, target)
1.296 - self._endCallFunc(temp, target)
1.297 -
1.298 def visitClass(self, node):
1.299
1.300 # Store the name.
1.301 @@ -1431,122 +1643,126 @@
1.302 self.dispatch(node.code)
1.303 self.unit = unit
1.304
1.305 - def visitCompare(self, node):
1.306 + def visitDecorators(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Decorators")
1.307 +
1.308 + def visitFrom(self, node): pass
1.309 +
1.310 + def visitFunction(self, node):
1.311 +
1.312 + # Only store the name when visiting this node from outside.
1.313 +
1.314 + if self.unit is not node.unit:
1.315 + self.new_op(LoadConst(node.unit))
1.316 +
1.317 + self.record_value()
1.318 + self._visitName(node, self.name_store_instructions) # AssName equivalent
1.319 + self.set_source()
1.320 + self.discard_value()
1.321 +
1.322 + self._generateFunctionDefaults(node.unit)
1.323 +
1.324 + # Visiting of the code occurs when get_code is invoked on this node.
1.325 +
1.326 + else:
1.327 + extend = ExtendFrame()
1.328 + self.new_op(extend)
1.329 +
1.330 + self.dispatch(node.code)
1.331 + if not isinstance(self.last_op(), Return):
1.332 + self.dispatch(compiler.ast.Name("None"))
1.333 + self.new_op(StoreResult())
1.334 +
1.335 + self.new_op(Return())
1.336 +
1.337 + self.set_frame_usage(node, extend)
1.338 +
1.339 + def visitGlobal(self, node): pass
1.340 +
1.341 + def visitImport(self, node): pass
1.342 +
1.343 + def visitKeyword(self, node): pass
1.344 +
1.345 + def visitLambda(self, node):
1.346
1.347 """
1.348 - _t1 = node.expr
1.349 - _t1 op1 _t2 and _t2 op2 _t3 and ...
1.350 + Lambda functions can be represented as globally defined functions
1.351 + provided they do not define any default parameter values, since these
1.352 + may defined in a non-global scope.
1.353 +
1.354 + Where defaults are defined, an object must be created and its content
1.355 + defined: the callable member of the object's structure must be set to
1.356 + the lambda function definition; each default must be attached to the
1.357 + object as an attribute, as is the case with normal functions and
1.358 + methods.
1.359 """
1.360
1.361 - end_label = self.new_label()
1.362 -
1.363 - self.dispatch(node.expr)
1.364 - temp2 = self.optimiser.optimise_temp_storage()
1.365 -
1.366 - last_op = node.ops[-1]
1.367 -
1.368 - for op in node.ops:
1.369 - op_name, next_node = op
1.370 - methods = self.comparison_methods[op_name]
1.371 -
1.372 - temp1 = temp2
1.373 - self.dispatch(next_node)
1.374 - temp2 = self.optimiser.optimise_temp_storage()
1.375 -
1.376 - # Use the appropriate mechanism, setting the boolean status for the
1.377 - # comparison.
1.378 -
1.379 - if methods is not None:
1.380 - left_method, right_method = methods
1.381 -
1.382 - # Generate method call using evaluated argument and next node.
1.383 -
1.384 - temp_result = self._generateBinary(node, temp1, temp2, left_method, right_method)
1.385 - self._generateTestBoolean(node, temp_result)
1.386 - self.discard_temp(temp_result)
1.387 -
1.388 - else:
1.389 - # Deal with the special operators.
1.390 -
1.391 - if op_name.startswith("is"):
1.392 - self.new_op(temp1)
1.393 - self.record_value()
1.394 - self.new_op(temp2)
1.395 - self.new_op(TestIdentity())
1.396 - self.set_source()
1.397 - self.discard_value()
1.398 -
1.399 - elif op_name.endswith("in"):
1.400 - self._startCallFunc()
1.401 - self.new_op(temp2)
1.402 -
1.403 - # Get method on temp2.
1.404 -
1.405 - self._generateAttr(node, "__contains__", self.attribute_load_instructions)
1.406 - temp_method = self.optimiser.optimise_temp_storage()
1.407 -
1.408 - # Add arguments.
1.409 - # NOTE: No support for defaults.
1.410 -
1.411 - self.new_op(temp2)
1.412 - self.new_op(StoreFrame(0))
1.413 - self.new_op(temp1)
1.414 - self.new_op(StoreFrame(1))
1.415 - self._endCallFuncArgs(2)
1.416 - self._doCallFunc(temp_method)
1.417 - self._endCallFunc(temp_method)
1.418 -
1.419 - temp_result = self.get_temp()
1.420 - self._generateTestBoolean(node, temp_result)
1.421 - self.discard_temp(temp_result)
1.422 -
1.423 - if op_name.find("not") != -1:
1.424 - self.new_op(InvertBoolean())
1.425 -
1.426 - # Test the result and jump to the end label if false.
1.427 -
1.428 - if op is not last_op:
1.429 - self.new_op(JumpIfFalse(end_label))
1.430 -
1.431 - # Compilation duties...
1.432 -
1.433 - self.discard_temp(temp1)
1.434 -
1.435 - self.discard_temp(temp2)
1.436 - self.set_label(end_label)
1.437 -
1.438 - # Yield the appropriate value.
1.439 -
1.440 - self._generateLoadBoolean(node)
1.441 -
1.442 - def visitConst(self, node):
1.443 - const = self.module.constant_values[node.value]
1.444 - self.new_op(LoadConst(const))
1.445 + # Produce the reference to this function when visiting this node from
1.446 + # outside.
1.447 +
1.448 + if self.unit is not node.unit:
1.449 + temp = self._generateFunctionDefaults(node.unit)
1.450 + self.new_op(LoadConst(node.unit))
1.451 +
1.452 + # Populate the new object required for the function.
1.453 +
1.454 + if temp is not None:
1.455 + self.new_op(LoadCallable())
1.456 + self.new_op(temp)
1.457 + self.new_op(StoreCallable())
1.458 +
1.459 + self.new_op(temp)
1.460 + #self.discard_temp(temp)
1.461 +
1.462 + # Visiting of the code occurs when get_code is invoked on this node.
1.463 +
1.464 + else:
1.465 + self.dispatch(node.code)
1.466 + self.new_op(StoreResult())
1.467 + self.new_op(Return())
1.468 +
1.469 + def visitModule(self, node):
1.470 + extend = ExtendFrame()
1.471 + self.new_op(extend)
1.472 + self.dispatch(node.node)
1.473 + self.set_frame_usage(node, extend)
1.474 +
1.475 + # Statements.
1.476 +
1.477 + def visitStmt(self, node):
1.478 +
1.479 + "Process the collection of statements provided by 'node'."
1.480 +
1.481 + for n in node.nodes:
1.482 +
1.483 + # Process the statement.
1.484 +
1.485 + self.dispatch(n)
1.486 +
1.487 + # Discard temporary storage.
1.488 +
1.489 + if self.temp_positions:
1.490 + #print "Had temp", self.temp_positions
1.491 + self.temp_positions = set()
1.492 +
1.493 + # Prevent incorrect optimisation by resetting the optimiser after
1.494 + # each statement.
1.495 +
1.496 + self.optimiser.reset()
1.497 +
1.498 + def visitAssert(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Assert")
1.499 +
1.500 + def visitBreak(self, node):
1.501 + next_label, exit_label = self.get_loop_labels()
1.502 + self.new_op(Jump(exit_label))
1.503
1.504 def visitContinue(self, node):
1.505 next_label, exit_label = self.get_loop_labels()
1.506 self.new_op(Jump(next_label))
1.507
1.508 - def visitDecorators(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Decorators")
1.509 -
1.510 - def visitDict(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Dict")
1.511 -
1.512 def visitDiscard(self, node):
1.513 self.dispatch(node.expr)
1.514 self.optimiser.optimise_unused_results()
1.515
1.516 - def visitDiv(self, node):
1.517 - self._visitBinary(node, "__div__", "__rdiv__")
1.518 -
1.519 - def visitEllipsis(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Ellipsis")
1.520 -
1.521 - def visitExec(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Exec")
1.522 -
1.523 - def visitExpression(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Expression")
1.524 -
1.525 - def visitFloorDiv(self, node):
1.526 - self._visitBinary(node, "__floordiv__", "__rfloordiv__")
1.527 -
1.528 def visitFor(self, node):
1.529 next_handler_label = self.new_label()
1.530 end_handler_label = self.new_label()
1.531 @@ -1631,6 +1847,11 @@
1.532
1.533 if node.else_ is not None:
1.534 self.set_label(exit_label)
1.535 +
1.536 + # Prevent incorrect optimisation.
1.537 +
1.538 + self.optimiser.reset()
1.539 +
1.540 self.dispatch(node.else_)
1.541
1.542 # After the loop...
1.543 @@ -1641,50 +1862,6 @@
1.544
1.545 self.discard_temp(temp_iterator)
1.546
1.547 - def visitFrom(self, node): pass
1.548 -
1.549 - def visitFunction(self, node):
1.550 -
1.551 - # Only store the name when visiting this node from outside.
1.552 -
1.553 - if self.unit is not node.unit:
1.554 - self.new_op(LoadConst(node.unit))
1.555 -
1.556 - self.record_value()
1.557 - self._visitName(node, self.name_store_instructions) # AssName equivalent
1.558 - self.set_source()
1.559 - self.discard_value()
1.560 -
1.561 - self._generateFunctionDefaults(node.unit)
1.562 -
1.563 - # Visiting of the code occurs when get_code is invoked on this node.
1.564 -
1.565 - else:
1.566 - extend = ExtendFrame()
1.567 - self.new_op(extend)
1.568 -
1.569 - self.dispatch(node.code)
1.570 - if not isinstance(self.last_op(), Return):
1.571 - self.dispatch(compiler.ast.Name("None"))
1.572 - self.new_op(StoreResult())
1.573 -
1.574 - self.new_op(Return())
1.575 -
1.576 - self.set_frame_usage(node, extend)
1.577 -
1.578 - def visitGenExpr(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "GenExpr")
1.579 -
1.580 - def visitGenExprFor(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "GenExprFor")
1.581 -
1.582 - def visitGenExprIf(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "GenExprIf")
1.583 -
1.584 - def visitGenExprInner(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "GenExprInner")
1.585 -
1.586 - def visitGetattr(self, node):
1.587 - self._visitAttr(node, self.attribute_load_instructions)
1.588 -
1.589 - def visitGlobal(self, node): pass
1.590 -
1.591 def visitIf(self, node):
1.592 first = 1
1.593 exit_label = self.new_label()
1.594 @@ -1705,129 +1882,17 @@
1.595 self.dispatch(body)
1.596 if clause is not last_clause:
1.597 self.new_op(Jump(exit_label))
1.598 +
1.599 + # Prevent incorrect optimisation.
1.600 +
1.601 + self.optimiser.reset()
1.602 +
1.603 first = 0
1.604
1.605 self.set_label(exit_label)
1.606
1.607 - def visitImport(self, node): pass
1.608 -
1.609 - def visitInvert(self, node):
1.610 - self._visitUnary(node, "__invert__")
1.611 -
1.612 - def visitKeyword(self, node): pass
1.613 -
1.614 - def visitLambda(self, node):
1.615 -
1.616 - """
1.617 - Lambda functions can be represented as globally defined functions
1.618 - provided they do not define any default parameter values, since these
1.619 - may defined in a non-global scope.
1.620 -
1.621 - Where defaults are defined, an object must be created and its content
1.622 - defined: the callable member of the object's structure must be set to
1.623 - the lambda function definition; each default must be attached to the
1.624 - object as an attribute, as is the case with normal functions and
1.625 - methods.
1.626 - """
1.627 -
1.628 - # Produce the reference to this function when visiting this node from
1.629 - # outside.
1.630 -
1.631 - if self.unit is not node.unit:
1.632 - temp = self._generateFunctionDefaults(node.unit)
1.633 - self.new_op(LoadConst(node.unit))
1.634 -
1.635 - # Populate the new object required for the function.
1.636 -
1.637 - if temp is not None:
1.638 - self.new_op(LoadCallable())
1.639 - self.new_op(temp)
1.640 - self.new_op(StoreCallable())
1.641 -
1.642 - self.new_op(temp)
1.643 - #self.discard_temp(temp)
1.644 -
1.645 - # Visiting of the code occurs when get_code is invoked on this node.
1.646 -
1.647 - else:
1.648 - self.dispatch(node.code)
1.649 - self.new_op(StoreResult())
1.650 - self.new_op(Return())
1.651 -
1.652 - def visitLeftShift(self, node):
1.653 - self._visitBinary(node, "__lshift__", "__rlshift__")
1.654 -
1.655 - def visitList(self, node):
1.656 - self._generateSequence("list", node)
1.657 -
1.658 - def visitListComp(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "ListComp")
1.659 -
1.660 - def visitListCompFor(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "ListCompFor")
1.661 -
1.662 - def visitListCompIf(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "ListCompIf")
1.663 -
1.664 - def visitMod(self, node):
1.665 - self._visitBinary(node, "__mod__", "__rmod__")
1.666 -
1.667 - def visitModule(self, node):
1.668 - extend = ExtendFrame()
1.669 - self.new_op(extend)
1.670 - self.dispatch(node.node)
1.671 - self.set_frame_usage(node, extend)
1.672 -
1.673 - def visitMul(self, node):
1.674 - self._visitBinary(node, "__mul__", "__rmul__")
1.675 -
1.676 - def visitName(self, node):
1.677 - if node.name == "None":
1.678 - const = self.module.constant_values[None]
1.679 - self.new_op(LoadConst(const))
1.680 - else:
1.681 - self._visitName(node, self.name_load_instructions)
1.682 -
1.683 - def visitNot(self, node):
1.684 - self.dispatch(node.expr)
1.685 -
1.686 - temp = self.optimiser.optimise_temp_storage()
1.687 - self._generateTestBoolean(node.expr, temp)
1.688 - self.discard_temp(temp)
1.689 -
1.690 - self.new_op(InvertBoolean())
1.691 - self._generateLoadBoolean(node)
1.692 -
1.693 - # Prevent incorrect optimisation.
1.694 -
1.695 - self.optimiser.reset()
1.696 -
1.697 - def visitOr(self, node):
1.698 - end_label = self.new_label()
1.699 - temp_pos = self.reserve_temp()
1.700 - temp = LoadTemp(temp_pos)
1.701 -
1.702 - for n in node.nodes[:-1]:
1.703 - self.dispatch(n)
1.704 - self.new_op(StoreTemp(temp_pos))
1.705 -
1.706 - self._generateTestBoolean(n, temp)
1.707 - self.new_op(JumpIfTrue(end_label))
1.708 -
1.709 - self.dispatch(node.nodes[-1])
1.710 - self.new_op(StoreTemp(temp_pos))
1.711 -
1.712 - self.set_label(end_label)
1.713 -
1.714 - # Prevent incorrect optimisation.
1.715 -
1.716 - self.optimiser.reset()
1.717 -
1.718 - self.new_op(temp)
1.719 - self.discard_temp(temp)
1.720 -
1.721 def visitPass(self, node): pass
1.722
1.723 - def visitPower(self, node):
1.724 - self._visitBinary(node, "__pow__", "__rpow__")
1.725 -
1.726 def visitPrint(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Print")
1.727
1.728 def visitPrintnl(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Printnl")
1.729 @@ -1863,40 +1928,9 @@
1.730 self.new_op(StoreResult())
1.731 self.new_op(Return())
1.732
1.733 - def visitRightShift(self, node):
1.734 - self._visitBinary(node, "__rshift__", "__rrshift__")
1.735 -
1.736 - def visitSlice(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Slice")
1.737 -
1.738 - def visitStmt(self, node):
1.739 -
1.740 - "Process the collection of statements provided by 'node'."
1.741 -
1.742 - for n in node.nodes:
1.743 -
1.744 - # Process the statement.
1.745 -
1.746 - self.dispatch(n)
1.747 -
1.748 - # Discard temporary storage.
1.749 -
1.750 - if self.temp_positions:
1.751 - #print "Had temp", self.temp_positions
1.752 - self.temp_positions = set()
1.753 -
1.754 - # Prevent incorrect optimisation by resetting the optimiser after
1.755 - # each statement.
1.756 -
1.757 - self.optimiser.reset()
1.758 -
1.759 - def visitSub(self, node):
1.760 - self._visitBinary(node, "__sub__", "__rsub__")
1.761 -
1.762 - def visitSubscript(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "Subscript")
1.763 -
1.764 def visitTryExcept(self, node):
1.765 exit_label = self.new_label()
1.766 - success_label = self.new_label()
1.767 + else_label = self.new_label()
1.768 handler_label = self.new_label()
1.769
1.770 self.add_exception_labels(handler_label, exit_label)
1.771 @@ -1907,11 +1941,20 @@
1.772 self.new_op(PushHandler(handler_label))
1.773 self.dispatch(node.body)
1.774 self.new_op(PopHandler())
1.775 - self.new_op(Jump(exit_label))
1.776 +
1.777 + if node.else_ is not None:
1.778 + self.new_op(Jump(else_label))
1.779 + else:
1.780 + self.new_op(Jump(exit_label))
1.781
1.782 # Start of handlers.
1.783
1.784 self.set_label(handler_label)
1.785 +
1.786 + # Prevent incorrect optimisation.
1.787 +
1.788 + self.optimiser.reset()
1.789 +
1.790 self.new_op(PopHandler())
1.791
1.792 for name, assignment, handler in node.handlers:
1.793 @@ -1943,6 +1986,10 @@
1.794
1.795 self.set_label(next_label)
1.796
1.797 + # Prevent incorrect optimisation.
1.798 +
1.799 + self.optimiser.reset()
1.800 +
1.801 # Unhandled exceptions.
1.802
1.803 self.new_op(RaiseException())
1.804 @@ -1950,6 +1997,12 @@
1.805 # Optional else clause.
1.806
1.807 if node.else_ is not None:
1.808 + self.set_label(else_label)
1.809 +
1.810 + # Prevent incorrect optimisation.
1.811 +
1.812 + self.optimiser.reset()
1.813 +
1.814 self.dispatch(node.else_)
1.815
1.816 self.set_label(exit_label)
1.817 @@ -1957,15 +2010,6 @@
1.818
1.819 def visitTryFinally(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "TryFinally")
1.820
1.821 - def visitTuple(self, node):
1.822 - self._generateSequence("tuple", node)
1.823 -
1.824 - def visitUnaryAdd(self, node):
1.825 - self._visitUnary(node, "__pos__")
1.826 -
1.827 - def visitUnarySub(self, node):
1.828 - self._visitUnary(node, "__neg__")
1.829 -
1.830 def visitWhile(self, node):
1.831 exit_label = self.new_label()
1.832 next_label = self.new_label()
1.833 @@ -1985,9 +2029,19 @@
1.834
1.835 if node.else_ is not None:
1.836 self.set_label(else_label)
1.837 +
1.838 + # Prevent incorrect optimisation.
1.839 +
1.840 + self.optimiser.reset()
1.841 +
1.842 self.dispatch(node.else_)
1.843
1.844 self.set_label(exit_label)
1.845 +
1.846 + # Prevent incorrect optimisation.
1.847 +
1.848 + self.optimiser.reset()
1.849 +
1.850 self.drop_loop_labels()
1.851
1.852 def visitWith(self, node): raise TranslationNotImplementedError(self.module.full_name(), node, "With")