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

nik at codespeak.net nik at codespeak.net
Tue Apr 25 06:48:29 CEST 2006


Author: nik
Date: Tue Apr 25 06:48:23 2006
New Revision: 26287

Added:
   pypy/dist/pypy/rpython/ootypesystem/test/test_ootuple.py   (contents, props changed)
Modified:
   pypy/dist/pypy/rpython/ootypesystem/ootype.py
   pypy/dist/pypy/rpython/ootypesystem/rtuple.py
   pypy/dist/pypy/rpython/ootypesystem/test/test_oolist.py
Log:
(nik, pedronis consulting)
introduce a new low-level type Tuple in ootypesystem. it's to be used for
structure-like things such as tuples and iterators. this will resolve the
recursion and ForwardReference problems that we currently have. these are
mostly caused by the fact that Instances are compared by identity, the new
Tuple type compares by structure. rtyping doesn't yet use the new type
anywhere.


Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/ootype.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/ootype.py	Tue Apr 25 06:48:23 2006
@@ -183,6 +183,40 @@
 
 class BuiltinType(OOType):
 
+    def _example(self):
+        return new(self)
+
+    def _defl(self):
+        return self._null
+
+    def _get_interp_class(self):
+        raise NotImplementedError
+
+class Tuple(BuiltinType):
+    
+    def __init__(self, ITEMTYPES):
+        self._items = frozendict(ITEMTYPES)
+        self._null = _null_tuple(self)
+
+    def _defl(self):
+        return self._null
+
+    def _get_interp_class(self):
+        return _tuple
+
+    def _field_type(self, name):
+        try:
+            return self._items[name]
+        except KeyError:
+            raise TypeError("No field names %r" % name)
+
+    _check_field = _field_type
+
+    def _lookup(self, meth_name):
+        return self, None
+
+class BuiltinADTType(BuiltinType):
+
     def _setup_methods(self, generic_types):
         methods = {}
         for name, meth in self._GENERIC_METHODS.iteritems():
@@ -194,7 +228,7 @@
         self._METHODS = frozendict(methods)
 
     def _specialize_type(self, type_, generic_types):
-        if isinstance(type_, BuiltinType):
+        if isinstance(type_, BuiltinADTType):
             return type_._specialize(generic_types)
         else:
             return generic_types.get(type_, type_)
@@ -210,17 +244,8 @@
             meth = _meth(METH, _name=meth_name, _callable=getattr(cls, meth_name))
         return self, meth
 
-    def _example(self):
-        return new(self)
-
-    def _defl(self):
-        return self._null
 
-    def _get_interp_class(self):
-        raise NotImplementedError
-
-
-class List(BuiltinType):
+class List(BuiltinADTType):
     # placeholders for types
     # make sure that each derived class has his own SELFTYPE_T
     # placeholder, because we want backends to distinguish that.
@@ -276,9 +301,12 @@
     def _specialize(self, generic_types):
         ITEMTYPE = self._specialize_type(self._ITEMTYPE, generic_types)
         return self.__class__(ITEMTYPE)
+    
+    def _defl(self):
+        return self._null
 
 
-class Dict(BuiltinType):
+class Dict(BuiltinADTType):
     # placeholders for types
     SELFTYPE_T = object()
     KEYTYPE_T = object()
@@ -327,7 +355,7 @@
 
 class ForwardReference(OOType):
     def become(self, real_instance):
-        if not isinstance(real_instance, (Instance, BuiltinType)):
+        if not isinstance(real_instance, (Instance, BuiltinADTType)):
             raise TypeError("ForwardReference can only be to an instance, "
                             "not %r" % (real_instance,))
         self.__class__ = real_instance.__class__
@@ -600,7 +628,7 @@
             return meth._bound(TYPE, self)
 
         return object.__getattribute__(self, name)
-    
+
 
 class _list(_builtin_type):
 
@@ -701,6 +729,36 @@
     def __init__(self, DICT):
         self.__dict__["_TYPE"] = DICT
 
