[Python-checkins] CVS: python/dist/src/Tools/compiler/compiler future.py,NONE,1.1 pycodegen.py,1.27,1.28

Jeremy Hylton jhylton@users.sourceforge.net
Sun, 08 Apr 2001 21:28:50 -0700


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

Modified Files:
	pycodegen.py 
Added Files:
	future.py 
Log Message:
Add support for future statements


--- NEW FILE: future.py ---
"""Parser for future statements

"""

from compiler import ast, walk

def is_future(stmt):
    """Return true if statement is a well-formed future statement"""
    if not isinstance(stmt, ast.From):
        return 0
    if stmt.modname == "__future__":
        return 1
    else:
        return 0

class FutureParser:

    features = ("nested_scopes",)
    
    def __init__(self):
        self.found = {} # set

    def visitModule(self, node):
        if node.doc is None:
            off = 0
        else:
            off = 1

        stmt = node.node
        for s in stmt.nodes[off:]:
            if not self.check_stmt(s):
                break

    def check_stmt(self, stmt):
        if is_future(stmt):
            for name, asname in stmt.names:
                if name in self.features:
                    self.found[name] = 1
                else:
                    raise SyntaxError, \
                          "future feature %s is not defined" % name
            stmt.valid_future = 1
            return 1
        return 0

    def get_features(self):
        """Return list of features enabled by future statements"""
        return self.found.keys()

class BadFutureParser:
    """Check for invalid future statements"""

    def visitFrom(self, node):
        if hasattr(node, 'valid_future'):
            return
        if node.modname != "__future__":
            return
        raise SyntaxError, "invalid future statement"

def find_futures(node):
    p1 = FutureParser()
    p2 = BadFutureParser()
    walk(node, p1)
    walk(node, p2)
    return p1.get_features()

if __name__ == "__main__":
    import sys
    from compiler import parseFile, walk

    for file in sys.argv[1:]:
        print file
        tree = parseFile(file)
        v = FutureParser()
        walk(tree, v)
        print v.found
        print


Index: pycodegen.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/compiler/compiler/pycodegen.py,v
retrieving revision 1.27
retrieving revision 1.28
diff -C2 -r1.27 -r1.28
*** pycodegen.py	2000/11/06 03:43:11	1.27
--- pycodegen.py	2001/04/09 04:28:48	1.28
***************
*** 10,14 ****
  
  from compiler import ast, parse, walk
! from compiler import pyassem, misc
  from compiler.pyassem import CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS, TupleArg
  
--- 10,14 ----
  
  from compiler import ast, parse, walk
! from compiler import pyassem, misc, future
  from compiler.pyassem import CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS, TupleArg
  
***************
*** 44,54 ****
  
      def compile(self, display=0):
!         ast = parse(self.source)
          root, filename = os.path.split(self.filename)
          gen = ModuleCodeGenerator(filename)
!         walk(ast, gen, 1)
          if display:
              import pprint
!             print pprint.pprint(ast)
          self.code = gen.getCode()
  
--- 44,54 ----
  
      def compile(self, display=0):
!         tree = parse(self.source)
          root, filename = os.path.split(self.filename)
          gen = ModuleCodeGenerator(filename)
!         walk(tree, gen, 1)
          if display:
              import pprint
!             print pprint.pprint(tree)
          self.code = gen.getCode()
  
***************
*** 863,873 ****
  
  class ModuleCodeGenerator(CodeGenerator):
!     super_init = CodeGenerator.__init__
      
      def __init__(self, filename):
          # XXX <module> is ? in compile.c
          self.graph = pyassem.PyFlowGraph("<module>", filename)
!         self.super_init(filename)
  
  class FunctionCodeGenerator(CodeGenerator):
      super_init = CodeGenerator.__init__
--- 863,885 ----
  
  class ModuleCodeGenerator(CodeGenerator):
!     __super_init = CodeGenerator.__init__
!     __super_visitModule = CodeGenerator.visitModule
      
      def __init__(self, filename):
          # XXX <module> is ? in compile.c
          self.graph = pyassem.PyFlowGraph("<module>", filename)
!         self.__super_init(filename)
!         self.symbols = None
!         self.future = None
  
+     def visitModule(self, node):
+         self.future = future.find_futures(node)
+         self.symbols = self.parseSymbols(node)
+         self.__super_visitModule(node)
+ 
+     def parseSymbols(self, node):
+         # XXX not implemented
+         return None
+ 
  class FunctionCodeGenerator(CodeGenerator):
      super_init = CodeGenerator.__init__
***************
*** 965,968 ****
--- 977,982 ----
          for name in names:
              self.names.add(name)
+ 
+     # XXX list comprehensions and for loops
  
      def getLocals(self):