[Python-checkins] CVS: python/dist/src/Tools/compiler/compiler symbols.py,1.1,1.2

Jeremy Hylton jhylton@users.sourceforge.net
Mon, 09 Apr 2001 06:57:35 -0700


Update of /cvsroot/python/python/dist/src/Tools/compiler/compiler
In directory usw-pr-cvs1:/tmp/cvs-serv628/compiler

Modified Files:
	symbols.py 
Log Message:
Add two arguments to Scope constructor, module scope and class name
Add mangling support
Add get_children() and add_child() methods to Scope
Skip nodes when If test is a false constant
Add test code that checks results against symtable module


Index: symbols.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/compiler/compiler/symbols.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** symbols.py	2001/04/09 04:35:35	1.1
--- symbols.py	2001/04/09 13:57:32	1.2
***************
*** 2,27 ****
  
  from compiler import ast
  
! module_scope = None
  
  class Scope:
      # XXX how much information do I need about each name?
!     def __init__(self, name):
          self.name = name
          self.defs = {}
          self.uses = {}
          self.globals = {}
          self.params = {}
  
      def __repr__(self):
          return "<%s: %s>" % (self.__class__.__name__, self.name)
  
      def add_def(self, name):
!         self.defs[name] = 1
  
      def add_use(self, name):
!         self.uses[name] = 1
  
      def add_global(self, name):
          if self.uses.has_key(name) or self.defs.has_key(name):
              pass # XXX warn about global following def/use
--- 2,48 ----
  
  from compiler import ast
+ import types
  
! MANGLE_LEN = 256
  
  class Scope:
      # XXX how much information do I need about each name?
!     def __init__(self, name, module, klass=None):
          self.name = name
+         self.module = module
          self.defs = {}
          self.uses = {}
          self.globals = {}
          self.params = {}
+         self.children = []
+         self.klass = None
+         if klass is not None:
+             for i in range(len(klass)):
+                 if klass[i] != '_':
+                     self.klass = klass[i:]
+                     break
  
      def __repr__(self):
          return "<%s: %s>" % (self.__class__.__name__, self.name)
  
+     def mangle(self, name):
+         if self.klass is None:
+             return name
+         if not name.startswith('__'):
+             return name
+         if len(name) + 2 >= MANGLE_LEN:
+             return name
+         if name.endswith('__'):
+             return name
+         return "_%s%s" % (self.klass, name)
+ 
      def add_def(self, name):
!         self.defs[self.mangle(name)] = 1
  
      def add_use(self, name):
!         self.uses[self.mangle(name)] = 1
  
      def add_global(self, name):
+         name = self.mangle(name)
          if self.uses.has_key(name) or self.defs.has_key(name):
              pass # XXX warn about global following def/use
***************
*** 30,36 ****
                    (name, self.name)
          self.globals[name] = 1
!         module_scope.add_def(name)
  
      def add_param(self, name):
          self.defs[name] = 1
          self.params[name] = 1
--- 51,58 ----
                    (name, self.name)
          self.globals[name] = 1
!         self.module.add_def(name)
  
      def add_param(self, name):
+         name = self.mangle(name)
          self.defs[name] = 1
          self.params[name] = 1
***************
*** 42,53 ****
          return d.keys()
  
  class ModuleScope(Scope):
      __super_init = Scope.__init__
      
      def __init__(self):
!         self.__super_init("global")
!         global module_scope
!         assert module_scope is None 
!         module_scope = self
  
  class LambdaScope(Scope):
--- 64,78 ----
          return d.keys()
  
+     def add_child(self, child):
+         self.children.append(child)
+ 
+     def get_children(self):
+         return self.children
+ 
  class ModuleScope(Scope):
      __super_init = Scope.__init__
      
      def __init__(self):
!         self.__super_init("global", self)
  
  class LambdaScope(Scope):
***************
*** 56,63 ****
      __counter = 1
      
!     def __init__(self):
          i = self.__counter
          self.__counter += 1
!         self.__super_init("lambda.%d" % i)
  
  class FunctionScope(Scope):
--- 81,88 ----
      __counter = 1
      
!     def __init__(self, module, klass=None):
          i = self.__counter
          self.__counter += 1
!         self.__super_init("lambda.%d" % i, module, klass)
  
  class FunctionScope(Scope):
***************
*** 65,78 ****
  
  class ClassScope(Scope):
!     pass
  
  class SymbolVisitor:
      def __init__(self):
          self.scopes = {}
! 
      # node that define new scopes
  
      def visitModule(self, node):
