[pypy-svn] r16279 - pypy/dist/pypy/interpreter/astcompiler

ludal at codespeak.net ludal at codespeak.net
Tue Aug 23 16:53:34 CEST 2005


Author: ludal
Date: Tue Aug 23 16:53:32 2005
New Revision: 16279

Modified:
   pypy/dist/pypy/interpreter/astcompiler/pyassem.py
   pypy/dist/pypy/interpreter/astcompiler/pycodegen.py
   pypy/dist/pypy/interpreter/astcompiler/symbols.py
Log:
 - make astcompiler accept the new ast form for function arguments
 - some modifications make the compiler look more rpythonic
 - fixes to accept the new varname attribute for Name nodes


Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/pyassem.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/pyassem.py	Tue Aug 23 16:53:32 2005
@@ -5,7 +5,7 @@
 import sys
 import types
 
-from pypy.interpreter.astcompiler import misc
+from pypy.interpreter.astcompiler import misc, ast
 from pypy.interpreter.astcompiler.consts \
      import CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS
 
@@ -340,11 +340,16 @@
         # 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]
-            if isinstance(var, TupleArg):
-                self.varnames[i] = var.getName()
+        self.varnames = []
+        for var in args:
+            if isinstance(var, ast.AssName):
+                self.varnames.append(var.name)
+            elif isinstance(var, TupleArg):
+                self.varnames.append(var.getName())
+            elif isinstance(var, ast.AssTuple):
+                for n in var.flatten():
+                    assert isinstance(n, ast.AssName)
+                    self.varnames.append(n.name)
         self.stage = RAW
         self.orderedblocks = []
 
@@ -397,6 +402,20 @@
         if io:
             sys.stdout = save
 
+    def _max_depth(self, depth, seen, b, d):
+        if seen.has_key(b):
+            return d
+        seen[b] = 1
+        d = d + depth[b]
+        children = b.get_children()
+        if children:
+            return max([ self._max_depth(depth, seen, c, d) for c in children])
+        else:
+            if not b.label == "exit":
+                return self._max_depth(depth, seen, self.exit, d)
+            else:
+                return d
+
     def computeStackDepth(self):
         """Compute the max stack depth.
 
@@ -411,21 +430,7 @@
 
         seen = {}
 
-        def max_depth(b, d):
-            if seen.has_key(b):
-                return d
-            seen[b] = 1
-            d = d + depth[b]
-            children = b.get_children()
-            if children:
-                return max([max_depth(c, d) for c in children])
-            else:
-                if not b.label == "exit":
-                    return max_depth(self.exit, d)
-                else:
-                    return d
-
-        self.stacksize = max_depth(self.entry, 0)
+        self.stacksize = self._max_depth( depth, seen, self.entry, 0)
 
     def flattenGraph(self):
         """Arrange the blocks in order and resolve jumps"""
@@ -661,7 +666,7 @@
     if opname[:4] == 'JUMP':
         return 1
 
-class TupleArg:
+class TupleArg(ast.Node):
     """Helper for marking func defs with nested tuples in arglist"""
     def __init__(self, count, names):
         self.count = count

Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py	Tue Aug 23 16:53:32 2005
@@ -14,12 +14,8 @@
     CO_NEWLOCALS, CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION
 from pypy.interpreter.astcompiler.pyassem import TupleArg
 
-# XXX The version-specific code can go, since this code only works with 2.x.
-# Do we have Python 1.x or Python 2.x?
-try:
-    VERSION = sys.version_info[0]
-except AttributeError:
-    VERSION = 1
+# drop VERSION dependency since it the ast transformer for 2.4 doesn't work with 2.3 anyway
+VERSION = 2
 
 callfunc_opcode_info = {
     # (Have *args, Have **args) : opcode
@@ -186,12 +182,6 @@
     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.
-
-    The concrete class must also define the class attributes
-    NameFinder, FunctionGen, and ClassGen.  These attributes can be
-    defined in the initClass() method, which is a hook for
-    initializing these methods after all the classes have been
-    defined.
     """
 
     optimized = 0 # is namespace access optimized?
