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

Jeremy Hylton jhylton@users.sourceforge.net
Mon, 27 Aug 2001 14:51:55 -0700


Update of /cvsroot/python/python/dist/src/Tools/compiler/compiler
In directory usw-pr-cvs1:/tmp/cvs-serv9563

Modified Files:
	pycodegen.py 
Log Message:
Many changes -- bug fixes and sundry improvements

Make nested scopes enabled by default

Add is_constant_false() helper so that compiled code and symbols are
consistent with builtin compiler's handling of "if 0:"

Fix doc string handling to be consistent with recent change that
eliminates the doc string from the Module's node attribute.

Add fix to print handling from Evan & Shane.

Track change to visitor api by making "verbose" explicit.

Comment out setting CO_NESTED flag (it's unnecessary in 2.2).





Index: pycodegen.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/compiler/compiler/pycodegen.py,v
retrieving revision 1.39
retrieving revision 1.40
diff -C2 -d -r1.39 -r1.40
*** pycodegen.py	2001/04/12 21:54:41	1.39
--- pycodegen.py	2001/08/27 21:51:52	1.40
***************
*** 41,45 ****
  class Module:
      def __init__(self, source, filename):
!         self.filename = filename
          self.source = source
          self.code = None
--- 41,45 ----
  class Module:
      def __init__(self, source, filename):
!         self.filename = os.path.abspath(filename)
          self.source = source
          self.code = None
***************
*** 47,56 ****
      def compile(self, display=0):
          tree = parse(self.source)
!         root, filename = os.path.split(self.filename)
!         if "nested_scopes" in future.find_futures(tree):
!             gen = NestedScopeModuleCodeGenerator(filename)
!         else:
!             gen = ModuleCodeGenerator(filename)
!         walk(tree, gen, 1)
          if display:
              import pprint
--- 47,52 ----
      def compile(self, display=0):
          tree = parse(self.source)
!         gen = NestedScopeModuleCodeGenerator(self.filename)
!         walk(tree, gen, verbose=1)
          if display:
              import pprint
***************
*** 116,119 ****
--- 112,121 ----
          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
***************
*** 235,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)
--- 237,245 ----
      def visitModule(self, 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)
***************
*** 265,269 ****
          gen = self.ClassGen(node, self.filename, self.scopes)
          if node.doc:
!             self.fixDocstring(node.code)
          walk(node.code, gen)
          gen.finish()
--- 268,273 ----
          gen = self.ClassGen(node, self.filename, self.scopes)
          if node.doc:
!             self.emit('LOAD_CONST', node.doc)
!             self.storeName('__doc__')
          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
  
--- 283,286 ----
***************
*** 301,304 ****
--- 292,298 ----
          for i in range(numtests):
              test, suite = node.tests[i]
+             if is_constant_false(test):
+                 # XXX will need to check generator stuff here
+                 continue
              self.set_lineno(test)
              self.visit(test)
***************
*** 794,798 ****
          self.emit(opcode, kw << 8 | pos)
  
!     def visitPrint(self, node):
          self.set_lineno(node)
          if node.dest:
--- 788,792 ----
          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')
--- 801,809 ----
              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')
***************
*** 1022,1026 ****
          gen = self.ClassGen(node, self.filename, self.scopes)
          if node.doc:
!             self.fixDocstring(node.code)
          walk(node.code, gen)
          gen.finish()
--- 1018,1023 ----
          gen = self.ClassGen(node, self.filename, self.scopes)
          if node.doc:
!             self.emit('LOAD_CONST', node.doc)
!             self.storeName('__doc__')
          walk(node.code, gen)
          gen.finish()
***************
*** 1073,1077 ****
          self.graph = pyassem.PyFlowGraph("<module>", filename)
          self.__super_init(filename)
!         self.graph.setFlag(CO_NESTED)
  
  class AbstractFunctionCode:
--- 1070,1074 ----
          self.graph = pyassem.PyFlowGraph("<module>", filename)
          self.__super_init(filename)
! ##        self.graph.setFlag(CO_NESTED)
  
  class AbstractFunctionCode:
***************
*** 1095,1099 ****
              self.setDocstring(func.doc)
  
!         lnf = walk(func.code, self.NameFinder(args), 0)
          self.locals.push(lnf.getLocals())
          if func.varargs:
--- 1092,1096 ----
              self.setDocstring(func.doc)
  
!         lnf = walk(func.code, self.NameFinder(args), verbose=0)
          self.locals.push(lnf.getLocals())
          if func.varargs:
***************
*** 1148,1152 ****
          self.graph.setFreeVars(self.scope.get_free_vars())
          self.graph.setCellVars(self.scope.get_cell_vars())
!         self.graph.setFlag(CO_NESTED)
  
  class AbstractClassCode:
--- 1145,1149 ----
          self.graph.setFreeVars(self.scope.get_free_vars())
          self.graph.setCellVars(self.scope.get_cell_vars())
! ##        self.graph.setFlag(CO_NESTED)
  
  class AbstractClassCode:
***************
*** 1156,1160 ****
                                             optimized=0)
          self.super_init(filename)
!         lnf = walk(klass.code, self.NameFinder(), 0)
          self.locals.push(lnf.getLocals())
          self.graph.setFlag(CO_NEWLOCALS)
--- 1153,1157 ----
                                             optimized=0)
          self.super_init(filename)
!         lnf = walk(klass.code, self.NameFinder(), verbose=0)
          self.locals.push(lnf.getLocals())
          self.graph.setFlag(CO_NEWLOCALS)
***************
*** 1187,1191 ****
          self.graph.setFreeVars(self.scope.get_free_vars())
          self.graph.setCellVars(self.scope.get_cell_vars())
!         self.graph.setFlag(CO_NESTED)
  
  def generateArgList(arglist):
--- 1184,1188 ----
          self.graph.setFreeVars(self.scope.get_free_vars())
          self.graph.setCellVars(self.scope.get_cell_vars())
! ##        self.graph.setFlag(CO_NESTED)
  
  def generateArgList(arglist):
***************
*** 1209,1213 ****
      """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
      v = OpFinder()
!     walk(node, v, 0)
      return v.op
  
--- 1206,1210 ----
      """Find the op (DELETE, LOAD, STORE) in an AssTuple tree"""
      v = OpFinder()
!     walk(node, v, verbose=0)
      return v.op