summaryrefslogtreecommitdiffstats
path: root/Lib/compiler/pycodegen.py
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2001-04-12 20:21:39 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2001-04-12 20:21:39 (GMT)
commit542b11acfd5309438ed2769be1fc476b9597f1fb (patch)
treea6ed2a4207c9421d884b6a171f988cb1ae2b3d8e /Lib/compiler/pycodegen.py
parent35cf0a3f90de8f2e3597e67701d1e03dd11a8cbe (diff)
downloadcpython-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.py24
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: