[Python-checkins] CVS: python/dist/src/Tools/compiler/compiler pycodegen.py,1.46,1.47
Jeremy Hylton
jhylton@users.sourceforge.net
Wed, 29 Aug 2001 15:30:11 -0700
Update of /cvsroot/python/python/dist/src/Tools/compiler/compiler
In directory usw-pr-cvs1:/tmp/cvs-serv26905
Modified Files:
pycodegen.py
Log Message:
Track the block stack more reasonably in order to handle continue in
try/except or try/finally.
Previous versions had only track SETUP_LOOP blocks and ignored the
exception part. This meant that it allowed continue inside a
try/except but generated buggy code. Now it does the right thing.
Index: pycodegen.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/compiler/compiler/pycodegen.py,v
retrieving revision 1.46
retrieving revision 1.47
diff -C2 -d -r1.46 -r1.47
*** pycodegen.py 2001/08/29 20:57:43 1.46
--- pycodegen.py 2001/08/29 22:30:09 1.47
***************
*** 29,32 ****
--- 29,37 ----
}
+ LOOP = 1
+ EXCEPT = 2
+ TRY_FINALLY = 3
+ END_FINALLY = 4
+
def compile(filename, display=0):
f = open(filename)
***************
*** 143,147 ****
self.filename = filename
self.locals = misc.Stack()
! self.loops = misc.Stack()
self.curStack = 0
self.maxStack = 0
--- 148,152 ----
self.filename = filename
self.locals = misc.Stack()
! self.setups = misc.Stack()
self.curStack = 0
self.maxStack = 0
***************
*** 328,332 ****
self.nextBlock(loop)
! self.loops.push(loop)
self.set_lineno(node, force=1)
--- 333,337 ----
self.nextBlock(loop)
! self.setups.push((LOOP, loop))
self.set_lineno(node, force=1)
***************
*** 342,346 ****
self.emit('POP_TOP')
self.emit('POP_BLOCK')
! self.loops.pop()
if node.else_:
self.visit(node.else_)
--- 347,351 ----
self.emit('POP_TOP')
self.emit('POP_BLOCK')
! self.setups.pop()
if node.else_:
self.visit(node.else_)
***************
*** 351,355 ****
anchor = self.newBlock()
after = self.newBlock()
! self.loops.push(start)
self.set_lineno(node)
--- 356,360 ----
anchor = self.newBlock()
after = self.newBlock()
! self.setups.push((LOOP, start))
self.set_lineno(node)
***************
*** 366,370 ****
self.nextBlock(anchor)
self.emit('POP_BLOCK')
! self.loops.pop()
if node.else_:
self.visit(node.else_)
--- 371,375 ----
self.nextBlock(anchor)
self.emit('POP_BLOCK')
! self.setups.pop()
if node.else_:
self.visit(node.else_)
***************
*** 372,376 ****
def visitBreak(self, node):
! if not self.loops:
raise SyntaxError, "'break' outside loop (%s, %d)" % \
(self.filename, node.lineno)
--- 377,381 ----
def visitBreak(self, node):
! if not self.setups:
raise SyntaxError, "'break' outside loop (%s, %d)" % \
(self.filename, node.lineno)
***************
*** 379,389 ****
def visitContinue(self, node):
! if not self.loops:
raise SyntaxError, "'continue' outside loop (%s, %d)" % \
(self.filename, node.lineno)
! l = self.loops.top()
! self.set_lineno(node)
! self.emit('JUMP_ABSOLUTE', l)
! self.nextBlock()
def visitTest(self, node, jump):
--- 384,412 ----
def visitContinue(self, node):
! if not self.setups:
raise SyntaxError, "'continue' outside loop (%s, %d)" % \
(self.filename, node.lineno)
! kind, block = self.setups.top()
! if kind == LOOP:
! self.set_lineno(node)
! self.emit('JUMP_ABSOLUTE', block)
! self.nextBlock()
! elif kind == EXCEPT or kind == TRY_FINALLY:
! self.set_lineno(node)
! # find the block that starts the loop
! top = len(self.setups)
! while top > 0:
! top = top - 1
! kind, loop_block = self.setups[top]
! if kind == LOOP:
! break
! if kind != LOOP:
! raise SyntaxError, "'continue' outside loop (%s, %d)" % \
! (self.filename, node.lineno)
! self.emit('CONTINUE_LOOP', loop_block)
! self.nextBlock()
! elif kind == END_FINALLY:
! msg = "'continue' not allowed inside 'finally' clause (%s, %d)"
! raise SyntaxError, msg % (self.filename, node.lineno)
def visitTest(self, node, jump):
***************
*** 530,533 ****
--- 553,557 ----
def visitTryExcept(self, node):
+ body = self.newBlock()
handlers = self.newBlock()
end = self.newBlock()
***************
*** 538,544 ****
self.set_lineno(node)
self.emit('SETUP_EXCEPT', handlers)
! self.nextBlock()
self.visit(node.body)
self.emit('POP_BLOCK')
self.emit('JUMP_FORWARD', lElse)
self.startBlock(handlers)
--- 562,570 ----
self.set_lineno(node)
self.emit('SETUP_EXCEPT', handlers)
! self.nextBlock(body)
! self.setups.push((EXCEPT, body))
self.visit(node.body)
self.emit('POP_BLOCK')
+ self.setups.pop()
self.emit('JUMP_FORWARD', lElse)
self.startBlock(handlers)
***************
*** 571,574 ****
--- 597,601 ----
self.emit('POP_TOP')
self.emit('END_FINALLY')
+ self.setups.pop()
if node.else_:
self.nextBlock(lElse)
***************
*** 577,590 ****
def visitTryFinally(self, node):
final = self.newBlock()
self.set_lineno(node)
self.emit('SETUP_FINALLY', final)
! self.nextBlock()
self.visit(node.body)
self.emit('POP_BLOCK')
self.emit('LOAD_CONST', None)
self.nextBlock(final)
self.visit(node.final)
self.emit('END_FINALLY')
# misc
--- 604,622 ----
def visitTryFinally(self, node):
+ body = self.newBlock()
final = self.newBlock()
self.set_lineno(node)
self.emit('SETUP_FINALLY', final)
! self.nextBlock(body)
! self.setups.push((TRY_FINALLY, body))
self.visit(node.body)
self.emit('POP_BLOCK')
+ self.setups.pop()
self.emit('LOAD_CONST', None)
self.nextBlock(final)
+ self.setups.push((END_FINALLY, final))
self.visit(node.final)
self.emit('END_FINALLY')
+ self.setups.pop()
# misc