[pypy-svn] r13356 - pypy/branch/pycompiler/module/recparser

adim at codespeak.net adim at codespeak.net
Mon Jun 13 17:28:25 CEST 2005


Author: adim
Date: Mon Jun 13 17:28:24 2005
New Revision: 13356

Modified:
   pypy/branch/pycompiler/module/recparser/codegen.py
Log:
updated codegen draft

Modified: pypy/branch/pycompiler/module/recparser/codegen.py
==============================================================================
--- pypy/branch/pycompiler/module/recparser/codegen.py	(original)
+++ pypy/branch/pycompiler/module/recparser/codegen.py	Mon Jun 13 17:28:24 2005
@@ -1,3 +1,10 @@
+# Copyright (c) 2000-2003 LOGILAB S.A. (Paris, FRANCE).
+# http://www.logilab.fr/ -- mailto:contact at logilab.fr
+"""
+
+"""
+
+__revision__ = "$Id: $"
 
 import pythonutil
 from compiler.visitor import ASTVisitor
@@ -27,7 +34,7 @@
     def __init__(self):
         self.lineno = 0
         
-    def emit(self, insn ):
+    def emit(self, insn):
         print "% 5d     %s" % (self.lineno, insn)
 
     def emit_arg(self, insn, arg ):
@@ -54,15 +61,26 @@
     def set_start_pos(self, pos ):
         self.start_pos = pos
 
+###########################
+### XXX MUST FIX SET_LINENO
+###########################
 
     
 class CompilerVisitor(ASTVisitor):
     """Basic code generator for Python Bytecode"""
+
+    LOOP = 1
+    EXCEPT = 2
+    TRY_FINALLY = 3
+    END_FINALLY = 4
+
     def __init__(self, filename, flags, dont_inherit ):
         self.scopes = []
         self.blocks = []
+        self.setups = [] # for loops and try/finally
         self.code = None
         self.current_block = None
+        self.ctx = PrintContext()
 
     ### Visitor functions
 
@@ -87,18 +105,100 @@
             if is_constant_false(test):
                 continue
             test.visit(self) # emit test code in current block
-            self.a
             nextTest = Block()
+            self.emit(CondJump('IF_FALSE', nextTest))
+            self.nextBlock()
+            self.emit(PopTop())
+            suite.visit(self)
+            self.emit(CondJump('FWD', end))
+            self.startBlock(nextTest)
+            self.emit(PopTop())
+        if node.else_:
+            node.else_.visit(self)
+        self.nextBlock(end)
+                           
+    def visitWhile(self, node):
+        # XXX emit LINENO here ?
+        loop = self.newBlock()
+        else_ = self.newBlock()
+        after = self.newBlock()
+
+        self.emit(SetupLoop(after))
+        
+        self.nextBlock(loop)
+        self.setups.append((self.LOOP, loop))
+
+        node.test.visit(self)
+        self.emit(CondJump('IF_FALSE', else_or after))
 
+        self.nextBlock()
+        self.emit(PopTop())
+        node.body.visit(self)
+        self.emit(CondJump('ABOSLUTE', loop))
+
+        self.startBlock(else_) # or just the POPs if not else clause
+        self.emit(PopTop())
+        self.emit(PopBlock())
+        self.setups.pop()
+        if node.else_:
+            node.else_.visit(self)
+        self.nextBlock(after)
+        
+
+    def visitFor(self, node):
+        start = self.newBlock()
+        anchor = self.newBlock()
+        after = self.newBlock()
+
+        self.setups.append((self.LOOP, start))
+
+        self.emit(SetupLoop(after))
+        node.list.visit(self)
+        self.emit(GetIter())
+
+        self.nextBlock(start)
+        self.set_lineno(node, force=1)
+        self.emit(ForIter(anchor))
+        node.assign.visit(self)
+        node.body.visit(self)
+        self.emit(CondJump('ABSOLUTE', start))
+        self.nextBlock(anchor)
+        self.emit(PopBlock())
+        self.setups.pop()
+        if node.else_:
+            node.else_.visist(self)
+        self.nextBlock(after)
+
+    def visitBreak(self, node):
+        if not self.setups:
+            raise SyntaxError("'break' outside loop (%s, %d)" % \
+                              (node.filename, node.lineno))
+        # self.set_lineno(node)
+        self.emit(BreakLoop())
+
+
+    ## Shortcut methods
+    def emit(self, bytecode):
+        bytecode.emit(self.ctx)
+            
     ### Block handling functions
     def newBlock(self):
         """Create a new block and make it current"""
         b = Block()
         self.blocks.append(b)
-        self.current_block = b
+        # self.current_block = b
         return b
 
+    def nextBlock(self, block=None):
+        """goto next block in the flow graph"""
+        if block is None:
+            block = self.newBlock()
 
+        self.blocks.append(block)
+        self.startBlock(block)
+    
+    def startBlock(self, block):
+        self.current_block = block
 
 if __name__ == "__main__":
     testf = file("pycodegen2.py").read()



More information about the Pypy-commit mailing list