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

ludal at codespeak.net ludal at codespeak.net
Mon Aug 22 16:19:11 CEST 2005


Author: ludal
Date: Mon Aug 22 16:19:08 2005
New Revision: 16205

Modified:
   pypy/dist/pypy/interpreter/astcompiler/ast.py
   pypy/dist/pypy/interpreter/astcompiler/astgen.py
   pypy/dist/pypy/interpreter/astcompiler/consts.py
   pypy/dist/pypy/interpreter/astcompiler/future.py
   pypy/dist/pypy/interpreter/astcompiler/pyassem.py
   pypy/dist/pypy/interpreter/astcompiler/pycodegen.py
   pypy/dist/pypy/interpreter/astcompiler/symbols.py
   pypy/dist/pypy/interpreter/astcompiler/syntax.py
   pypy/dist/pypy/interpreter/astcompiler/transformer.py
   pypy/dist/pypy/interpreter/astcompiler/visitor.py
Log:
(ludal, nik)
+ port modifications from stablecompiler to astcompiler
+ modify astgen.py so that it doesn't generate __eq__ on ast.Node



Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/ast.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/ast.py	Mon Aug 22 16:19:08 2005
@@ -33,23 +33,6 @@
         pass # implemented by subclasses
     def visit(self, visitor, *args):
         return visitor.visitNode(self, *args)
-    def __eq__(self, right):
-        if type(self) != type(right):
-            return False
-        # the following tests prevnts Node1([foo]) and Node2([foo])
-        # from being equals. compare __name__ because class will
-        # be different (astcompiler.class1 and stablecompiler.class1 should
-        # be seen as equals)
-        if self.__class__.__name__ != right.__class__.__name__:
-            return False
-        self_child = self.getChildren()
-        right_child = right.getChildren()
-        if len(self_child) != len(right_child):
-            return False
-        for i,j in zip(self_child, right_child):
-            if not i==j:
-                return False
-        return True
 
 class EmptyNode(Node):
     def visit(self, visitor, *args):
@@ -987,7 +970,6 @@
     def accept(self, visitor, args):
         return visitor.visitListComp(self, args)
 
-
 class ListCompFor(Node):
     def __init__(self, assign, list, ifs, lineno=None):
         self.assign = assign

Modified: pypy/dist/pypy/interpreter/astcompiler/astgen.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/astgen.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/astgen.py	Mon Aug 22 16:19:08 2005
@@ -296,13 +296,6 @@
         pass # implemented by subclasses
     def visit(self, visitor, *args):
         return visitor.visitNode(self, *args)
-    def __eq__(self, right):
-        if type(self)!=type(right):
-            return False
-        for i,j in zip(self.getChildren(),right.getChildren()):
-            if not i==j:
-                return False
-        return True
 
 class EmptyNode(Node):
     def visit(self, visitor, *args):

Modified: pypy/dist/pypy/interpreter/astcompiler/consts.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/consts.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/consts.py	Mon Aug 22 16:19:08 2005
@@ -8,6 +8,7 @@
 SC_FREE = 3
 SC_CELL = 4
 SC_UNKNOWN = 5
+SC_REALLY_GLOBAL = 6
 
 CO_OPTIMIZED = 0x0001
 CO_NEWLOCALS = 0x0002

Modified: pypy/dist/pypy/interpreter/astcompiler/future.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/future.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/future.py	Mon Aug 22 16:19:08 2005
@@ -2,7 +2,7 @@
 
 """
 
-from compiler import ast, walk
+from pypy.interpreter.astcompiler import ast, walk
 
 def is_future(stmt):
     """Return true if statement is a well-formed future statement"""
@@ -61,7 +61,7 @@
 
 if __name__ == "__main__":
     import sys
-    from compiler import parseFile, walk
+    from pypy.interpreter.astcompiler import parseFile, walk
 
     for file in sys.argv[1:]:
         print file

Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/pyassem.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/pyassem.py	Mon Aug 22 16:19:08 2005
@@ -5,8 +5,8 @@
 import sys
 import types
 
-from compiler import misc
-from compiler.consts \
+from pypy.interpreter.astcompiler import misc
+from pypy.interpreter.astcompiler.consts \
      import CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS
 
 class FlowGraph:
@@ -81,6 +81,9 @@
 
         i.e. each node appears before all of its successors
         """
+        # TODO: What we need here is a topological sort that
+        
+        
         # XXX make sure every node that doesn't have an explicit next
         # is set so that next points to exit
         for b in self.blocks.elements():
@@ -244,7 +247,7 @@
         op = inst[0]
         if op[:4] == 'JUMP':
             self.outEdges.add(inst[1])
-        self.insts.append(inst)
+        self.insts.append( list(inst) )
 
     def getInstructions(self):
         return self.insts
