[pypy-svn] r17425 - in pypy/dist/pypy/interpreter: astcompiler pyparser

ludal at codespeak.net ludal at codespeak.net
Fri Sep 9 19:17:10 CEST 2005


Author: ludal
Date: Fri Sep  9 19:17:07 2005
New Revision: 17425

Modified:
   pypy/dist/pypy/interpreter/astcompiler/astgen.py
   pypy/dist/pypy/interpreter/astcompiler/pycodegen.py
   pypy/dist/pypy/interpreter/astcompiler/symbols.py
   pypy/dist/pypy/interpreter/pyparser/astbuilder.py
Log:
- make global objects for class attribute counters
- remove scopes dict { Node:Scope } put scope attribute on nodes
- try to make TokenObject.get_value annotated as SomeString(can_be_none=False)
- remove some class attributes



Modified: pypy/dist/pypy/interpreter/astcompiler/astgen.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/astgen.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/astgen.py	Fri Sep  9 19:17:07 2005
@@ -378,6 +378,7 @@
     def __init__(self, lineno = -1):
         self.lineno = lineno
         self.filename = ""
+        self.scope = None
         
     def getChildren(self):
         pass # implemented by subclasses

Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py	Fri Sep  9 19:17:07 2005
@@ -63,13 +63,12 @@
     return gen.code
 
 class AbstractCompileMode:
-
-    mode = None # defined by subclass
-
     def __init__(self, source, filename):
         self.source = source
         self.filename = filename
         self.code = None
+        # XXX: this attribute looks like unused anyway ???
+        self.mode = "" # defined by subclass
 
     def _get_tree(self):
         tree = parse(self.source, self.mode)
@@ -84,17 +83,19 @@
         return self.code
 
 class Expression(AbstractCompileMode):
-
-    mode = "eval"
-
+    def __init__(self, source, filename):
+        AbstractCompileMode.__init__(self, source, filename )
+        self.mode = "eval"
+        
     def compile(self):
         tree = self._get_tree()
         gen = ExpressionCodeGenerator(tree)
         self.code = gen.getCode()
 
 class Interactive(AbstractCompileMode):
-
-    mode = "single"
+    def __init__(self, source, filename):
+        AbstractCompileMode.__init__(self, source, filename )
+        self.mode = "single"
 
     def compile(self):
         tree = self._get_tree()
@@ -102,8 +103,9 @@
         self.code = gen.getCode()
 
 class Module(AbstractCompileMode):
-
-    mode = "exec"
+    def __init__(self, source, filename):
+        AbstractCompileMode.__init__(self, source, filename )
+        self.mode = "exec"
 
     def compile(self, display=0):
         tree = self._get_tree()
@@ -136,25 +138,19 @@
 
 class CodeGenerator(ast.ASTVisitor):
     """Defines basic code generator for Python bytecode
-
-    This class is an abstract base class.  Concrete subclasses must
-    define an __init__() that defines self.graph and then calls the
-    __init__() defined in this class.
     """
 
-    graph = None
 
-    optimized = 0 # is namespace access optimized?
-    __initialized = None
-    class_name = None # provide default for instance variable
 
-    def __init__(self, space):
+    def __init__(self, space, graph):
         self.space = space
-        self.checkClass()
         self.setups = misc.Stack()
         self.last_lineno = -1
         self._div_op = "BINARY_DIVIDE"
         self.genexpr_cont_stack = []
+        self.graph = graph
+        self.optimized = 0 # is namespace access optimized?
+        self.class_name = "" # provide default for instance variable
 
         # XXX set flags based on future features
         futures = self.get_module().futures
@@ -165,10 +161,6 @@
             elif feature == "generators":
                 self.graph.setFlag(CO_GENERATOR_ALLOWED)
 
-    def checkClass(self):
-        """Verify that class is constructed correctly"""
-        assert self.graph is not None, "bad class construction for %r" % self
-
     def emit(self, inst ):
         return self.graph.emit( inst )
 
