[pypy-svn] r13394 - in pypy/dist/pypy/rpython: . test

hpk at codespeak.net hpk at codespeak.net
Tue Jun 14 19:10:59 CEST 2005


Author: hpk
Date: Tue Jun 14 19:10:58 2005
New Revision: 13394

Added:
   pypy/dist/pypy/rpython/interp.py
   pypy/dist/pypy/rpython/test/test_interp.py
Log:
simplistic start at a lowlevel flow interpreter 



Added: pypy/dist/pypy/rpython/interp.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/interp.py	Tue Jun 14 19:10:58 2005
@@ -0,0 +1,77 @@
+from pypy.rpython.lltype import * 
+
+
+class LLInterpreter(object): 
+    """ low level interpreter working with concrete values. """ 
+    def __init__(self, flowgraphs): 
+        self.flowgraphs = flowgraphs 
+        self.bindings = {}
+
+    # _______________________________________________________
+    # variable setters/getters helpers 
+    
+    def fillvars(self, block, values): 
+        vars = block.inputargs 
+        assert len(vars) == len(values), (
+                   "block %s received %d args, expected %d" % (
+                    block, len(values), len(vars)))
+        for var, val in zip(vars, values): 
+            self.setvar(var, val) 
+        
+    def setvar(self, var, val): 
+        # XXX assert that val "matches" lowlevel type 
+        assert var not in self.bindings 
+        self.bindings[var] = val 
+
+    def getval(self, varorconst): 
+        try: 
+            return varorconst.value
+        except AttributeError: 
+            return self.bindings[varorconst]
+
+    # _______________________________________________________
+    # evaling functions 
+
+    def eval_function(self, func, args=()): 
+        graph = self.flowgraphs[func]
+        # inputargs 
+        self.fillvars(graph.startblock, args) 
+        # run startblock 
+        nextblock = graph.startblock
+        while 1: 
+            nextblock, values = self.eval_block(nextblock) 
+            if nextblock is None: 
+                return values
+            self.fillvars(nextblock, values) 
+
+    def eval_block(self, block): 
+        for op in block.operations: 
+            self.eval_operation(op) 
+
+        # determine nextblock and/or return value 
+        if len(block.exits) == 0: 
+            # return block 
+            resvar, = block.getvariables()
+            return None, self.getval(resvar) 
+        elif len(block.exits) == 1: 
+            index = 0 
+        else: 
+            index = self.getval(block.exitswitch) 
+        link = block.exits[index]
+        return link.target, [self.getval(x) for x in link.args]
+    
+    def eval_operation(self, operation): 
+        g = globals()
+        opname = operation.opname
+        assert opname in g, (
+                "cannot handle operation %r yet" %(opname,))
+        ophandler = g[opname]
+        vals = [self.getval(x) for x in operation.args]
+        retval = ophandler(*vals) 
+        self.setvar(operation.result, retval)
+
+##############################
+# int operations 
+
+def int_add(x, y): 
+    return x + y 

Added: pypy/dist/pypy/rpython/test/test_interp.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/test/test_interp.py	Tue Jun 14 19:10:58 2005
@@ -0,0 +1,51 @@
+
+import py
+py.magic.autopath()
+from pypy.rpython.rtyper import RPythonTyper 
+from pypy.rpython.interp import LLInterpreter 
+from pypy.translator.translator import Translator 
+
+def gengraph(func, argtypes=[]): 
+    t = Translator(func)
+    t.annotate(argtypes)
+    typer = RPythonTyper(t.annotator)
+    typer.specialize()
+    #t.view()
+    t.checkgraphs()
+    return t
+    
+def test_int_adding(): 
+    t = gengraph(int_adding, [int])
+    interp = LLInterpreter(t.flowgraphs)
+    res = interp.eval_function(int_adding, [3])
+    assert res == 6 
+
+#__________________________________________________________________
+# example functions for testing the LLInterpreter 
+_snap = globals().copy()
+
+def int_adding(i): 
+    j = i + 2
+    return j + 1 
+
+
+
+#__________________________________________________________________
+# interactive playing 
+
+if __name__ == '__main__': 
+    try:
+        import rlcompleter2 as _rl2
+        _rl2.setup() 
+    except ImportError: 
+        pass
+
+    t = gengraph(int_adding, [int])
+    interp = LLInterpreter(t.flowgraphs)
+    res = interp.eval_function(int_adding, [3])
+    assert res == 6 
+    for name, value in globals().items(): 
+        if name not in _snap and name[0] != '_': 
+            print "%20s: %s" %(name, value)
+
+



More information about the Pypy-commit mailing list