diff options
author | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-04-12 20:21:39 (GMT) |
---|---|---|
committer | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-04-12 20:21:39 (GMT) |
commit | 542b11acfd5309438ed2769be1fc476b9597f1fb (patch) | |
tree | a6ed2a4207c9421d884b6a171f988cb1ae2b3d8e /Lib/compiler/pycodegen.py | |
parent | 35cf0a3f90de8f2e3597e67701d1e03dd11a8cbe (diff) | |
download | cpython-542b11acfd5309438ed2769be1fc476b9597f1fb.zip cpython-542b11acfd5309438ed2769be1fc476b9597f1fb.tar.gz cpython-542b11acfd5309438ed2769be1fc476b9597f1fb.tar.bz2 |
pyassem.py:
Fix annoying bugs in flow graph layout code. In some cases the
implicit control transfers weren't honored. In other cases,
JUMP_FORWARD instructions jumped backwards.
Remove unused arg from nextBlock().
pycodegen.py
Add optional force kwarg to set_lineno() that will emit a
SET_LINENO even if it is the same as the previous lineno.
Use explicit LOAD_FAST and STORE_FAST to access list comp implicit
variables. (The symbol table doesn't know about them.)
Diffstat (limited to 'Lib/compiler/pycodegen.py')
-rw-r--r-- | Lib/compiler/pycodegen.py | 24 |
1 files changed, 11 insertions, 13 deletions
diff --git a/Lib/compiler/pycodegen.py b/Lib/compiler/pycodegen.py index 691232f..63b0a57 100644 --- a/Lib/compiler/pycodegen.py +++ b/Lib/compiler/pycodegen.py @@ -193,7 +193,7 @@ class CodeGenerator: else: self.emit(prefix + '_GLOBAL', name) - def set_lineno(self, node): + def set_lineno(self, node, force=0): """Emit SET_LINENO if node has lineno attribute and it is different than the last lineno emitted. @@ -205,7 +205,8 @@ class CodeGenerator: then, this method works around missing line numbers. """ lineno = getattr(node, 'lineno', None) - if lineno is not None and lineno != self.last_lineno: + if lineno is not None and (lineno != self.last_lineno + or force): self.emit('SET_LINENO', lineno) self.last_lineno = lineno return 1 @@ -413,9 +414,6 @@ class CodeGenerator: __list_count = 0 def visitListComp(self, node): - # XXX would it be easier to transform the AST into the form it - # would have if the list comp were expressed as a series of - # for and if stmts and an explicit append? self.set_lineno(node) # setup list append = "$append%d" % self.__list_count @@ -423,10 +421,10 @@ class CodeGenerator: self.emit('BUILD_LIST', 0) self.emit('DUP_TOP') self.emit('LOAD_ATTR', 'append') - self.storeName(append) - l = len(node.quals) + self.emit('STORE_FAST', append) + stack = [] - for i, for_ in zip(range(l), node.quals): + for i, for_ in zip(range(len(node.quals)), node.quals): start, anchor = self.visit(for_) cont = None for if_ in for_.ifs: @@ -434,8 +432,8 @@ class CodeGenerator: cont = self.newBlock() self.visit(if_, cont) stack.insert(0, (start, cont, anchor)) - - self.loadName(append) + + self.emit('LOAD_FAST', append) self.visit(node.expr) self.emit('CALL_FUNCTION', 1) self.emit('POP_TOP') @@ -449,12 +447,11 @@ class CodeGenerator: self.nextBlock(skip_one) self.emit('JUMP_ABSOLUTE', start) self.startBlock(anchor) - self.delName(append) + self.emit('DELETE_FAST', append) self.__list_count = self.__list_count - 1 def visitListCompFor(self, node): - self.set_lineno(node) start = self.newBlock() anchor = self.newBlock() @@ -468,7 +465,7 @@ class CodeGenerator: return start, anchor def visitListCompIf(self, node, branch): - self.set_lineno(node) + self.set_lineno(node, force=1) self.visit(node.test) self.emit('JUMP_IF_FALSE', branch) self.newBlock() @@ -672,6 +669,7 @@ class CodeGenerator: print node def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'): +## print >> sys.stderr, "AssSequence", op, findOp(node), node if findOp(node) != 'OP_DELETE': self.emit(op, len(node.nodes)) for child in node.nodes: |