+class _tuple(object):
+
+    def __init__(self, TYPE):
+        self._items = {}
+        self._TYPE = TYPE
+        for name, ITEMTYPE in TYPE._items.items():
+            self._items[name] = ITEMTYPE._defl()
+
+    def __getattr__(self, name):
+        items = self.__dict__["_items"]
+        if name in items:
+            return items[name]
+        return self.__dict__[name]
+
+    def __setattr__(self, name, value):
+        if hasattr(self, "_items") and name in self._items:
+            self._items[name] = value
+        else:
+            self.__dict__[name] = value
+
+    def _identityhash(self):
+        if self:
+            return id(self)
+        else:
+            return 0 # for all null tuples
+
+class _null_tuple(_null_mixin(_tuple), _tuple):
+
+    def __init__(self, TUPLE):
+        self.__dict__["_TYPE"] = TUPLE 
 
 def new(TYPE):
     if isinstance(TYPE, Instance):
@@ -776,7 +834,7 @@
     return instance._downcast(INSTANCE)
 
 def ooidentityhash(inst):
-    assert isinstance(typeOf(inst), Instance)
+    assert isinstance(typeOf(inst), (Instance, Tuple))
     return inst._identityhash()
 
 

Modified: pypy/dist/pypy/rpython/ootypesystem/rtuple.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rtuple.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/rtuple.py	Tue Apr 25 06:48:23 2006
@@ -8,6 +8,7 @@
 
     def __init__(self, rtyper, items_r):
         AbstractTupleRepr.__init__(self, rtyper, items_r)
+        #self.lowleveltype = ootype.Tuple(dict(zip(self.fieldnames, self.lltypes)))
         self.lowleveltype = tuple_type(self.fieldnames, self.lltypes)
 
     def newtuple(cls, llops, r_tuple, items_v):

Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oolist.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_oolist.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_oolist.py	Tue Apr 25 06:48:23 2006
@@ -2,6 +2,7 @@
 from pypy.rpython.test.test_llinterp import interpret 
 from pypy.rpython.ootypesystem.ootype import *
 from pypy.rpython.rlist import ll_append
+from pypy.translator.translator import TranslationContext
 
 def test_new():
     LT = List(Signed)
@@ -111,3 +112,27 @@
         res = interpret(f, [3], type_system="ootype")
         assert res == 3 
 
+    def test_initialize(self):
+        def f(x):
+            l = [1, 2]
+            l.append(x)
+            return l[2]
+        res = interpret(f, [3], type_system="ootype")
+        assert res == 3 
+
+    def dont_test_listtype_explosion(self):
+        def f(x):
+            l1 = [x]
+            l2 = [x]
+            return l1, l2 
+        t = TranslationContext()
+        a = t.buildannotator()
+        s = a.build_types(f, [int])
+        typer = t.buildrtyper(type_system="ootype")
+        typer.specialize()
+        
+        s_l1, s_l2 = s.items
+        r_l1 = typer.getrepr(s_l1)
+        r_l2 = typer.getrepr(s_l2)
+        assert r_l1.lowleveltype == r_l2.lowleveltype 
+

Added: pypy/dist/pypy/rpython/ootypesystem/test/test_ootuple.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_ootuple.py	Tue Apr 25 06:48:23 2006
@@ -0,0 +1,40 @@
+from pypy.rpython.ootypesystem.ootype import *
+
+def test_type_comparison():
+    T = Tuple({"a": Signed, "b": Signed})
+    T2 = Tuple({"a": Signed, "b": Signed})
+    T3 = Tuple({"a": Signed, "b": Unsigned})
+
+    assert T == T2
+    assert T2 != T3
+    assert hash(T) == hash(T2)
+
+def test_new():
+    T = Tuple({"a": Signed, "b": Signed})
+    t = new(T)
+    assert t.a == 0
+    assert t.b == 0
+
+def test_getsetitem():
+    T = Tuple({"a": Signed, "b": Signed})
+    t = new(T)
+    t.a = 2
+    t.b = 3
+    assert t.a == 2
+    assert t.b == 3
+
+def test_null():
+    T = Tuple({"a": Signed})
+    n = null(T)
+    n2 = null(T)
+    assert n == n2
+
+def test_ooidentityhash():
+    T = Tuple({"a": Signed, "b": Signed})
+    t = new(T)
+    t.a = 1
+    t.b = 2
+    t2 = new(T)
+    t.a = 1
+    t.b = 2
+    assert ooidentityhash(t) != ooidentityhash(t2)



More information about the Pypy-commit mailing list