1.1 --- a/micropython/ast.py Sun Feb 20 01:35:15 2011 +0100
1.2 +++ b/micropython/ast.py Sun Feb 20 19:31:50 2011 +0100
1.3 @@ -3,7 +3,7 @@
1.4 """
1.5 Translate the AST of a Python program into a more interpretable representation.
1.6
1.7 -Copyright (C) 2007, 2008, 2009 Paul Boddie <paul@boddie.org.uk>
1.8 +Copyright (C) 2007, 2008, 2009, 2010, 2011 Paul Boddie <paul@boddie.org.uk>
1.9
1.10 This program is free software; you can redistribute it and/or modify it under
1.11 the terms of the GNU General Public License as published by the Free Software
1.12 @@ -123,6 +123,7 @@
1.13
1.14 self.unit = self.module
1.15 self.reset()
1.16 + self.add_exception_unit()
1.17
1.18 block = self.new_block()
1.19 self.set_block(block)
1.20 @@ -142,9 +143,10 @@
1.21
1.22 if self.module.name == "__main__":
1.23 self.set_block(handler_block)
1.24 - self.new_op(PopHandler())
1.25 + self.new_op(PopHandler(1))
1.26 self.new_op(Return())
1.27
1.28 + self.drop_exception_unit()
1.29 self.unit.temp_usage = self.max_temp_position + 1
1.30 self.unit.blocks = self.blocks
1.31 return self.blocks
1.32 @@ -155,6 +157,7 @@
1.33
1.34 self.unit = unit
1.35 self.reset()
1.36 + self.add_exception_unit()
1.37
1.38 block = self.new_block()
1.39 self.set_block(block)
1.40 @@ -162,6 +165,7 @@
1.41 if unit.astnode is not None:
1.42 self.dispatch(unit.astnode)
1.43
1.44 + self.drop_exception_unit()
1.45 self.unit.temp_usage = self.max_temp_position + 2 # include space for instantiators to expand backwards
1.46 self.unit.blocks = self.blocks
1.47 return self.blocks
1.48 @@ -698,6 +702,7 @@
1.49
1.50 # Handle exceptions when calling "next"...
1.51
1.52 + self.add_exception_blocks(next_handler_block, end_handler_block)
1.53 self.new_op(PushHandler(next_handler_block))
1.54
1.55 # Use the iterator to get the next value.
1.56 @@ -715,13 +720,17 @@
1.57
1.58 # Skip the handler where the call was successful.
1.59
1.60 - self.new_op(PopHandler())
1.61 + self.new_op(PopHandler(1))
1.62 self.new_op(Jump(end_handler_block))
1.63
1.64 # Enter the exception handler.
1.65
1.66 self.set_block(next_handler_block)
1.67 - self.new_op(PopHandler())
1.68 + self.new_op(PopHandler(1))
1.69 +
1.70 + # Disable the handlers.
1.71 +
1.72 + self.drop_exception_blocks()
1.73
1.74 # Test for StopIteration.
1.75
1.76 @@ -846,6 +855,11 @@
1.77 if self.in_exception_handler:
1.78 self.new_op(ClearException())
1.79
1.80 + # NOTE: Support finally blocks here.
1.81 +
1.82 + if self.exception_blocks[-1]:
1.83 + self.new_op(PopHandler(len(self.exception_blocks[-1])))
1.84 +
1.85 self.new_op(Return())
1.86
1.87 def visitTryExcept(self, node):
1.88 @@ -860,7 +874,7 @@
1.89
1.90 self.new_op(PushHandler(handler_block))
1.91 self.dispatch(node.body)
1.92 - self.new_op(PopHandler())
1.93 + self.new_op(PopHandler(1))
1.94
1.95 if node.else_ is not None:
1.96 self.new_op(Jump(else_block))
1.97 @@ -870,7 +884,11 @@
1.98 # Start of handlers.
1.99
1.100 self.set_block(handler_block)
1.101 - self.new_op(PopHandler())
1.102 + self.new_op(PopHandler(1))
1.103 +
1.104 + # Disable the handlers.
1.105 +
1.106 + self.drop_exception_blocks()
1.107
1.108 for name, assignment, handler in node.handlers:
1.109 next_block = self.new_block()
1.110 @@ -918,7 +936,6 @@
1.111
1.112 self.set_block(exit_block)
1.113 self.new_op(ClearException())
1.114 - self.drop_exception_blocks()
1.115
1.116 def visitTryFinally(self, node):
1.117