!         scope = self.scopes[node] = ModuleScope()
          self.visit(node.node, scope)
  
--- 90,107 ----
  
  class ClassScope(Scope):
!     __super_init = Scope.__init__
  
+     def __init__(self, name, module):
+         self.__super_init(name, module, name)
+ 
  class SymbolVisitor:
      def __init__(self):
          self.scopes = {}
!         self.klass = None
!         
      # node that define new scopes
  
      def visitModule(self, node):
!         scope = self.module = self.scopes[node] = ModuleScope()
          self.visit(node.node, scope)
  
***************
*** 81,85 ****
          for n in node.defaults:
              self.visit(n, parent)
!         scope = FunctionScope(node.name)
          self.scopes[node] = scope
          for name in node.argnames:
--- 110,114 ----
          for n in node.defaults:
              self.visit(n, parent)
!         scope = FunctionScope(node.name, self.module, self.klass)
          self.scopes[node] = scope
          for name in node.argnames:
***************
*** 90,94 ****
          for n in node.defaults:
              self.visit(n, parent)
!         scope = LambdaScope()
          self.scopes[node] = scope
          for name in node.argnames:
--- 119,123 ----
          for n in node.defaults:
              self.visit(n, parent)
!         scope = LambdaScope(self.module, self.klass)
          self.scopes[node] = scope
          for name in node.argnames:
***************
*** 100,106 ****
          for n in node.bases:
              self.visit(n, parent)
!         scope = ClassScope(node.name)
          self.scopes[node] = scope
          self.visit(node.code, scope)
  
      # name can be a def or a use
--- 129,138 ----
          for n in node.bases:
              self.visit(n, parent)
!         scope = ClassScope(node.name, self.module)
          self.scopes[node] = scope
+         prev = self.klass
+         self.klass = node.name
          self.visit(node.code, scope)
+         self.klass = prev
  
      # name can be a def or a use
***************
*** 156,159 ****
--- 188,206 ----
              scope.add_global(name)
  
+     # prune if statements if tests are false
+ 
+     _const_types = types.StringType, types.IntType, types.FloatType
+ 
+     def visitIf(self, node, scope):
+         for test, body in node.tests:
+             if isinstance(test, ast.Const):
+                 if type(test.value) in self._const_types:
+                     if not test.value:
+                         continue
+             self.visit(test, scope)
+             self.visit(body, scope)
+         if node.else_:
+             self.visit(node.else_, scope)
+ 
  def sort(l):
      l = l[:]
***************
*** 169,172 ****
--- 216,223 ----
      import symtable
  
+     def get_names(syms):
+         return [s for s in [s.get_name() for s in syms.get_symbols()]
+                 if not s.startswith('_[')]        
+     
      for file in sys.argv[1:]:
          print file
***************
*** 175,193 ****
          f.close()
          syms = symtable.symtable(buf, file, "exec")
!         mod_names = [s for s in [s.get_name()
!                                  for s in syms.get_symbols()]
!                      if not s.startswith('_[')]
          tree = parseFile(file)
          s = SymbolVisitor()
          walk(tree, s)
-         for node, scope in s.scopes.items():
-             print node.__class__.__name__, id(node)
-             print scope
-             print scope.get_names()
  
          names2 = s.scopes[tree].get_names()
          if not list_eq(mod_names, names2):
              print "oops", file
              print sort(mod_names)
              print sort(names2)
              sys.exit(-1)
--- 226,261 ----
          f.close()
          syms = symtable.symtable(buf, file, "exec")
!         mod_names = get_names(syms)
          tree = parseFile(file)
          s = SymbolVisitor()
          walk(tree, s)
  
+         # compare module-level symbols
          names2 = s.scopes[tree].get_names()
+ 
          if not list_eq(mod_names, names2):
+             print
              print "oops", file
              print sort(mod_names)
              print sort(names2)
              sys.exit(-1)
+ 
+         d = {}
+         d.update(s.scopes)
+         del d[tree]
+         scopes = d.values()
+         del d
+ 
+         for s in syms.get_symbols():
+             if s.is_namespace():
+                 l = [sc for sc in scopes
+                      if sc.name == s.get_name()]
+                 if len(l) > 1:
+                     print "skipping", s.get_name()
+                 else:
+                     if not list_eq(get_names(s.get_namespace()),
+                                    l[0].get_names()):
+                         print s.get_name()
+                         print get_names(s.get_namespace())
+                         print l[0].get_names()
+                         sys.exit(-1)