@@ -209,15 +201,14 @@
         return self.graph.getCode()
 
     def mangle(self, name):
-        if self.class_name is not None:
+        if self.class_name:
             return misc.mangle(name, self.class_name)
         else:
             return name
 
     def parseSymbols(self, tree):
         s = symbols.SymbolVisitor(self.space)
-        walk(tree, s)
-        return s.scopes
+        tree.accept(s)
 
     def get_module(self):
         raise RuntimeError, "should be implemented by subclasses"
@@ -301,8 +292,9 @@
 
 
     def visitModule(self, node):
-        self.scopes = self.parseSymbols(node)
-        self.scope = self.scopes[node]
+        self.parseSymbols(node)
+        assert node.scope is not None
+        self.scope = node.scope
         self.emitop_int('SET_LINENO', 0)
         if node.doc:
             self.emitop_obj('LOAD_CONST', node.doc)
@@ -313,8 +305,9 @@
 
     def visitExpression(self, node):
         self.set_lineno(node)
-        self.scopes = self.parseSymbols(node)
-        self.scope = self.scopes[node]
+        self.parseSymbols(node)
+        assert node.scope is not None
+        self.scope = node.scope
         node.node.accept( self )
         self.emit('RETURN_VALUE')
 
@@ -335,7 +328,7 @@
         else:
             ndecorators = 0
 
