summaryrefslogtreecommitdiffstats
path: root/Lib/compiler/pyassem.py
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2000-02-17 22:09:35 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2000-02-17 22:09:35 (GMT)
commit3ec7e2c4be9b3127ed1b10de6e3c48e1786c1a10 (patch)
treeab6383ea0770c6358db907c0cf02cbd99588f9b6 /Lib/compiler/pyassem.py
parent7708d697ee38f5d8c61b88737e941a4d1eb49691 (diff)
downloadcpython-3ec7e2c4be9b3127ed1b10de6e3c48e1786c1a10.zip
cpython-3ec7e2c4be9b3127ed1b10de6e3c48e1786c1a10.tar.gz
cpython-3ec7e2c4be9b3127ed1b10de6e3c48e1786c1a10.tar.bz2
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 ...
Diffstat (limited to 'Lib/compiler/pyassem.py')
-rw-r--r--Lib/compiler/pyassem.py32
1 files changed, 23 insertions, 9 deletions
diff --git a/Lib/compiler/pyassem.py b/Lib/compiler/pyassem.py
index 5ae7294..7efc4ab 100644
--- a/Lib/compiler/pyassem.py
+++ b/Lib/compiler/pyassem.py
@@ -42,6 +42,15 @@ CO_NEWLOCALS = 0x0002
CO_VARARGS = 0x0004
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
"""
@@ -54,6 +63,7 @@ class PyAssembler:
self.insts = []
# used by makeCodeObject
self._getArgCount(args)
+ print name, args, self.argcount
self.code = ''
self.consts = [docstring]
self.filename = filename
@@ -61,6 +71,10 @@ class PyAssembler:
self.name = name
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
self.lastlineno = 0
@@ -68,14 +82,12 @@ class PyAssembler:
self.lnotab = ''
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)
-
+ 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):
return "<bytecode: %d instrs>" % len(self.insts)
@@ -88,7 +100,9 @@ class PyAssembler:
self.flags = self.flags | CO_OPTIMIZED
def setVarArgs(self):
- self.flags = self.flags | CO_VARARGS
+ if not self.flags & CO_VARARGS:
+ self.flags = self.flags | CO_VARARGS
+ self.argcount = self.argcount - 1
def setKWArgs(self):
self.flags = self.flags | CO_VARKEYWORDS