[Python-checkins] CVS: python/dist/src/Tools/compiler/compiler pycodegen.py,1.39,1.39.2.1

Jeremy Hylton jhylton@users.sourceforge.net
2001年12月17日 16:06:05 -0800


Update of /cvsroot/python/python/dist/src/Tools/compiler/compiler
In directory usw-pr-cvs1:/tmp/cvs-serv31507
Modified Files:
 Tag: release21-maint
	pycodegen.py 
Log Message:
Backport bugfixes since rev 1.39 from the trunk.
Add is_constant_false(), rev 1.41.
Fixed print handling, rev. 1.41.
Handle private names, 1.42.
Make sure JUMP_ABS and POP_BLOCK blocks are contiguous, rev. 1.44.
Make sure class object has no co_varnames, rev. 1.45.
Fix typo in visitDict(), rev. 1.46.
Generate correct code for continue in try/except, rev. 1.47.
Index: pycodegen.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/compiler/compiler/Attic/pycodegen.py,v
retrieving revision 1.39
retrieving revision 1.39.2.1
diff -C2 -d -r1.39 -r1.39.2.1
*** pycodegen.py	2001年04月12日 21:54:41	1.39
--- pycodegen.py	2001年12月18日 00:06:03	1.39.2.1
***************
*** 12,17 ****
 from compiler import pyassem, misc, future, symbols
 from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL
! from compiler.pyassem import CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS,\
! CO_NESTED, TupleArg
 
 # Do we have Python 1.x or Python 2.x?
--- 12,18 ----
 from compiler import pyassem, misc, future, symbols
 from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL
! from compiler.consts import CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS,\
! CO_NESTED
! from compiler.pyassem import TupleArg
 
 # Do we have Python 1.x or Python 2.x?
***************
*** 29,32 ****
--- 30,38 ----
 }
 
+ LOOP = 1
+ EXCEPT = 2
+ TRY_FINALLY = 3
+ END_FINALLY = 4
+ 
 def compile(filename, display=0):
 f = open(filename)
***************
*** 34,41 ****
 f.close()
 mod = Module(buf, filename)
! mod.compile(display)
! f = open(filename + "c", "wb")
! mod.dump(f)
! f.close()
 
 class Module:
--- 40,51 ----
 f.close()
 mod = Module(buf, filename)
! try:
! mod.compile(display)
! except SyntaxError:
! raise
! else:
! f = open(filename + "c", "wb")
! mod.dump(f)
! f.close()
 
 class Module:
***************
*** 116,119 ****
--- 126,135 ----
 self.names.add(node.name)
 
