summaryrefslogtreecommitdiffstats
path: root/Lib/compiler/pyassem.py
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2001-04-12 06:40:42 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2001-04-12 06:40:42 (GMT)
commit364f9b9e2f798e4d28ed21122faffb030a6ccac5 (patch)
treebc709b0d46eeba0c737bdd7bb58371ad06d70739 /Lib/compiler/pyassem.py
parent53ee2a94c70875b7b334ddca59900933409eaa63 (diff)
downloadcpython-364f9b9e2f798e4d28ed21122faffb030a6ccac5.zip
cpython-364f9b9e2f798e4d28ed21122faffb030a6ccac5.tar.gz
cpython-364f9b9e2f798e4d28ed21122faffb030a6ccac5.tar.bz2
Preliminary support for nested scopes
XXX Still doesn't work right for classes XXX Still doesn't do sufficient error checking
Diffstat (limited to 'Lib/compiler/pyassem.py')
-rw-r--r--Lib/compiler/pyassem.py50
1 files changed, 43 insertions, 7 deletions
diff --git a/Lib/compiler/pyassem.py b/Lib/compiler/pyassem.py
index 43bf6f4..447a8e7 100644
--- a/Lib/compiler/pyassem.py
+++ b/Lib/compiler/pyassem.py
@@ -99,12 +99,6 @@ class FlowGraph:
if not self.exit in order:
order.append(self.exit)
-## for b in order:
-## print repr(b)
-## print "\t", b.get_children()
-## print b
-## print
-
return order
def getBlocks(self):
@@ -222,6 +216,7 @@ CO_OPTIMIZED = 0x0001
CO_NEWLOCALS = 0x0002
CO_VARARGS = 0x0004
CO_VARKEYWORDS = 0x0008
+CO_NESTED = 0x0010
# the FlowGraph is transformed in place; it exists in one of these states
RAW = "RAW"
@@ -245,6 +240,15 @@ class PyFlowGraph(FlowGraph):
self.flags = 0
self.consts = []
self.names = []
+ # Free variables found by the symbol table scan, including
+ # variables used only in nested scopes, are included here.
+ self.freevars = []
+ self.cellvars = []
+ # The closure list is used to track the order of cell
+ # variables and free variables in the resulting code object.
+ # The offsets used by LOAD_CLOSURE/LOAD_DEREF refer to both
+ # kinds of variables.
+ self.closure = []
self.varnames = list(args) or []
for i in range(len(self.varnames)):
var = self.varnames[i]
@@ -260,6 +264,12 @@ class PyFlowGraph(FlowGraph):
if flag == CO_VARARGS:
self.argcount = self.argcount - 1
+ def setFreeVars(self, names):
+ self.freevars = list(names)
+
+ def setCellVars(self, names):
+ self.cellvars = names
+
def getCode(self):
"""Get a Python code object"""
if self.stage == RAW:
@@ -335,6 +345,7 @@ class PyFlowGraph(FlowGraph):
"""Convert arguments from symbolic to concrete form"""
assert self.stage == FLAT
self.consts.insert(0, self.docstring)
+ self.sort_cellvars()
for i in range(len(self.insts)):
t = self.insts[i]
if len(t) == 2:
@@ -345,6 +356,19 @@ class PyFlowGraph(FlowGraph):
self.insts[i] = opname, conv(self, oparg)
self.stage = CONV
+ def sort_cellvars(self):
+ """Sort cellvars in the order of varnames and prune from freevars.
+ """
+ cells = {}
+ for name in self.cellvars:
+ cells[name] = 1
+ self.cellvars = [name for name in self.varnames
+ if cells.has_key(name)]
+ for name in self.cellvars:
+ del cells[name]
+ self.cellvars = self.cellvars + cells.keys()
+ self.closure = self.cellvars + self.freevars
+
def _lookupName(self, name, list):
"""Return index of name in list, appending if necessary"""
t = type(name)
@@ -382,6 +406,17 @@ class PyFlowGraph(FlowGraph):
_convert_STORE_GLOBAL = _convert_NAME
_convert_DELETE_GLOBAL = _convert_NAME
+ def _convert_DEREF(self, arg):
+ self._lookupName(arg, self.names)
+ self._lookupName(arg, self.varnames)
+ return self._lookupName(arg, self.closure)
+ _convert_LOAD_DEREF = _convert_DEREF
+ _convert_STORE_DEREF = _convert_DEREF
+
+ def _convert_LOAD_CLOSURE(self, arg):
+ self._lookupName(arg, self.varnames)
+ return self._lookupName(arg, self.closure)
+
_cmp = list(dis.cmp_op)
def _convert_COMPARE_OP(self, arg):
return self._cmp.index(arg)
@@ -432,7 +467,8 @@ class PyFlowGraph(FlowGraph):
self.lnotab.getCode(), self.getConsts(),
tuple(self.names), tuple(self.varnames),
self.filename, self.name, self.lnotab.firstline,
- self.lnotab.getTable())
+ self.lnotab.getTable(), tuple(self.freevars),
+ tuple(self.cellvars))
def getConsts(self):
"""Return a tuple for the const slot of the code object