[pypy-svn] r23211 - in pypy/dist/pypy: annotation rpython rpython/lltypesystem rpython/lltypesystem/test rpython/test

pedronis at codespeak.net pedronis at codespeak.net
Fri Feb 10 17:54:19 CET 2006


Author: pedronis
Date: Fri Feb 10 17:54:16 2006
New Revision: 23211

Modified:
   pypy/dist/pypy/annotation/builtin.py
   pypy/dist/pypy/rpython/lltypesystem/lltype.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py
   pypy/dist/pypy/rpython/rbuiltin.py
   pypy/dist/pypy/rpython/test/test_llann.py
   pypy/dist/pypy/rpython/test/test_rbuiltin.py
Log:
generic cast_primitive(PRIMITIVE_TYPE, value), avoids to have logic to pick the right highlevel op
corresponding to cast_xxx_to_yyy when generating code.



Modified: pypy/dist/pypy/annotation/builtin.py
==============================================================================
--- pypy/dist/pypy/annotation/builtin.py	(original)
+++ pypy/dist/pypy/annotation/builtin.py	Fri Feb 10 17:54:16 2006
@@ -9,7 +9,7 @@
 from pypy.annotation.model import SomeFloat, unionof
 from pypy.annotation.model import SomePBC, SomeInstance, SomeDict
 from pypy.annotation.model import SomeExternalObject
-from pypy.annotation.model import annotation_to_lltype, lltype_to_annotation
+from pypy.annotation.model import annotation_to_lltype, lltype_to_annotation, ll_to_annotation
 from pypy.annotation.model import add_knowntypedata
 from pypy.annotation.model import s_ImpossibleValue
 from pypy.annotation.bookkeeper import getbookkeeper
@@ -404,6 +404,10 @@
     lltype = annotation_to_lltype(s_val, info="in typeOf(): ")
     return immutablevalue(lltype)
 
+def cast_primitive(T, s_v):
+    assert T.is_constant()
+    return ll_to_annotation(lltype.cast_primitive(T.const, annotation_to_lltype(s_v)._defl()))
+
 def nullptr(T):
     assert T.is_constant()
     p = lltype.nullptr(T.const)
@@ -428,6 +432,7 @@
 
 BUILTIN_ANALYZERS[lltype.malloc] = malloc
 BUILTIN_ANALYZERS[lltype.typeOf] = typeOf
+BUILTIN_ANALYZERS[lltype.cast_primitive] = cast_primitive
 BUILTIN_ANALYZERS[lltype.nullptr] = nullptr
 BUILTIN_ANALYZERS[lltype.cast_pointer] = cast_pointer
 BUILTIN_ANALYZERS[lltype.cast_ptr_to_int] = cast_ptr_to_int

Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py	Fri Feb 10 17:54:16 2006
@@ -508,6 +508,31 @@
             return val.lltype()
         raise TypeError("typeOf(%r object)" % (tp.__name__,))
 
+_to_primitive = {
+    Signed: int,
+    Unsigned: r_uint,
+    Float: float,
+    Char: chr,
+    UniChar: unichr,
+    Bool: bool,
+}
+
+def cast_primitive(TGT, value):
+    ORIG = typeOf(value)
+    if not isinstance(TGT, Primitive) or not isinstance(ORIG, Primitive):
+        raise TypeError, "can only primitive to primitive"
+    if ORIG == TGT:
+        return value
+    if ORIG == Char or ORIG == UniChar:
+        value = ord(value)
+    elif ORIG == Float:
+        value = long(value)
+    cast = _to_primitive.get(TGT)
+    if cast is None:
+        raise TypeError, "unsupported cast"
+    return cast(value)
+ 
+
 class InvalidCast(TypeError):
     pass
 

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py	Fri Feb 10 17:54:16 2006
@@ -491,3 +491,20 @@
 
     assert S == Sprime
 
+def test_cast_primitive():
+    cases = [
+        (Float, 1, 1.0),
+        (Signed, 1.0, 1),
+        (Unsigned, 1.0, 1),
+        (Signed, r_uint(-1), -1),
+        (Unsigned, -1, r_uint(-1)),
+        (Char, ord('a'), 'a'),
+        (Char, False,  chr(0)),
+        (Signed, 'x', ord('x')),
+        (Unsigned, u"x", ord(u'x')),
+    ]
+    for TGT, orig_val, expect in cases:
+         res = cast_primitive(TGT, orig_val)
+         assert typeOf(res) == TGT
+         assert res == expect
+        

Modified: pypy/dist/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/rbuiltin.py	(original)
+++ pypy/dist/pypy/rpython/rbuiltin.py	Fri Feb 10 17:54:16 2006
@@ -5,7 +5,8 @@
 from pypy.rpython import rarithmetic, objectmodel, rstack, rint, raddress
 from pypy.rpython.error import TyperError
 from pypy.rpython.rmodel import Repr, IntegerRepr
