[pypy-svn] r26283 - in pypy/dist/pypy/translator/cl: . test

sanxiyn at codespeak.net sanxiyn at codespeak.net
Tue Apr 25 04:53:27 CEST 2006


Author: sanxiyn
Date: Tue Apr 25 04:53:21 2006
New Revision: 26283

Modified:
   pypy/dist/pypy/translator/cl/buildcl.py
   pypy/dist/pypy/translator/cl/gencl.py
   pypy/dist/pypy/translator/cl/test/test_cltrans_oo.py
Log:
(dialtone, sanxiyn)
Support generation of methods of classes


Modified: pypy/dist/pypy/translator/cl/buildcl.py
==============================================================================
--- pypy/dist/pypy/translator/cl/buildcl.py	(original)
+++ pypy/dist/pypy/translator/cl/buildcl.py	Tue Apr 25 04:53:21 2006
@@ -95,12 +95,10 @@
     if conftest.option.view:
         t.view()
     
-    graph = t.graphs[0]
-        
-    gen = GenCL(graph, argtypes)
+    gen = GenCL(t, func, argtypes)
     out = gen.emitcode()
     i = 1
-    fpath = path.join("%s.lisp" % graph.name)
+    fpath = path.join("%s.lisp" % func.func_name)
 
     if conftest.option.prettyprint:
         script = path.join(".printer.lisp")
@@ -111,7 +109,7 @@
     def _(*args):
         fpath.write(out)
         fp = file(str(fpath), "a")
-        print >>fp, "(write (", repr_fun_name(graph.name),
+        print >>fp, "(write (", repr_fun_name(func.func_name),
         for arg in args:
             print >>fp, writelisp(arg),
         print >>fp, "))"

Modified: pypy/dist/pypy/translator/cl/gencl.py
==============================================================================
--- pypy/dist/pypy/translator/cl/gencl.py	(original)
+++ pypy/dist/pypy/translator/cl/gencl.py	Tue Apr 25 04:53:21 2006
@@ -1,4 +1,7 @@
-from pypy.rpython.ootypesystem.ootype import Instance, List
+import types
+
+from pypy.translator.translator import graphof
+from pypy.rpython.ootypesystem.ootype import Instance, List, _static_meth, _meth
 from pypy.translator.cl.clrepr import repr_arg, repr_var, repr_const, repr_fun_name, repr_class_name
 
 
@@ -54,8 +57,8 @@
         yield "(setf %s (not (zerop %s)))" % (result, arg)
 
     def op_direct_call(self, result, fun, *args):
-        graph = self.args[0].value.graph
-        self.gen.pendinggraphs.append(graph)
+        funobj = self.args[0].value
+        self.gen.pendinggraphs.append(funobj)
         args = " ".join(args)
         yield "(setf %s (%s %s))" % (result, fun, args)
 
@@ -80,11 +83,19 @@
     def op_oosend(self, result, *ignore):
         method = self.args[0].value
         receiver = self.args[1]
+        cls = receiver.concretetype
         args = self.args[2:]
-        if isinstance(receiver.concretetype, List):
+        if isinstance(cls, List):
             impl = ListImpl(receiver)
             code = getattr(impl, method)(*args)
-        yield "(setf %s %s)" % (result, code)
+            yield "(setf %s %s)" % (result, code)
+        elif isinstance(cls, Instance):
+            methodobj = cls._methods[method]
+            methodobj._method_name = method # XXX
+            self.gen.pendinggraphs.append(methodobj)
+            args = map(repr_arg, args)
+            args = " ".join(args)
+            yield "(setf %s (%s %s %s))" % (result, repr_fun_name(method), repr_arg(receiver), args)
 
     def op_oogetfield(self, result, obj, _):
         fieldname = self.args[1].value
@@ -121,8 +132,9 @@
 
 class GenCL:
 
-    def __init__(self, entry_point, input_arg_types=[]):
-        self.pendinggraphs = [entry_point]
+    def __init__(self, context, funobj, input_arg_types=[]):
+        self.context = context
+        self.pendinggraphs = [funobj]
         self.declarations = []
 
     def emitcode(self, public=True):
@@ -136,15 +148,40 @@
 
     def emit(self):
         while self.pendinggraphs:
-            graph = self.pendinggraphs.pop()
-            for line in self.emit_defun(graph):
-                yield line
+            obj = self.pendinggraphs.pop()
+            if isinstance(obj, types.FunctionType):
+                graph = graphof(self.context, obj)
+                for line in self.emit_defun(graph):
+                    yield line
+            elif isinstance(obj, _static_meth):
+                graph = obj.graph
+                for line in self.emit_defun(graph):
+                    yield line
+            elif isinstance(obj, _meth):
+                graph = obj.graph
+                name = obj._method_name # XXX
+                for line in self.emit_defmethod(graph, name):
+                    yield line
 
     def emit_defun(self, fun):
         yield "(defun " + repr_fun_name(fun.name)
         arglist = fun.getargs()
         args = " ".join(map(repr_var, arglist))
         yield "(%s)" % (args,)
+        for line in self.emit_body(fun, arglist):
+            yield line
+
+    def emit_defmethod(self, fun, name):
+        yield "(defmethod %s" % (repr_fun_name(name))
+        arglist = fun.getargs()
+        cls = arglist[0].concretetype
+        selfvar = repr_var(arglist[0])
+        args = " ".join(map(repr_var, arglist[1:]))
+        yield "((%s %s) %s)" % (selfvar, repr_class_name(cls._name), args)
+        for line in self.emit_body(fun, arglist):
+            yield line
+
+    def emit_body(self, fun, arglist):
         yield "(prog"
         blocklist = list(fun.iterblocks())
         vardict = {}

Modified: pypy/dist/pypy/translator/cl/test/test_cltrans_oo.py
==============================================================================
--- pypy/dist/pypy/translator/cl/test/test_cltrans_oo.py	(original)
+++ pypy/dist/pypy/translator/cl/test/test_cltrans_oo.py	Tue Apr 25 04:53:21 2006
@@ -10,6 +10,21 @@
     cl_new_get_set = make_cl_func(new_get_set)
     assert cl_new_get_set() == 42
 
+def test_inc():
+    class IntHolder:
+        def __init__(self, number):
+            self.number = number
+        def inc(self):
+            self.number += 1
+        def get(self):
+            return self.number
+    def inc(number):
+        obj = IntHolder(number)
+        obj.inc()
+        return obj.get()
+    cl_inc = make_cl_func(inc, [int])
+    assert cl_inc(5) == 6
+
 def test_list_length():
     def list_length_one(number):
         lst = [number]



More information about the Pypy-commit mailing list