summaryrefslogtreecommitdiff
path: root/Tools/compiler
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2001-08-29 18:10:51 +0000
committerJeremy Hylton <jeremy@alum.mit.edu>2001-08-29 18:10:51 +0000
commitdc53e49dfbf074c7e937672f65f20cb842ecc4e4 (patch)
treea75b271f7a8c2ebf042d1ec24b51a02b340f430a /Tools/compiler
parentbca29fafaeb38f74750df30da802198cf4183f9d (diff)
downloadcpython-dc53e49dfbf074c7e937672f65f20cb842ecc4e4.tar.gz
Add generator detection to symbol table.
Fix bug in handling of statements like "l[x:y] = 2". The visitor was treating this as assignments to l, x, and y!
Diffstat (limited to 'Tools/compiler')
-rw-r--r--Tools/compiler/compiler/symbols.py44
1 files changed, 35 insertions, 9 deletions
diff --git a/Tools/compiler/compiler/symbols.py b/Tools/compiler/compiler/symbols.py
index 40fd127bfd..946a8b1a3a 100644
--- a/Tools/compiler/compiler/symbols.py
+++ b/Tools/compiler/compiler/symbols.py
@@ -25,6 +25,7 @@ class Scope:
# nested is true if the class could contain free variables,
# i.e. if it is nested within another function.
self.nested = None
+ self.generator = None
self.klass = None
if klass is not None:
for i in range(len(klass)):
@@ -287,6 +288,27 @@ class SymbolVisitor:
name = name[:i]
scope.add_def(asname or name)
+ def visitGlobal(self, node, scope):
+ for name in node.names:
+ scope.add_global(name)
+
+ def visitAssign(self, node, scope):
+ """Propagate assignment flag down to child nodes.
+
+ The Assign node doesn't itself contains the variables being
+ assigned to. Instead, the children in node.nodes are visited
+ with the assign flag set to true. When the names occur in
+ those nodes, they are marked as defs.
+
+ Some names that occur in an assignment target are not bound by
+ the assignment, e.g. a name occurring inside a slice. The
+ visitor handles these nodes specially; they do not propagate
+ the assign flag to their children.
+ """
+ for n in node.nodes:
+ self.visit(n, scope, 1)
+ self.visit(node.expr, scope)
+
def visitAssName(self, node, scope, assign=1):
scope.add_def(node.name)
@@ -297,6 +319,13 @@ class SymbolVisitor:
self.visit(node.expr, scope, 0)
for n in node.subs:
self.visit(n, scope, 0)
+
+ def visitSlice(self, node, scope, assign=0):
+ self.visit(node.expr, scope, assign)
+ if node.lower:
+ self.visit(node.lower, scope, 0)
+ if node.upper:
+ self.visit(node.upper, scope, 0)
def visitAugAssign(self, node, scope):
# If the LHS is a name, then this counts as assignment.
@@ -306,15 +335,6 @@ class SymbolVisitor:
self.visit(node.node, scope, 1) # XXX worry about this
self.visit(node.expr, scope)
- def visitAssign(self, node, scope):
- for n in node.nodes:
- self.visit(n, scope, 1)
- self.visit(node.expr, scope)
-
- def visitGlobal(self, node, scope):
- for name in node.names:
- scope.add_global(name)
-
# prune if statements if tests are false
_const_types = types.StringType, types.IntType, types.FloatType
@@ -330,6 +350,12 @@ class SymbolVisitor:
if node.else_:
self.visit(node.else_, scope)
+ # a yield statement signals a generator
+
+ def visitYield(self, node, scope):
+ self.generator = 1
+ self.visit(node.value, scope)
+
def sort(l):
l = l[:]
l.sort()