diff options
author | Jeremy Hylton <jeremy@alum.mit.edu> | 2000-02-17 22:09:35 (GMT) |
---|---|---|
committer | Jeremy Hylton <jeremy@alum.mit.edu> | 2000-02-17 22:09:35 (GMT) |
commit | 3ec7e2c4be9b3127ed1b10de6e3c48e1786c1a10 (patch) | |
tree | ab6383ea0770c6358db907c0cf02cbd99588f9b6 /Lib/compiler/pyassem.py | |
parent | 7708d697ee38f5d8c61b88737e941a4d1eb49691 (diff) | |
download | cpython-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.py | 32 |
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 |