-        gen = FunctionCodeGenerator(self.space, node, self.scopes, isLambda,
+        gen = FunctionCodeGenerator(self.space, node, isLambda,
                                self.class_name, self.get_module())
         walk(node.code, gen)
         gen.finish()
@@ -356,7 +349,7 @@
             self.emitop_int('CALL_FUNCTION', 1)
 
     def visitClass(self, node):
-        gen = ClassCodeGenerator(self.space, node, self.scopes,
+        gen = ClassCodeGenerator(self.space, node,
                                  self.get_module())
         walk(node.code, gen)
         gen.finish()
@@ -597,7 +590,7 @@
         self.emit('POP_TOP')
 
     def visitGenExpr(self, node):
-        gen = GenExprCodeGenerator(self.space, node, self.scopes, self.class_name,
+        gen = GenExprCodeGenerator(self.space, node, self.class_name,
                                    self.get_module())
         inner = node.code
         assert isinstance(inner, ast.GenExprInner)
@@ -1149,44 +1142,41 @@
 
 
 class ModuleCodeGenerator(CodeGenerator):
-    scopes = None
 
     def __init__(self, space, tree, futures = []):
-        self.graph = pyassem.PyFlowGraph(space, "<module>", tree.filename)
+        graph = pyassem.PyFlowGraph(space, "<module>", tree.filename)
         self.futures = future.find_futures(tree)
         for f in futures:
             if f not in self.futures:
                 self.futures.append(f)
-        CodeGenerator.__init__(self, space)
-        walk(tree, self)
+        CodeGenerator.__init__(self, space, graph)
+        tree.accept(self) # yuck
 
     def get_module(self):
         return self
 
 class ExpressionCodeGenerator(CodeGenerator):
-    scopes = None
 
     def __init__(self, space, tree, futures=[]):
-        self.graph = pyassem.PyFlowGraph(space, "<expression>", tree.filename)
+        graph = pyassem.PyFlowGraph(space, "<expression>", tree.filename)
         self.futures = futures[:]
-        CodeGenerator.__init__(self, space)
-        walk(tree, self)
+        CodeGenerator.__init__(self, space, graph)
+        tree.accept(self) # yuck
 
     def get_module(self):
         return self
 
 class InteractiveCodeGenerator(CodeGenerator):
-    scopes = None
 
     def __init__(self, space, tree, futures=[]):
-        self.graph = pyassem.PyFlowGraph(space, "<interactive>", tree.filename)
+        graph = pyassem.PyFlowGraph(space, "<interactive>", tree.filename)
         self.futures = future.find_futures(tree)
         for f in futures:
             if f not in self.futures:
                 self.futures.append(f)
-        CodeGenerator.__init__(self, space)
+        CodeGenerator.__init__(self, space, graph)
         self.set_lineno(tree)
-        walk(tree, self)
+        tree.accept(self) # yuck
         self.emit('RETURN_VALUE')
 
     def get_module(self):
@@ -1198,26 +1188,24 @@
         node.expr.accept( self )
         self.emit('PRINT_EXPR')
 
-class AbstractFunctionCode(CodeGenerator):
-    optimized = 1
-    lambdaCount = 0
+AbstractFunctionCodeLambdaCounter = symbols.Counter(0)
 
-    def __init__(self, space, func, scopes, isLambda, class_name, mod):
+class AbstractFunctionCode(CodeGenerator):
+    def __init__(self, space, func, isLambda, class_name, mod):
         self.class_name = class_name
         self.module = mod
         if isLambda:
-            klass = FunctionCodeGenerator
-            name = "<lambda.%d>" % klass.lambdaCount
-            klass.lambdaCount = klass.lambdaCount + 1
+            name = "<lambda.%d>" % AbstractFunctionCodeLambdaCounter.next()
         else:
             assert isinstance(func, ast.Function)
             name = func.name
 
         args, hasTupleArg = generateArgList(func.argnames)
-        self.graph = pyassem.PyFlowGraph(space, name, func.filename, args,
+        graph = pyassem.PyFlowGraph(space, name, func.filename, args,
                                          optimized=1)
         self.isLambda = isLambda
-        CodeGenerator.__init__(self, space)
+        CodeGenerator.__init__(self, space, graph)
+        self.optimized = 1
 
         if not isLambda and func.doc:
             self.setDocstring(func.doc)
@@ -1263,36 +1251,34 @@
     unpackTuple = unpackSequence
 
 class FunctionCodeGenerator(AbstractFunctionCode):
-    scopes = None
 
-    def __init__(self, space, func, scopes, isLambda, class_name, mod):
-        self.scopes = scopes
-        self.scope = scopes[func]
-        AbstractFunctionCode.__init__(self, space, func, scopes, isLambda, class_name, mod)
+    def __init__(self, space, func, isLambda, class_name, mod):
+        assert func.scope is not None
+        self.scope = func.scope
+        AbstractFunctionCode.__init__(self, space, func, isLambda, class_name, mod)
         self.graph.setFreeVars(self.scope.get_free_vars())
         self.graph.setCellVars(self.scope.get_cell_vars())
         if self.scope.generator:
             self.graph.setFlag(CO_GENERATOR)
 
 class GenExprCodeGenerator(AbstractFunctionCode):
-    scopes = None
 
-    def __init__(self, space, gexp, scopes, class_name, mod):
-        self.scopes = scopes
-        self.scope = scopes[gexp]
-        AbstractFunctionCode.__init__(self, space, gexp, scopes, 1, class_name, mod)
+    def __init__(self, space, gexp, class_name, mod):
+        assert gexp.scope is not None
+        self.scope = gexp.scope
+        AbstractFunctionCode.__init__(self, space, gexp, 1, class_name, mod)
         self.graph.setFreeVars(self.scope.get_free_vars())
         self.graph.setCellVars(self.scope.get_cell_vars())
         self.graph.setFlag(CO_GENERATOR)
 
 class AbstractClassCode(CodeGenerator):
 
-    def __init__(self, space, klass, scopes, module):
+    def __init__(self, space, klass, module):
         self.class_name = klass.name
         self.module = module
-        self.graph = pyassem.PyFlowGraph( space, klass.name, klass.filename,
+        graph = pyassem.PyFlowGraph( space, klass.name, klass.filename,
                                            optimized=0, klass=1)
-        CodeGenerator.__init__(self, space)
+        CodeGenerator.__init__(self, space, graph)
         self.graph.setFlag(CO_NEWLOCALS)
         if klass.doc:
             self.setDocstring(klass.doc)
@@ -1306,12 +1292,11 @@
         self.emit('RETURN_VALUE')
 
 class ClassCodeGenerator(AbstractClassCode):
-    scopes = None
 
-    def __init__(self, space, klass, scopes, module):
-        self.scopes = scopes
-        self.scope = scopes[klass]
-        AbstractClassCode.__init__(self, space, klass, scopes, module)
+    def __init__(self, space, klass, module):
+        assert klass.scope is not None
+        self.scope = klass.scope
+        AbstractClassCode.__init__(self, space, klass, module)
         self.graph.setFreeVars(self.scope.get_free_vars())
         self.graph.setCellVars(self.scope.get_cell_vars())
         self.set_lineno(klass)

Modified: pypy/dist/pypy/interpreter/astcompiler/symbols.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/symbols.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/symbols.py	Fri Sep  9 19:17:07 2005
@@ -12,6 +12,15 @@
 
 MANGLE_LEN = 256
 
+class Counter:
+    def __init__(self, initial):
+        self.count = initial
+
+    def next(self):
+        i = self.count
+        self.count += 1
+        return i
+
 class Scope:
     # XXX how much information do I need about each name?
     def __init__(self, name, module, klass=None):
@@ -180,12 +189,12 @@
 class FunctionScope(Scope):
     pass
 
+GenExprScopeCounter = Counter(1)
+
 class GenExprScope(Scope):
-    __counter = 1
 
     def __init__(self, module, klass=None):
-        i = self.__counter
-        self.__counter += 1
+        i = GenExprScopeCounter.next()
         Scope.__init__(self, "generator expression<%d>"%i, module, klass)
         self.add_param('[outmost-iterable]')
 
@@ -193,12 +202,12 @@
         keys = Scope.get_names()
         return keys
 
+LambdaScopeCounter = Counter(1)
+
 class LambdaScope(FunctionScope):
-    __counter = 1
 
     def __init__(self, module, klass=None):
-        i = self.__counter
-        self.__counter += 1
+        i = LambdaScopeCounter.next()
         Scope.__init__(self, "lambda.%d" % i, module, klass)
 
 class ClassScope(Scope):
@@ -209,7 +218,6 @@
 class SymbolVisitor(ast.ASTVisitor):
     def __init__(self, space):
         self.space = space
-        self.scopes = {}
         self.klass = None
         self.scope_stack = []
         self.assign_stack = [ False ]
@@ -235,7 +243,7 @@
     # node that define new scopes
 
     def visitModule(self, node):
-        scope = self.module = self.scopes[node] = ModuleScope()
+        scope = self.module = node.scope = ModuleScope()
         self.push_scope(scope)
         node.node.accept(self)
         self.pop_scope()
@@ -252,7 +260,7 @@
         scope = FunctionScope(node.name, self.module, self.klass)
         if parent.nested or isinstance(parent, FunctionScope):
             scope.nested = 1
-        self.scopes[node] = scope
+        node.scope = scope
         self._do_args(scope, node.argnames)
         self.push_scope( scope )
         node.code.accept(self )
@@ -266,7 +274,7 @@
                 or isinstance(parent, GenExprScope):
             scope.nested = 1
 
-        self.scopes[node] = scope
+        node.scope = scope
         self.push_scope(scope)
         node.code.accept(self)
         self.pop_scope()
@@ -302,7 +310,7 @@
         scope = LambdaScope(self.module, self.klass)
         if parent.nested or isinstance(parent, FunctionScope):
             scope.nested = 1
-        self.scopes[node] = scope
+        node.scope = scope
         self._do_args(scope, node.argnames)
         self.push_scope(scope)
         node.code.accept(self)
@@ -333,7 +341,7 @@
         if node.doc is not None:
             scope.add_def('__doc__')
         scope.add_def('__module__')
-        self.scopes[node] = scope
+        node.scope = scope
         prev = self.klass
         self.klass = node.name
         self.push_scope( scope )
@@ -467,6 +475,7 @@
 def list_eq(l1, l2):
     return sort(l1) == sort(l2)
 
+    
 if __name__ == "__main__":
     import sys
     from pypy.interpreter.astcompiler import parseFile, walk
@@ -488,7 +497,7 @@
         walk(tree, s)
 
         # compare module-level symbols
-        names2 = s.scopes[tree].get_names()
+        names2 = tree.scope.get_names()
 
         if not list_eq(mod_names, names2):
             print
@@ -498,6 +507,7 @@
             sys.exit(-1)
 
         d = {}
+        # this part won't work anymore
         d.update(s.scopes)
         del d[tree]
         scopes = d.values()

Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/astbuilder.py	(original)
+++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py	Fri Sep  9 19:17:07 2005
@@ -123,7 +123,8 @@
             stack.pop()
         else:
             assert isinstance(token, TokenObject)
-            stack[-1].nodes.append(ast.AssName(token.get_value(),consts.OP_ASSIGN))
+            val = token.get_value()
+            stack[-1].nodes.append(ast.AssName(val,consts.OP_ASSIGN))
     return tokens_read, top
 
 def parse_arglist(tokens):
@@ -153,7 +154,8 @@
                 assert isinstance(cur_token, TokenObject)
                 index += 1
                 if cur_token.name == tok.NAME:
-                    names.append( ast.AssName( cur_token.get_value(), consts.OP_ASSIGN ) )
+                    val = cur_token.get_value()
+                    names.append( ast.AssName( val, consts.OP_ASSIGN ) )
                     flags |= consts.CO_VARARGS
                     index += 1
                     if index >= l:
@@ -171,7 +173,8 @@
             index += 1
             assert isinstance(cur_token, TokenObject)
             if cur_token.name == tok.NAME:
-                names.append( ast.AssName( cur_token.get_value(), consts.OP_ASSIGN ) )
+                val = cur_token.get_value()
+                names.append( ast.AssName( val, consts.OP_ASSIGN ) )
                 flags |= consts.CO_VARKEYWORDS
                 index +=  1
             else:
@@ -179,7 +182,8 @@
             if index < l:
                 raise ValueError("unexpected token: %s" % tokens[index])
         elif cur_token.name == tok.NAME:
-            names.append( ast.AssName( cur_token.get_value(), consts.OP_ASSIGN ) )
+            val = cur_token.get_value()
+            names.append( ast.AssName( val, consts.OP_ASSIGN ) )
     return names, defaults, flags
 
 
@@ -407,7 +411,8 @@
     token = tokens[0]
     # XXX HACK for when parse_attraccess is called from build_decorator
     if isinstance(token, TokenObject):
-        result = ast.Name(token.get_value())
+        val = token.get_value()
+        result = ast.Name(val)
     else:
         result = token
     index = 1
@@ -485,7 +490,8 @@
                 items.append((atoms[index], atoms[index+2]))
             builder.push(ast.Dict(items)) #  top.line))
         elif top.name == tok.NAME:
-            builder.push( ast.Name(top.get_value()) )
+            val = top.get_value()
+            builder.push( ast.Name(val) )
         elif top.name == tok.NUMBER:
             builder.push(ast.Const(builder.eval_number(top.get_value())))
         elif top.name == tok.STRING:
@@ -948,6 +954,7 @@
     funcname_token = atoms[1]
     assert isinstance(funcname_token, TokenObject)
     funcname = funcname_token.get_value()
+    assert funcname is not None
     arglist = atoms[2]
     code = atoms[-1]
     doc = get_docstring(builder, code)
@@ -960,7 +967,7 @@
     l = len(atoms)
     classname_token = atoms[1]
     assert isinstance(classname_token, TokenObject)
-    classname = classname_token.get_value()
+    classname = classname_token.get_string()
     if l == 4:
         basenames = []
         body = atoms[3]
@@ -1388,10 +1395,9 @@
                                   tok.tok_name.get(self.name, str(self.name)))
 
     def get_value(self):
-        if self.value is None:
+        value = self.value
+        if value is None:
             value = ''
-        else:
-            value = self.value
         return value
     
     def __str__(self):



More information about the Pypy-commit mailing list