-from pypy.rpython.rrange import rtype_builtin_range, rtype_builtin_xrange 
+from pypy.rpython.rrange import rtype_builtin_range, rtype_builtin_xrange
+from pypy.rpython import rstr
 from pypy.rpython import rptr
 from pypy.rpython.robject import pyobj_repr
 from pypy.rpython.rdict import rtype_r_dict
@@ -38,7 +39,7 @@
             # rtype_method_xxx() will read from that hop.args_s[0].
             # See test_method_join in test_rbuiltin.
             # There is no problem with self.s_self being garbage-collected and
-            # its id reused, because the BuiltinMethodRepr keeps a reference
+            # its id reused, because the BuiltinMethodepr keeps a reference
             # to it.
             return (self.__class__, self.methodname, id(self.s_self))
 
@@ -294,6 +295,25 @@
     return hop.genop('cast_pointer', [v_input],    # v_type implicit in r_result
                      resulttype = hop.r_result.lowleveltype)
 
+def rtype_cast_primitive(hop):
+    assert hop.args_s[0].is_constant()
+    TGT = hop.args_s[0].const
+    # we don't want these as automatic conversions, so:
+    if TGT == lltype.Char:
+        hop2 = hop.copy()
+        hop2.r_s_popfirstarg()
+        return hop2.args_r[0].rtype_chr(hop2)
+    elif TGT == lltype.UniChar:
+        hop2 = hop.copy()
+        hop2.r_s_popfirstarg()
+        return hop2.args_r[0].rtype_unichr(hop2)
+    elif hop.args_r[1] in (rstr.char_repr, rstr.unichar_repr):
+        hop2 = hop.copy()
+        hop2.r_s_popfirstarg()
+        v = hop2.args_r[0].rtype_ord(hop2)
+        return hop.llops.convertvar(v, rint.signed_repr, hop.r_result)
+    return hop.inputarg(TGT, 1)
+
 def rtype_cast_ptr_to_int(hop):
     assert isinstance(hop.args_r[0], rptr.PtrRepr)
     vlist = hop.inputargs(hop.args_r[0])
@@ -307,6 +327,7 @@
                  resulttype = rptr.PtrRepr(lltype.Ptr(lltype.RuntimeTypeInfo)))
 
 BUILTIN_TYPER[lltype.malloc] = rtype_malloc
+BUILTIN_TYPER[lltype.cast_primitive] = rtype_cast_primitive
 BUILTIN_TYPER[lltype.cast_pointer] = rtype_cast_pointer
 BUILTIN_TYPER[lltype.cast_ptr_to_int] = rtype_cast_ptr_to_int
 BUILTIN_TYPER[lltype.typeOf] = rtype_const_result

Modified: pypy/dist/pypy/rpython/test/test_llann.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_llann.py	(original)
+++ pypy/dist/pypy/rpython/test/test_llann.py	Fri Feb 10 17:54:16 2006
@@ -287,3 +287,14 @@
         assert isinstance(s, annmodel.SomePtr)
         assert s.ll_ptrtype == Ptr(RuntimeTypeInfo)
         
+    def test_cast_primitive(self):
+        def llf(u):
+            return cast_primitive(Signed, u)
+        s = self.annotate(llf, [annmodel.SomeInteger(unsigned=True)])
+        assert s.knowntype == int
+        def llf(s):
+            return cast_primitive(Unsigned, s)
+        s = self.annotate(llf, [annmodel.SomeInteger()])
+        assert s.unsigned == True
+
+ 

Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rbuiltin.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rbuiltin.py	Fri Feb 10 17:54:16 2006
@@ -296,3 +296,31 @@
 
     res = interpret(f, [r_uint(5)])
     assert type(res) is int and res == 5
+
+def test_cast_primitive():
+    from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy
+    def llf(u):
+        return lltype.cast_primitive(lltype.Signed, u)
+    res = interpret(llf, [r_uint(-1)], policy=LowLevelAnnotatorPolicy())
+    assert res == -1
+    res = interpret(llf, ['x'], policy=LowLevelAnnotatorPolicy())
+    assert res == ord('x')
+    def llf(v):
+        return lltype.cast_primitive(lltype.Unsigned, v)
+    res = interpret(llf, [-1], policy=LowLevelAnnotatorPolicy())
+    assert res == r_uint(-1)
+    res = interpret(llf, [u'x'], policy=LowLevelAnnotatorPolicy())
+    assert res == ord(u'x')
+    res = interpret(llf, [1.0], policy=LowLevelAnnotatorPolicy())
+    assert res == r_uint(1)
+    def llf(v):
+        return lltype.cast_primitive(lltype.Char, v)
+    res = interpret(llf, [ord('x')], policy=LowLevelAnnotatorPolicy())
+    assert res == 'x'
+    def llf(v):
+        return lltype.cast_primitive(lltype.UniChar, v)
+    res = interpret(llf, [ord('x')], policy=LowLevelAnnotatorPolicy())
+    assert res == u'x'
+ 
+    
+ 



More information about the Pypy-commit mailing list