[Python-checkins] CVS: /python/nondist/src/Compiler compile.py,1.16,1.17 pyassem.py,1.3,1.4

Jeremy Hylton jhylton@cnri.reston.va.us
Thu, 17 Feb 2000 17:09:38 -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 pyassem.py 
Log Message:
the previous quick hack to fix def foo((x,y)) failed on some cases
(big surprise).  new solution is a little less hackish.

Code gen adds a TupleArg instance in the argument slot. The tuple arg
includes a copy of the names that it is responsble for binding.  The
PyAssembler uses this information to calculate the correct argcount.

all fix this wacky case: del (a, ((b,), c)), d
which is the same as: del a, b, c, d
(Can't wait for Guido to tell me why.)

solution uses findOp which walks a tree to find out whether it
contains OP_ASSIGN or OP_DELETE or ...



Index: compile.py
===================================================================
RCS file: /projects/cvsroot//python/nondist/src/Compiler/compile.py,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -r1.16 -r1.17
*** compile.py	2000/02/17 17:56:29	1.16
--- compile.py	2000/02/17 22:09:35	1.17
***************
*** 7,11 ****
  
  from p2c import transformer, ast
! from pyassem import StackRef, PyAssembler
  import dis
  import misc
--- 7,11 ----
  
  from p2c import transformer, ast
! from pyassem import StackRef, PyAssembler, TupleArg
  import dis
  import misc
***************
*** 204,208 ****
                  args.append(elt)
              elif type(elt) == types.TupleType:
!                 args.append(".nested%d" % count)
                  count = count + 1
                  extra.extend(misc.flatten(elt))
--- 204,208 ----
                  args.append(elt)
              elif type(elt) == types.TupleType:
!                 args.append(TupleArg(count, elt))
                  count = count + 1
                  extra.extend(misc.flatten(elt))
***************
*** 344,348 ****
      def visitLambda(self, node):
          node.name = '<lambda>'
-         node.varargs = node.kwargs = None
          self._visitFuncOrLambda(node, 'Lambda')
          return 1
--- 344,347 ----
***************
*** 634,641 ****
  
      def visitAssName(self, node):
!         # XXX handle OP_DELETE
!         if node.flags != 'OP_ASSIGN':
              print "oops", node.flags
!         self.storeName(node.name)
  
      def visitAssAttr(self, node):
--- 633,643 ----
  
      def visitAssName(self, node):
!         if node.flags == 'OP_ASSIGN':
!             self.storeName(node.name)
!         elif node.flags == 'OP_DELETE':
!             self.delName(node.name)
!         else:
              print "oops", node.flags
!         return 1
  
      def visitAssAttr(self, node):
***************
*** 651,655 ****
  
      def visitAssTuple(self, node):
!         self.emit('UNPACK_TUPLE', len(node.nodes))
          for child in node.nodes:
              self.visit(child)
--- 653,658 ----
  
      def visitAssTuple(self, node):
!         if findOp(node) != 'OP_DELETE':
!             self.emit('UNPACK_TUPLE', len(node.nodes))
          for child in node.nodes:
              self.visit(child)
***************
*** 839,842 ****
--- 842,846 ----
              self.visit(node.globals)
          self.emit('EXEC_STMT')
+         return 1
  
  class LocalNameFinder:
***************
*** 882,885 ****
--- 886,903 ----
      def visitAssName(self, node):
          self.names.add(node.name)
+ 
+ class OpFinder:
+     def __init__(self):
+         self.op = None
+     def visitAssName(self, node):
+         if self.op is None:
+             self.op = node.flags
+         elif self.op != node.flags:
+             raise ValueError, "mixed ops in stmt"
+ 
+ def findOp(node):
+     v = OpFinder()
+     walk(node, v)
+     return v.op
  
  class Loop:

Index: pyassem.py
===================================================================
RCS file: /projects/cvsroot//python/nondist/src/Compiler/pyassem.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** pyassem.py	2000/02/16 00:50:29	1.3
--- pyassem.py	2000/02/17 22:09:35	1.4
***************
*** 43,46 ****
--- 43,55 ----
  CO_VARKEYWORDS = 0x0008
  
+ class TupleArg:
+     def __init__(self, count, names):
+         self.count = count
+         self.names = names
+     def __repr__(self):
+         return "TupleArg(%s, %s)" % (self.count, self.names)
+     def getName(self):
+         return ".nested%d" % self.count
+ 
  class PyAssembler:
      """Creates Python code objects
***************
*** 55,58 ****
--- 64,68 ----
          # used by makeCodeObject
          self._getArgCount(args)
+         print name, args, self.argcount
          self.code = ''
          self.consts = [docstring]
***************
*** 62,65 ****
--- 72,79 ----
          self.names = []
          self.varnames = list(args) or []
+         for i in range(len(self.varnames)):
+             var = self.varnames[i]
+             if isinstance(var, TupleArg):
+                 self.varnames[i] = var.getName()
          # lnotab support
          self.firstlineno = 0
***************
*** 69,80 ****
  
      def _getArgCount(self, args):
!         if args and args[0][0] == '.':
!             for i in range(len(args)):
!                 if args[i][0] == '.':
!                     num = i
!             self.argcount = num + 1
!         else:
!             self.argcount = len(args)
!                 
  
      def __repr__(self):
--- 83,92 ----
  
      def _getArgCount(self, args):
!         self.argcount = len(args)
!         if args:
!             for arg in args:
!                 if isinstance(arg, TupleArg):
!                     numNames = len(misc.flatten(arg.names))
!                     self.argcount = self.argcount - numNames 
  
      def __repr__(self):
***************
*** 89,93 ****
  
      def setVarArgs(self):
!         self.flags = self.flags | CO_VARARGS
  
      def setKWArgs(self):
--- 101,107 ----
  
      def setVarArgs(self):
!         if not self.flags & CO_VARARGS:
!             self.flags = self.flags | CO_VARARGS
!             self.argcount = self.argcount - 1
  
      def setKWArgs(self):