@@ -343,6 +346,7 @@
             if isinstance(var, TupleArg):
                 self.varnames[i] = var.getName()
         self.stage = RAW
+        self.orderedblocks = []
 
     def setDocstring(self, doc):
         self.docstring = doc
@@ -366,10 +370,10 @@
         """Get a Python code object"""
         if self.stage == RAW:
             self.computeStackDepth()
-            self.flattenGraph()
-        if self.stage == FLAT:
             self.convertArgs()
         if self.stage == CONV:
+            self.flattenGraph()
+        if self.stage == FLAT:
             self.makeByteCode()
         if self.stage == DONE:
             return self.newCodeObject()
@@ -425,35 +429,64 @@
 
     def flattenGraph(self):
         """Arrange the blocks in order and resolve jumps"""
-        assert self.stage == RAW
+        assert self.stage == CONV
         self.insts = insts = []
         pc = 0
         begin = {}
         end = {}
-        for b in self.getBlocksInOrder():
+        forward_refs = []
+        for b in self.orderedblocks:
             begin[b] = pc
             for inst in b.getInstructions():
-                insts.append(inst)
                 if len(inst) == 1:
+                    insts.append(inst)
                     pc = pc + 1
                 elif inst[0] != "SET_LINENO":
-                    # arg takes 2 bytes
-                    pc = pc + 3
+                    opname, arg = inst
+                    if self.hasjrel.has_elt(opname):
+                        # relative jump - no extended arg
+                        forward_refs.append( (arg,  inst, pc ) )
+                        insts.append(inst)
+                        pc = pc + 3
+                    elif self.hasjabs.has_elt(opname):
+                        # absolute jump - can be extended if backward
+                        if arg in begin:
+                            # can only extend argument if backward
+                            offset = begin[arg]
+                            hi, lo = divmod(offset,65536)
+                            if hi>0:
+                                # extended argument
+                                insts.append( ["EXTENDED_ARG", hi ] )
+                                pc = pc + 3
+                            inst[1] = lo
+                        else:
+                            forward_refs.append( (arg,  inst, pc ) )
+                        insts.append(inst)
+                        pc = pc + 3
+                    else:
+                        # numerical arg
+                        assert type(arg)==int
+                        hi,lo = divmod(arg,65536)
+                        if hi>0:
+                            # extended argument
+                            insts.append( ["EXTENDED_ARG", hi ] )
+                            inst[1] = lo
+                            pc = pc + 3    
+                        insts.append(inst)
+                        pc = pc + 3
+                else:
+                    insts.append(inst)
             end[b] = pc
         pc = 0
-        for i in range(len(insts)):
-            inst = insts[i]
-            if len(inst) == 1:
-                pc = pc + 1
-            elif inst[0] != "SET_LINENO":
-                pc = pc + 3
-            opname = inst[0]
+
+        for arg, inst, pc in forward_refs:
+            opname, block = inst
+            abspos = begin[block]
             if self.hasjrel.has_elt(opname):
-                oparg = inst[1]
-                offset = begin[oparg] - pc
-                insts[i] = opname, offset
-            elif self.hasjabs.has_elt(opname):
-                insts[i] = opname, begin[inst[1]]
+                offset = abspos - pc - 3
+                inst[1] = offset
+            else:
+                inst[1] = abspos
         self.stage = FLAT
 
     hasjrel = misc.Set()
@@ -465,16 +498,18 @@
 
     def convertArgs(self):
         """Convert arguments from symbolic to concrete form"""
-        assert self.stage == FLAT
+        assert self.stage == RAW
+        self.orderedblocks = self.getBlocksInOrder()
         self.consts.insert(0, self.docstring)
         self.sort_cellvars()
-        for i in range(len(self.insts)):
-            t = self.insts[i]
-            if len(t) == 2:
-                opname, oparg = t
-                conv = self._converters.get(opname, None)
-                if conv:
-                    self.insts[i] = opname, conv(self, oparg)
+
+        for b in self.orderedblocks:
+            for inst in b.getInstructions():
+                if len(inst) == 2:
+                    opname, oparg = inst
+                    conv = self._converters.get(opname, None)
+                    if conv:
+                        inst[1] = conv(self, oparg)
         self.stage = CONV
 
     def sort_cellvars(self):
@@ -563,10 +598,15 @@
     del name, obj, opname
 
     def makeByteCode(self):
-        assert self.stage == CONV
+        assert self.stage == FLAT
         self.lnotab = lnotab = LineAddrTable()
         for t in self.insts:
             opname = t[0]
+            if self._debug:
+                if len(t)==1:
+                    print "x",opname
+                else:
+                    print "x",opname, t[1]
             if len(t) == 1:
                 lnotab.addCode(self.opnum[opname])
             else:

Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py	Mon Aug 22 16:19:08 2005
@@ -6,12 +6,13 @@
 import types
 from cStringIO import StringIO
 