+ def is_constant_false(node):
+ if isinstance(node, ast.Const):
+ if not node.value:
+ return 1
+ return 0
+ 
 class CodeGenerator:
 """Defines basic code generator for Python bytecode
***************
*** 132,135 ****
--- 148,152 ----
 optimized = 0 # is namespace access optimized?
 __initialized = None
+ class_name = None # provide default for instance variable
 
 def __init__(self, filename):
***************
*** 140,144 ****
 self.filename = filename
 self.locals = misc.Stack()
! self.loops = misc.Stack()
 self.curStack = 0
 self.maxStack = 0
--- 157,161 ----
 self.filename = filename
 self.locals = misc.Stack()
! self.setups = misc.Stack()
 self.curStack = 0
 self.maxStack = 0
***************
*** 171,174 ****
--- 188,202 ----
 return self.graph.getCode()
 
+ def mangle(self, name):
+ if self.class_name is not None:
+ return misc.mangle(name, self.class_name)
+ else:
+ return name
+ 
+ def parseSymbols(self, tree):
+ s = symbols.SymbolVisitor()
+ walk(tree, s)
+ return s.scopes
+ 
 # Next five methods handle name access
 
***************
*** 186,196 ****
 
 def _nameOp(self, prefix, name):
! if not self.optimized:
! self.emit(prefix + '_NAME', name)
! return
! if self.isLocalName(name):
! self.emit(prefix + '_FAST', name)
 else:
! self.emit(prefix + '_GLOBAL', name)
 
 def _implicitNameOp(self, prefix, name):
--- 214,234 ----
 
 def _nameOp(self, prefix, name):
! name = self.mangle(name)
! scope = self.scope.check_name(name)
! if scope == SC_LOCAL:
! if not self.optimized:
! self.emit(prefix + '_NAME', name)
! else:
! self.emit(prefix + '_FAST', name)
! elif scope == SC_GLOBAL:
! if not self.optimized:
! self.emit(prefix + '_NAME', name)
! else:
! self.emit(prefix + '_GLOBAL', name)
! elif scope == SC_FREE or scope == SC_CELL:
! self.emit(prefix + '_DEREF', name)
 else:
! raise RuntimeError, "unsupported scope for var %s: %d" % \
! (name, scope)
 
 def _implicitNameOp(self, prefix, name):
***************
*** 234,242 ****
 
 def visitModule(self, node):
 self.emit('SET_LINENO', 0)
- lnf = walk(node.node, self.NameFinder(), 0)
- self.locals.push(lnf.getLocals())
 if node.doc:
! self.fixDocstring(node.node)
 self.visit(node.node)
 self.emit('LOAD_CONST', None)
--- 272,283 ----
 
 def visitModule(self, node):
+ self.scopes = self.parseSymbols(node)
+ self.scope = self.scopes[node]
 self.emit('SET_LINENO', 0)
 if node.doc:
! self.emit('LOAD_CONST', node.doc)
! self.storeName('__doc__')
! lnf = walk(node.node, self.NameFinder(), verbose=0)
! self.locals.push(lnf.getLocals())
 self.visit(node.node)
 self.emit('LOAD_CONST', None)
***************
*** 253,257 ****
 
 def _visitFuncOrLambda(self, node, isLambda=0):
! gen = self.FunctionGen(node, self.filename, self.scopes, isLambda)
 walk(node.code, gen)
 gen.finish()
--- 294,299 ----
 
 def _visitFuncOrLambda(self, node, isLambda=0):
! gen = self.FunctionGen(node, self.filename, self.scopes, isLambda,
! self.class_name)
 walk(node.code, gen)
 gen.finish()
***************
*** 263,269 ****
 
 def visitClass(self, node):
! gen = self.ClassGen(node, self.filename, self.scopes)
! if node.doc:
! self.fixDocstring(node.code)
 walk(node.code, gen)
 gen.finish()
--- 305,309 ----
 
 def visitClass(self, node):
! gen = self.ClassGen(node, self.scopes, self.filename)
 walk(node.code, gen)
 gen.finish()
***************
*** 279,295 ****
 self.storeName(node.name)
 
- def fixDocstring(self, node):
- """Rewrite the ast for a class with a docstring.
- 
- The AST includes a Discard(Const(docstring)) node. Replace
- this with an Assign([AssName('__doc__', ...])
- """
- assert isinstance(node, ast.Stmt)
- stmts = node.nodes
- discard = stmts[0]
- assert isinstance(discard, ast.Discard)
- stmts[0] = ast.Assign([ast.AssName('__doc__', 'OP_ASSIGN')],
- discard.expr)
- stmts[0].lineno = discard.lineno
 # The rest are standard visitor methods
 
--- 319,322 ----
***************
*** 301,304 ****
--- 328,333 ----
 for i in range(numtests):
 test, suite = node.tests[i]
+ if is_constant_false(test):
+ continue
 self.set_lineno(test)
 self.visit(test)
***************
*** 325,329 ****
 
 self.nextBlock(loop)
! self.loops.push(loop)
 
 self.set_lineno(node, force=1)
--- 354,358 ----
 
 self.nextBlock(loop)
! self.setups.push((LOOP, loop))
 
 self.set_lineno(node, force=1)
***************
*** 339,343 ****
 self.emit('POP_TOP')
 self.emit('POP_BLOCK')
! self.loops.pop()
 if node.else_:
 self.visit(node.else_)
--- 368,372 ----
 self.emit('POP_TOP')
 self.emit('POP_BLOCK')
! self.setups.pop()
 if node.else_:
 self.visit(node.else_)
***************
*** 348,352 ****
 anchor = self.newBlock()
 after = self.newBlock()
! self.loops.push(start)
 
 self.set_lineno(node)
--- 377,381 ----
 anchor = self.newBlock()
 after = self.newBlock()
! self.setups.push((LOOP, start))
 
 self.set_lineno(node)
***************
*** 357,367 ****
 self.set_lineno(node, force=1)
 self.emit('FOR_LOOP', anchor)
! self.nextBlock()
 self.visit(node.assign)
 self.visit(node.body)
 self.emit('JUMP_ABSOLUTE', start)
! self.startBlock(anchor)
 self.emit('POP_BLOCK')
! self.loops.pop()
 if node.else_:
 self.visit(node.else_)
--- 386,397 ----
 self.set_lineno(node, force=1)
 self.emit('FOR_LOOP', anchor)
! ## self.nextBlock()
 self.visit(node.assign)
 self.visit(node.body)
 self.emit('JUMP_ABSOLUTE', start)
! ## self.startBlock(anchor)
! self.nextBlock(anchor)
 self.emit('POP_BLOCK')
! self.setups.pop()
 if node.else_:
 self.visit(node.else_)
***************
*** 369,373 ****
 
 def visitBreak(self, node):
! if not self.loops:
 raise SyntaxError, "'break' outside loop (%s, %d)" % \
 (self.filename, node.lineno)
--- 399,403 ----
 
 def visitBreak(self, node):
! if not self.setups:
 raise SyntaxError, "'break' outside loop (%s, %d)" % \
 (self.filename, node.lineno)
***************
*** 376,386 ****
 
 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):
--- 406,435 ----
 
 def visitContinue(self, node):
! # XXX test_grammar.py, line 351
! 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):
***************
*** 527,530 ****
--- 576,580 ----
 
 def visitTryExcept(self, node):
+ body = self.newBlock()
 handlers = self.newBlock()
 end = self.newBlock()
***************
*** 535,541 ****
 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)
--- 585,593 ----
 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)
***************
*** 573,586 ****
 
 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
--- 625,643 ----
 
 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
***************
*** 649,653 ****
 def visitGetattr(self, node):
 self.visit(node.expr)
! self.emit('LOAD_ATTR', node.attrname)
 
 # next five implement assignments
--- 706,710 ----
 def visitGetattr(self, node):
 self.visit(node.expr)
! self.emit('LOAD_ATTR', self.mangle(node.attrname))
 
 # next five implement assignments
***************
*** 668,671 ****
--- 725,729 ----
 self.storeName(node.name)
 elif node.flags == 'OP_DELETE':
+ self.set_lineno(node)
 self.delName(node.name)
 else:
***************
*** 675,681 ****
 self.visit(node.expr)
 if node.flags == 'OP_ASSIGN':
! self.emit('STORE_ATTR', node.attrname)
 elif node.flags == 'OP_DELETE':
! self.emit('DELETE_ATTR', node.attrname)
 else:
 print "warning: unexpected flags:", node.flags
--- 733,739 ----
 self.visit(node.expr)
 if node.flags == 'OP_ASSIGN':
! self.emit('STORE_ATTR', self.mangle(node.attrname))
 elif node.flags == 'OP_DELETE':
! self.emit('DELETE_ATTR', self.mangle(node.attrname))
 else:
 print "warning: unexpected flags:", node.flags
***************
*** 701,704 ****
--- 759,763 ----
 
 def visitAugAssign(self, node):
+ self.set_lineno(node)
 aug_node = wrap_aug(node.node)
 self.visit(aug_node, "load")
***************
*** 731,738 ****
 self.visit(node.expr)
 self.emit('DUP_TOP')
! self.emit('LOAD_ATTR', node.attrname)
 elif mode == "store":
 self.emit('ROT_TWO')
! self.emit('STORE_ATTR', node.attrname)
 
 def visitAugSlice(self, node, mode):
--- 790,797 ----
 self.visit(node.expr)
 self.emit('DUP_TOP')
! self.emit('LOAD_ATTR', self.mangle(node.attrname))
 elif mode == "store":
 self.emit('ROT_TWO')
! self.emit('STORE_ATTR', self.mangle(node.attrname))
 
 def visitAugSlice(self, node, mode):
***************
*** 794,798 ****
 self.emit(opcode, kw << 8 | pos)
 
! def visitPrint(self, node):
 self.set_lineno(node)
 if node.dest:
--- 853,857 ----
 self.emit(opcode, kw << 8 | pos)
 
! def visitPrint(self, node, newline=0):
 self.set_lineno(node)
 if node.dest:
***************
*** 807,813 ****
 else:
 self.emit('PRINT_ITEM')
 
 def visitPrintnl(self, node):
! self.visitPrint(node)
 if node.dest:
 self.emit('PRINT_NEWLINE_TO')
--- 866,874 ----
 else:
 self.emit('PRINT_ITEM')
+ if node.dest and not newline:
+ self.emit('POP_TOP')
 
 def visitPrintnl(self, node):
! self.visitPrint(node, newline=1)
 if node.dest:
 self.emit('PRINT_NEWLINE_TO')
***************
*** 942,945 ****
--- 1003,1007 ----
 
 def visitTuple(self, node):
+ self.set_lineno(node)
 for elt in node.nodes:
 self.visit(elt)
***************
*** 947,950 ****
--- 1009,1013 ----
 
 def visitList(self, node):
+ self.set_lineno(node)
 for elt in node.nodes:
 self.visit(elt)
***************
*** 959,963 ****
 lineno = getattr(node, 'lineno', None)
 if lineno:
! set.emit('SET_LINENO', lineno)
 self.emit('BUILD_MAP', 0)
 for k, v in node.items:
--- 1022,1026 ----
 lineno = getattr(node, 'lineno', None)
 if lineno:
! self.emit('SET_LINENO', lineno)
 self.emit('BUILD_MAP', 0)
 for k, v in node.items:
***************
*** 988,991 ****
--- 1051,1055 ----
 
 def _nameOp(self, prefix, name):
+ name = self.mangle(name)
 scope = self.scope.check_name(name)
 if scope == SC_LOCAL:
***************
*** 1003,1007 ****
 
 def _visitFuncOrLambda(self, node, isLambda=0):
! gen = self.FunctionGen(node, self.filename, self.scopes, isLambda)
 walk(node.code, gen)
 gen.finish()
--- 1067,1072 ----
 
 def _visitFuncOrLambda(self, node, isLambda=0):
! gen = self.FunctionGen(node, self.filename, self.scopes, isLambda,
! self.class_name)
 walk(node.code, gen)
 gen.finish()
***************
*** 1020,1026 ****
 
 def visitClass(self, node):
! gen = self.ClassGen(node, self.filename, self.scopes)
! if node.doc:
! self.fixDocstring(node.code)
 walk(node.code, gen)
 gen.finish()
--- 1085,1089 ----
 
 def visitClass(self, node):
! gen = self.ClassGen(node, self.scopes, self.filename)
 walk(node.code, gen)
 gen.finish()
***************
*** 1079,1083 ****
 lambdaCount = 0
 
! def __init__(self, func, filename, scopes, isLambda):
 if isLambda:
 klass = FunctionCodeGenerator
--- 1142,1149 ----
 lambdaCount = 0
 
! def __init__(self, func, filename, scopes, isLambda, class_name):
! self.scopes = scopes
! self.scope = scopes[func]
! self.class_name = class_name
 if isLambda:
 klass = FunctionCodeGenerator
***************
*** 1095,1099 ****
 self.setDocstring(func.doc)
 
! lnf = walk(func.code, self.NameFinder(args), 0)
 self.locals.push(lnf.getLocals())
 if func.varargs:
--- 1161,1165 ----
 self.setDocstring(func.doc)
 
! lnf = walk(func.code, self.NameFinder(args), verbose=0)
 self.locals.push(lnf.getLocals())
 if func.varargs:
***************
*** 1142,1149 ****
 __super_init = AbstractFunctionCode.__init__
 
! def __init__(self, func, filename, scopes, isLambda):
 self.scopes = scopes
 self.scope = scopes[func]
! self.__super_init(func, filename, scopes, isLambda)
 self.graph.setFreeVars(self.scope.get_free_vars())
 self.graph.setCellVars(self.scope.get_cell_vars())
--- 1208,1215 ----
 __super_init = AbstractFunctionCode.__init__
 
! def __init__(self, func, filename, scopes, isLambda, class_name):
 self.scopes = scopes
 self.scope = scopes[func]
! self.__super_init(func, filename, scopes, isLambda, class_name)
 self.graph.setFreeVars(self.scope.get_free_vars())
 self.graph.setCellVars(self.scope.get_cell_vars())
***************
*** 1152,1156 ****
 class AbstractClassCode:
 
! def __init__(self, klass, filename, scopes):
 self.graph = pyassem.PyFlowGraph(klass.name, filename,
 optimized=0)
--- 1218,1224 ----
 class AbstractClassCode:
 
! def __init__(self, klass, scopes, filename):
! assert isinstance(filename, types.StringType)
! assert isinstance(scopes, types.DictType)
 self.graph = pyassem.PyFlowGraph(klass.name, filename,
 optimized=0)
***************
*** 1175,1178 ****
--- 1243,1255 ----
 scopes = None
 
+ __super_init = AbstractClassCode.__init__
+ 
+ def __init__(self, klass, scopes, filename):
+ self.scopes = scopes
+ self.scope = scopes[klass]
+ self.__super_init(klass, scopes, filename)
+ self.graph.setFreeVars(self.scope.get_free_vars())
+ self.graph.setCellVars(self.scope.get_cell_vars())
+ 
 class NestedClassCodeGenerator(AbstractClassCode,
 NestedScopeMixin,
***************
*** 1181,1188 ****
 __super_init = AbstractClassCode.__init__
 
! def __init__(self, klass, filename, scopes):
 self.scopes = scopes
 self.scope = scopes[klass]
! self.__super_init(klass, filename, scopes)
 self.graph.setFreeVars(self.scope.get_free_vars())
 self.graph.setCellVars(self.scope.get_cell_vars())
--- 1258,1266 ----
 __super_init = AbstractClassCode.__init__
 
! def __init__(self, klass, scopes, filename):
! assert isinstance(filename, types.StringType)
 self.scopes = scopes
 self.scope = scopes[klass]
! self.__super_init(klass, scopes, filename)
 self.graph.setFreeVars(self.scope.get_free_vars())
 self.graph.setCellVars(self.scope.get_cell_vars())
***************
*** 1209,1213 ****
 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
 v = OpFinder()
! walk(node, v, 0)
 return v.op
 
--- 1287,1291 ----
 """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
 v = OpFinder()
! walk(node, v, verbose=0)
 return v.op
 
***************
*** 1221,1224 ****
--- 1299,1303 ----
 raise ValueError, "mixed ops in stmt"
 visitAssAttr = visitAssName
+ visitSubscript = visitAssName
 
 class Delegator:
***************
*** 1250,1253 ****
--- 1329,1333 ----
 class AugSubscript(Delegator):
 pass
+ 
 
 wrapper = {

AltStyle によって変換されたページ (->オリジナル) /