[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