-from compiler import ast, parse, walk, syntax
-from compiler import pyassem, misc, future, symbols
-from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL
-from compiler.consts import CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS,\
-     CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION
-from compiler.pyassem import TupleArg
+from pypy.interpreter.astcompiler import ast, parse, walk, syntax
+from pypy.interpreter.astcompiler import pyassem, misc, future, symbols
+from pypy.interpreter.astcompiler.consts import SC_LOCAL, SC_GLOBAL, \
+    SC_FREE, SC_CELL, SC_REALLY_GLOBAL
+from pypy.interpreter.astcompiler.consts import CO_VARARGS, CO_VARKEYWORDS, \
+    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?
@@ -285,6 +286,8 @@
                 self.emit(prefix + '_GLOBAL', name)
         elif scope == SC_FREE or scope == SC_CELL:
             self.emit(prefix + '_DEREF', name)
+        elif scope == SC_REALLY_GLOBAL:
+            self.emit(prefix +  '_GLOBAL', name)
         else:
             raise RuntimeError, "unsupported scope for var %s: %d" % \
                   (name, scope)

Modified: pypy/dist/pypy/interpreter/astcompiler/symbols.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/symbols.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/symbols.py	Mon Aug 22 16:19:08 2005
@@ -1,8 +1,9 @@
 """Module symbol-table generator"""
 
-from compiler import ast
-from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL, SC_UNKNOWN
-from compiler.misc import mangle
+from pypy.interpreter.astcompiler import ast
+from pypy.interpreter.astcompiler.consts import SC_LOCAL, SC_GLOBAL, \
+    SC_FREE, SC_CELL, SC_UNKNOWN, SC_REALLY_GLOBAL
+from pypy.interpreter.astcompiler.misc import mangle
 import types
 
 
@@ -89,7 +90,7 @@
         The scope of a name could be LOCAL, GLOBAL, FREE, or CELL.
         """
         if self.globals.has_key(name):
-            return SC_GLOBAL
+            return SC_REALLY_GLOBAL
         if self.cells.has_key(name):
             return SC_CELL
         if self.defs.has_key(name):
@@ -154,7 +155,7 @@
                 if sc == SC_UNKNOWN or sc == SC_FREE \
                    or isinstance(self, ClassScope):
                     self.frees[name] = 1
-                elif sc == SC_GLOBAL:
+                elif sc == SC_GLOBAL or sc == SC_REALLY_GLOBAL:
                     child_globals.append(name)
                 elif isinstance(self, FunctionScope) and sc == SC_LOCAL:
                     self.cells[name] = 1
@@ -419,7 +420,7 @@
 
 if __name__ == "__main__":
     import sys
-    from compiler import parseFile, walk
+    from pypy.interpreter.astcompiler import parseFile, walk
     import symtable
 
     def get_names(syms):

Modified: pypy/dist/pypy/interpreter/astcompiler/syntax.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/syntax.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/syntax.py	Mon Aug 22 16:19:08 2005
@@ -9,7 +9,7 @@
 errors.
 """
 
-from compiler import ast, walk
+from pypy.interpreter.astcompiler import ast, walk
 
 def check(tree, multi=None):
     v = SyntaxErrorChecker(multi)

Modified: pypy/dist/pypy/interpreter/astcompiler/transformer.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/transformer.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/transformer.py	Mon Aug 22 16:19:08 2005
@@ -27,10 +27,12 @@
 #   http://www.opensource.org/licenses/bsd-license.html
 # and replace OWNER, ORGANIZATION, and YEAR as appropriate.
 
-from compiler.ast import *
+# make sure we import the parser with the correct grammar
+import pypy.interpreter.pyparser.pythonparse
+from pypy.interpreter.stablecompiler.ast import *
 import parser
-import symbol
-import token
+import pypy.interpreter.pyparser.pysymbol as symbol
+import pypy.interpreter.pyparser.pytoken as token
 import sys
 
 class WalkerError(StandardError):
@@ -171,7 +173,6 @@
 
     def single_input(self, node):
         ### do we want to do anything about being "interactive" ?
-
         # NEWLINE | simple_stmt | compound_stmt NEWLINE
         n = node[0][0]
         if n != token.NEWLINE:
@@ -780,7 +781,6 @@
         names = []
         defaults = []
         flags = 0
-
         i = 0
         while i < len(nodelist):
             node = nodelist[i]

Modified: pypy/dist/pypy/interpreter/astcompiler/visitor.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/visitor.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/visitor.py	Mon Aug 22 16:19:08 2005
@@ -1,4 +1,4 @@
-from compiler import ast
+from pypy.interpreter.astcompiler import ast
 
 # XXX should probably rename ASTVisitor to ASTWalker
 # XXX can it be made even more generic?



More information about the Pypy-commit mailing list