@@ -199,9 +189,6 @@
     class_name = None # provide default for instance variable
 
     def __init__(self):
-        if self.__initialized is None:
-            self.initClass()
-            self.__class__.__initialized = 1
         self.checkClass()
         self.locals = misc.Stack()
         self.setups = misc.Stack()
@@ -218,9 +205,6 @@
             elif feature == "generators":
                 self.graph.setFlag(CO_GENERATOR_ALLOWED)
 
-    def initClass(self):
-        """This method is called once for each class"""
-
     def checkClass(self):
         """Verify that class is constructed correctly"""
         try:
@@ -848,8 +832,7 @@
     def visitImport(self, node):
         self.set_lineno(node)
         for name, alias in node.names:
-            if VERSION > 1:
-                self.emit('LOAD_CONST', None)
+            self.emit('LOAD_CONST', None)
             self.emit('IMPORT_NAME', name)
             mod = name.split(".")[0]
             if alias:
@@ -861,23 +844,19 @@
     def visitFrom(self, node):
         self.set_lineno(node)
         fromlist = map(lambda (name, alias): name, node.names)
-        if VERSION > 1:
-            self.emit('LOAD_CONST', tuple(fromlist))
+        self.emit('LOAD_CONST', tuple(fromlist))
         self.emit('IMPORT_NAME', node.modname)
         for name, alias in node.names:
-            if VERSION > 1:
-                if name == '*':
-                    self.namespace = 0
-                    self.emit('IMPORT_STAR')
-                    # There can only be one name w/ from ... import *
-                    assert len(node.names) == 1
-                    return
-                else:
-                    self.emit('IMPORT_FROM', name)
-                    self._resolveDots(name)
-                    self.storeName(alias or name)
+            if name == '*':
+                self.namespace = 0
+                self.emit('IMPORT_STAR')
+                # There can only be one name w/ from ... import *
+                assert len(node.names) == 1
+                return
             else:
                 self.emit('IMPORT_FROM', name)
+                self._resolveDots(name)
+                self.storeName(alias or name)
         self.emit('POP_TOP')
 
     def _resolveDots(self, name):
@@ -1221,14 +1200,8 @@
             self.emit('ROT_THREE')
             self.emit('STORE_SUBSCR')
 
-class NestedScopeMixin:
-    """Defines initClass() for nested scoping (Python 2.2-compatible)"""
-    def initClass(self):
-        self.__class__.NameFinder = LocalNameFinder
-        self.__class__.FunctionGen = FunctionCodeGenerator
-        self.__class__.ClassGen = ClassCodeGenerator
 
-class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
+class ModuleCodeGenerator(CodeGenerator):
     __super_init = CodeGenerator.__init__
 
     scopes = None
@@ -1242,7 +1215,7 @@
     def get_module(self):
         return self
 
-class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator):
+class ExpressionCodeGenerator(CodeGenerator):
     __super_init = CodeGenerator.__init__
 
     scopes = None
@@ -1256,7 +1229,7 @@
     def get_module(self):
         return self
 
-class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator):
+class InteractiveCodeGenerator(CodeGenerator):
 
     __super_init = CodeGenerator.__init__
 
@@ -1324,24 +1297,27 @@
     def generateArgUnpack(self, args):
         for i in range(len(args)):
             arg = args[i]
-            if type(arg) == types.TupleType:
+            if isinstance(arg, ast.AssTuple):
                 self.emit('LOAD_FAST', '.%d' % (i * 2))
                 self.unpackSequence(arg)
 
     def unpackSequence(self, tup):
         if VERSION > 1:
-            self.emit('UNPACK_SEQUENCE', len(tup))
+            self.emit('UNPACK_SEQUENCE', len(tup.nodes))
         else:
-            self.emit('UNPACK_TUPLE', len(tup))
-        for elt in tup:
-            if type(elt) == types.TupleType:
-                self.unpackSequence(elt)
+            self.emit('UNPACK_TUPLE', len(tup.nodes))
+        
+        for elt in tup.nodes:
+            if isinstance(elt, ast.AssName):
+                self._nameOp('STORE', elt.name)
+            elif isinstance(elt, ast.AssTuple):
+                self.unpackSequence( elt )
             else:
-                self._nameOp('STORE', elt)
+                raise TypeError( "Got argument %s of type %s" % (elt,type(elt)))
 
     unpackTuple = unpackSequence
 
-class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
+class FunctionCodeGenerator(AbstractFunctionCode,
                             CodeGenerator):
     super_init = CodeGenerator.__init__ # call be other init
     scopes = None
@@ -1357,7 +1333,7 @@
         if self.scope.generator is not None:
             self.graph.setFlag(CO_GENERATOR)
 
-class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
+class GenExprCodeGenerator(AbstractFunctionCode,
                            CodeGenerator):
     super_init = CodeGenerator.__init__ # call be other init
     scopes = None
@@ -1394,7 +1370,7 @@
         self.emit('LOAD_LOCALS')
         self.emit('RETURN_VALUE')
 
-class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
+class ClassCodeGenerator(AbstractClassCode, CodeGenerator):
     super_init = CodeGenerator.__init__
     scopes = None
 
@@ -1420,14 +1396,14 @@
     count = 0
     for i in range(len(arglist)):
         elt = arglist[i]
-        if type(elt) == types.StringType:
+        if isinstance(elt, ast.AssName):
             args.append(elt)
-        elif type(elt) == types.TupleType:
+        elif isinstance(elt, ast.AssTuple):
             args.append(TupleArg(i * 2, elt))
-            extra.extend(misc.flatten(elt))
+            extra.extend(ast.flatten(elt))
             count = count + 1
         else:
-            raise ValueError, "unexpect argument type:", elt
+            raise ValueError( "unexpect argument type: %s" % elt )
     return args + extra, count
 
 def findOp(node):
@@ -1486,6 +1462,15 @@
 def wrap_aug(node):
     return wrapper[node.__class__](node)
 
+
+for klass in (ModuleCodeGenerator, ExpressionCodeGenerator, InteractiveCodeGenerator,
+              FunctionCodeGenerator, GenExprCodeGenerator, ClassCodeGenerator):
+    klass.NameFinder = LocalNameFinder
+    klass.FunctionGen = FunctionCodeGenerator
+    klass.ClassGen = ClassCodeGenerator
+
+
+
 if __name__ == "__main__":
     for file in sys.argv[1:]:
         compileFile(file)

Modified: pypy/dist/pypy/interpreter/astcompiler/symbols.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/symbols.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/symbols.py	Tue Aug 23 16:53:32 2005
@@ -281,11 +281,13 @@
         self.handle_free_vars(scope, parent)
 
     def _do_args(self, scope, args):
-        for name in args:
-            if type(name) == types.TupleType:
-                self._do_args(scope, name)
+        for arg in args:
+            if isinstance( arg, ast.AssName ):
+                scope.add_param( arg.name )
+            elif isinstance( arg, ast.AssTuple ):
+                self._do_args( scope, arg.flatten() )
             else:
-                scope.add_param(name)
+                raise TypeError( "Argument list contains %s of type %s" % (arg, type(arg) ) )
 
     def handle_free_vars(self, scope, parent):
         parent.add_child(scope)
@@ -316,9 +318,9 @@
 
     def visitName(self, node, scope, assign=0):
         if assign:
-            scope.add_def(node.name)
+            scope.add_def(node.varname)
         else:
-            scope.add_use(node.name)
+            scope.add_use(node.varname)
 
     # operations that bind new names
 



More information about the Pypy-commit mailing list