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

fijal at codespeak.net fijal at codespeak.net
Fri Jan 12 17:30:42 CET 2007


Author: fijal
Date: Fri Jan 12 17:30:38 2007
New Revision: 36592

Added:
   pypy/dist/pypy/rpython/lltypesystem/rgeneric.py
   pypy/dist/pypy/rpython/rgeneric.py
   pypy/dist/pypy/rpython/test/test_rgeneric.py
Modified:
   pypy/dist/pypy/rpython/rtyper.py
   pypy/dist/pypy/rpython/typesystem.py
Log:
(arigo, fijal) - Add rgeneric repr, so now we can provide a callback to an external function.


Added: pypy/dist/pypy/rpython/lltypesystem/rgeneric.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/lltypesystem/rgeneric.py	Fri Jan 12 17:30:38 2007
@@ -0,0 +1,9 @@
+
+from pypy.rpython.rgeneric import AbstractGenericCallableRepr
+from pypy.rpython.lltypesystem.lltype import Ptr, FuncType
+
+class GenericCallableRepr(AbstractGenericCallableRepr):
+    def create_low_leveltype(self):
+        l_args = [r_arg.lowleveltype for r_arg in self.args_r]
+        l_retval = self.r_result.lowleveltype
+        return Ptr(FuncType(l_args, l_retval))

Added: pypy/dist/pypy/rpython/rgeneric.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/rgeneric.py	Fri Jan 12 17:30:38 2007
@@ -0,0 +1,46 @@
+from pypy.annotation import model as annmodel
+from pypy.rpython.rmodel import Repr
+from pypy.rpython.rpbc import AbstractFunctionsPBCRepr
+from pypy.annotation.pairtype import pairtype
+from pypy.rpython.lltypesystem import lltype
+
+class AbstractGenericCallableRepr(Repr):
+    def __init__(self, rtyper, s_generic):
+        self.rtyper = rtyper
+        self.s_generic = s_generic
+        self.args_r = [self.rtyper.getrepr(arg) for arg in s_generic.args_s]
+        self.r_result = self.rtyper.getrepr(s_generic.s_result)
+        self.lowleveltype = self.create_low_leveltype()
+
+    def rtype_simple_call(self, hop):
+        return self.call('simple_call', hop)
+
+    def rtype_call_args(self, hop):
+        return self.call('call_args', hop)
+
+    def call(self, opname, hop):
+        bk = self.rtyper.annotator.bookkeeper
+        vlist = hop.inputargs(self, *self.args_r) + [hop.inputconst(lltype.Void, None)]
+        hop.exception_is_here()
+        v_result = hop.genop('indirect_call', vlist, resulttype=self.r_result)
+        return v_result
+
+    def convert_const(self, value):
+        bookkeeper = self.rtyper.annotator.bookkeeper
+        if value is None:
+            return self.rtyper.type_system.null_callable(self.lowleveltype)
+        r_func = self.rtyper.getrepr(bookkeeper.immutablevalue(value))
+        return r_func.get_unique_llfn().value
+
+class __extend__(annmodel.SomeGenericCallable):
+    def rtyper_makerepr(self, rtyper):
+        return rtyper.type_system.rgeneric.GenericCallableRepr(rtyper, self)
+
+class __extend__(pairtype(AbstractFunctionsPBCRepr, AbstractGenericCallableRepr)):
+    def convert_from_to((pbcrepr, gencallrepr), v, llops):
+        if pbcrepr.lowleveltype is lltype.Void:
+            return gencallrepr.convert_const(pbcrepr.s_pbc.const)
+        if pbcrepr.lowleveltype == gencallrepr.lowleveltype:
+            return v
+        return NotImplemented
+

Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py	(original)
+++ pypy/dist/pypy/rpython/rtyper.py	Fri Jan 12 17:30:38 2007
@@ -932,5 +932,6 @@
 from pypy.rpython import rclass, rbuiltin, rpbc, rspecialcase
 from pypy.rpython import rexternalobj
 from pypy.rpython import rptr
+from pypy.rpython import rgeneric
 from pypy.rpython import raddress # memory addresses
 from pypy.rpython.ootypesystem import rootype

Added: pypy/dist/pypy/rpython/test/test_rgeneric.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/test/test_rgeneric.py	Fri Jan 12 17:30:38 2007
@@ -0,0 +1,40 @@
+from pypy.rpython.rtyper import RPythonTyper
+from pypy.annotation import model as annmodel
+from pypy.annotation.annrpython import RPythonAnnotator
+from pypy.annotation import policy
+from pypy.rpython.test.test_llinterp import interpret, interpret_raises
+
+import py
+
+class TestRGeneric:
+    def test_some_generic_function_call(self):
+        def h(x):
+            return int(x)
+
+        def c(x):
+            return int(x) + 1
+
+        def default(x):
+            return int(x) + 3
+        
+        def g(a, x):
+            if x == -1:
+                a = None
+            if x > 0:
+                if x == 1:
+                    a = h
+                else:
+                    a = c
+                x = x + 0.01
+            return a(x)
+
+        def f(x):
+            return g(default, x)
+
+        g._annenforceargs_ = policy.Sig(annmodel.SomeGenericCallable(
+            args=[annmodel.SomeFloat()], result=annmodel.SomeInteger()),
+                                        float)
+
+        assert interpret(f, [1.]) == 1
+        assert interpret(f, [10.]) == 11
+        assert interpret(f, [-3.]) == 0

Modified: pypy/dist/pypy/rpython/typesystem.py
==============================================================================
--- pypy/dist/pypy/rpython/typesystem.py	(original)
+++ pypy/dist/pypy/rpython/typesystem.py	Fri Jan 12 17:30:38 2007
@@ -21,7 +21,7 @@
             except ImportError:
                 return None
         if name in ('rclass', 'rpbc', 'rbuiltin', 'rtuple', 'rlist',
-                    'rslice', 'rdict', 'rrange', 'rstr',
+                    'rslice', 'rdict', 'rrange', 'rstr', 'rgeneric',
                     'll_str', 'exceptiondata'):
             mod = load(name)
             if mod is not None:



More information about the Pypy-commit mailing list