[Python-checkins] CVS: /python/nondist/src/Compiler compile.py,1.14,1.15

Jeremy Hylton jhylton@cnri.reston.va.us
Tue, 15 Feb 2000 19:55:46 -0500


Update of /projects/cvsroot//python/nondist/src/Compiler
In directory goon.cnri.reston.va.us:/home/jhylton/python/nondist/src/Compiler

Modified Files:
	compile.py 
Log Message:
support for arglists with implicit tuple unpacks
- added a number of support methods to generate code just before the
  body 
- hack protocol for communicating number of args to PyAssembler

fix TryExcept generation for case where exception handler has no body
fix visitAssAttr
add comment about incomplete visitAssName

stop using the ExampleASTVisitor

change script invocation to accept a list of .py files (e.g. Lib/*.py)






Index: compile.py
===================================================================
RCS file: /projects/cvsroot//python/nondist/src/Compiler/compile.py,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -r1.14 -r1.15
*** compile.py	2000/02/15 23:45:26	1.14
--- compile.py	2000/02/16 00:55:44	1.15
***************
*** 17,20 ****
--- 17,21 ----
  import stat
  import struct
+ import types
  
  def parse(path):
***************
*** 178,182 ****
          self.name = func.name
          self.filename = filename
!         args = func.argnames
  	self.code = PyAssembler(args=args, name=func.name,
                                   filename=filename)
--- 179,186 ----
          self.name = func.name
          self.filename = filename
! 
!         # keep a lookout for 'def foo((x,y)):'
!         args, hasTupleArg = self.generateArglist(func.argnames)
!         
  	self.code = PyAssembler(args=args, name=func.name,
                                   filename=filename)
***************
*** 189,194 ****
--- 193,231 ----
          self.locals.push(lnf.getLocals())
  	self.emit('SET_LINENO', func.lineno)
+ 	if hasTupleArg:
+             self.generateArgUnpack(func.argnames)
          walk(func.code, self)
  
+     def generateArglist(self, arglist):
+         args = []
+         extra = []
+         count = 0
+         for elt in arglist:
+             if type(elt) == types.StringType:
+                 args.append(elt)
+             elif type(elt) == types.TupleType:
+                 args.append(".nested%d" % count)
+                 count = count + 1
+                 extra.extend(misc.flatten(elt))
+             else:
+                 raise ValueError, "unexpect argument type:", elt
+         return args + extra, count
+ 
+     def generateArgUnpack(self, args):
+         count = 0
+         for arg in args:
+             if type(arg) == types.TupleType:
+                 self.emit('LOAD_FAST', '.nested%d' % count)
+                 count = count + 1
+                 self.unpackTuple(arg)
+                         
+     def unpackTuple(self, tup):
+         self.emit('UNPACK_TUPLE', len(tup))
+         for elt in tup:
+             if type(elt) == types.TupleType:
+                 self.unpackTuple(elt)
+             else:
+                 self.emit('STORE_FAST', elt)
+ 
      def generateFunctionCode(self, func):
          """Generate code for a function body"""
***************
*** 392,396 ****
              lElse = l.breakAnchor
          l.startAnchor.bind(self.code.getCurInst())
!         self.emit('SET_LINENO', node.test.lineno)
          self.visit(node.test)
          self.emit('JUMP_IF_FALSE', lElse)
--- 429,434 ----
              lElse = l.breakAnchor
          l.startAnchor.bind(self.code.getCurInst())
!         if hasattr(node.test, 'lineno'):
!             self.emit('SET_LINENO', node.test.lineno)
          self.visit(node.test)
          self.emit('JUMP_IF_FALSE', lElse)
***************
*** 456,460 ****
              self.visit(body)
              self.emit('JUMP_FORWARD', end)
!             next.bind(self.code.getCurInst())
              self.emit('POP_TOP')
          self.emit('END_FINALLY')
--- 494,499 ----
              self.visit(body)
              self.emit('JUMP_FORWARD', end)
!             if expr:
!                 next.bind(self.code.getCurInst())
              self.emit('POP_TOP')
          self.emit('END_FINALLY')
***************
*** 554,558 ****
  	elif node.flags == 'OP_DELETE':
              self.emit('DELETE_SUBSCR')
-         print
          return 1
  
--- 593,596 ----
***************
*** 597,600 ****
--- 635,639 ----
  
      def visitAssName(self, node):
+         # XXX handle OP_DELETE
          if node.flags != 'OP_ASSIGN':
              print "oops", node.flags
***************
*** 602,610 ****
  
      def visitAssAttr(self, node):
!         if node.flags != 'OP_ASSIGN':
              print "warning: unexpected flags:", node.flags
              print node
-         self.visit(node.expr)
-         self.emit('STORE_ATTR', node.attrname)
          return 1
  
--- 641,652 ----
  
      def visitAssAttr(self, node):
!         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
              print node
          return 1
  
***************
*** 866,870 ****
          self.ast = t.parsesuite(self.source)
          cg = CodeGenerator(self.filename)
!         walk(self.ast, cg, walker=ExampleASTVisitor)
          self.code = cg.asConst()
  
--- 908,912 ----
          self.ast = t.parsesuite(self.source)
          cg = CodeGenerator(self.filename)
!         walk(self.ast, cg)
          self.code = cg.asConst()
  
***************
*** 889,905 ****
      import getopt
  
      opts, args = getopt.getopt(sys.argv[1:], 'vq')
      for k, v in opts:
          if k == '-v':
              ASTVisitor.VERBOSE = ASTVisitor.VERBOSE + 1
          if k == '-q':
              f = open('/dev/null', 'wb')
              sys.stdout = f
!     if args:
!         filename = args[0]
      else:
!         filename = 'test.py'
!     buf = open(filename).read()
!     mod = CompiledModule(buf, filename)
!     mod.compile()
!     mod.dump(filename + 'c')
--- 931,951 ----
      import getopt
  
+     VERBOSE = 0
      opts, args = getopt.getopt(sys.argv[1:], 'vq')
      for k, v in opts:
          if k == '-v':
+             VERBOSE = 1
              ASTVisitor.VERBOSE = ASTVisitor.VERBOSE + 1
          if k == '-q':
              f = open('/dev/null', 'wb')
              sys.stdout = f
!     if not args:
!         print "no files to compile"
      else:
!         for filename in args:
!             if VERBOSE:
!                 print filename
!             buf = open(filename).read()
!             mod = CompiledModule(buf, filename)
!             mod.compile()
!             mod.dump(filename + 'c')