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

pedronis at codespeak.net pedronis at codespeak.net
Thu Jun 9 20:26:56 CEST 2005


Author: pedronis
Date: Thu Jun  9 20:26:52 2005
New Revision: 13238

Modified:
   pypy/dist/pypy/annotation/binaryop.py
   pypy/dist/pypy/rpython/lltype.py
   pypy/dist/pypy/rpython/test/test_llann.py
   pypy/dist/pypy/rpython/test/test_lltype.py
Log:
support in lltype and annotation for low-level arrays of non-container types



Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py	(original)
+++ pypy/dist/pypy/annotation/binaryop.py	Thu Jun  9 20:26:52 2005
@@ -519,7 +519,7 @@
         return SomeImpossibleValue()
 
 # annotation of low-level types
-from pypy.annotation.model import SomePtr, ll_to_annotation
+from pypy.annotation.model import SomePtr, ll_to_annotation, annotation_to_lltype
 
 class __extend__(pairtype(SomePtr, SomePtr)):
     def union((p1, p2)):
@@ -533,6 +533,10 @@
         v = p.ll_ptrtype._example()[0]
         return ll_to_annotation(v)
 
+    def setitem((p, int1), s_value):
+        v_lltype = annotation_to_lltype(s_value)
+        p.ll_ptrtype._example()[0] = v_lltype._defl()
+
 class __extend__(pairtype(SomePtr, SomeObject)):
     def union((p, obj)):
         assert False, ("mixing pointer type %r with something else %r" % (p.ll_ptrtype, obj))
@@ -541,7 +545,7 @@
         assert False,"ptr %r getitem index not an int: %r" % (p.ll_ptrtype, obj)
 
     def settitem((p, obj)):
-        assert False,"ptr setitem is not a valid operation"
+        assert False,"ptr setitem with index is not a valid operation"
 
 class __extend__(pairtype(SomeObject, SomePtr)):
     def union((obj, p2)):

Modified: pypy/dist/pypy/rpython/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltype.py	(original)
+++ pypy/dist/pypy/rpython/lltype.py	Thu Jun  9 20:26:52 2005
@@ -113,7 +113,7 @@
     def _inline_is_varsize(self, last):
         if self._arrayfld:
             raise TypeError("cannot inline a var-sized struct "
-                            "inside another struct")
+                            "inside another container")
         return False
 
     def __getattr__(self, name):
@@ -147,19 +147,37 @@
 
 class Array(ContainerType):
     __name__ = 'array'
+    _anonym_struct = False
+    
     def __init__(self, *fields):
-        self.OF = Struct("<arrayitem>", *fields)
-        if self.OF._arrayfld is not None:
-            raise TypeError("array cannot contain an inlined array")
+        if len(fields) == 1 and isinstance(fields[0], LowLevelType):
+            self.OF = fields[0]
+        else:
+            self.OF = Struct("<arrayitem>", *fields)
+            self._anonym_struct = True
+        if isinstance(self.OF, GcStruct):
+            raise TypeError("cannot have a GC structure as array item type")
+        self.OF._inline_is_varsize(False)
 
     def _inline_is_varsize(self, last):
         if not last:
-            raise TypeError("array field must be last")
+            raise TypeError("cannot inline an array in another container"
+                            " unless as the last field of a structure")
         return True
 
+    def _str_fields(self):
+        if isinstance(self.OF, Struct):
+            of = self.OF
+            if self._anonym_struct:
+                return "{ %s }" % of._str_fields()
+            else:
+                return "%s { %s }" % (of._name, of._str_fields())
+        else:
+            return self.OF
+
     def __str__(self):
-        return "%s of { %s }" % (self.__class__.__name__,
-                                 self.OF._str_fields(),)
+        return "%s of %s " % (self.__class__.__name__,
+                               self._str_fields(),)
 
     def _container_example(self):
         return _array(self, 1)
@@ -430,7 +448,18 @@
 
     def __setitem__(self, i, val): # ! not allowed !
         if isinstance(self._T, Array):
-            raise TypeError("cannot directly assign to array items")
+            T1 = self._T.OF
+            if isinstance(T1, ContainerType):
+                raise TypeError("cannot directly assign to container array items")
+            T2 = typeOf(val)
+            if T2 != T1:
+                    raise TypeError("%r items:\n"
+                                    "expect %r\n"
+                                    "   got %r" % (self._T, T1, T2))                
+            if not (0 <= i < len(self._obj.items)):
+                raise IndexError("array index out of bounds")
+            self._obj.items[i] = val
+            return
         raise TypeError("%r instance is not an array" % (self._T,))
 
     def __len__(self):
@@ -539,8 +568,18 @@
     def __repr__(self):
         return '<%s>' % (self,)
 
+    def _str_item(self, item):
+        if isinstance(self._TYPE.OF, Struct):
+            of = self._TYPE.OF
+            if self._TYPE._anonym_struct:
+                return "{%s}" % item._str_fields()
+            else:
+                return "%s {%s}" % (of._name, item._str_fields())
+        else:
+            return item
+
     def __str__(self):
-        return 'array [ %s ]' % (', '.join(['{%s}' % item._str_fields()
+        return 'array [ %s ]' % (', '.join(['%s' % self._str_item(item)
                                             for item in self.items]),)
 
 class _func(object):

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	Thu Jun  9 20:26:52 2005
@@ -34,6 +34,25 @@
         a = self.RPythonAnnotator()
         s = a.build_types(llf, [])
         assert s.knowntype == int
+
+    def test_prim_array(self):
+        A = GcArray(Signed)
+        def llf():
+            a = malloc(A, 1)
+            return a[0]
+        a = self.RPythonAnnotator()
+        s = a.build_types(llf, [])
+        assert s.knowntype == int
+
+    def test_prim_array_setitem(self):
+        A = GcArray(Signed)
+        def llf():
+            a = malloc(A, 1)
+            a[0] = 3
+            return a[0]
+        a = self.RPythonAnnotator()
+        s = a.build_types(llf, [])
+        assert s.knowntype == int        
         
     def test_cast_parent(self):
         S2 = Struct("s2", ('a', Signed))

Modified: pypy/dist/pypy/rpython/test/test_lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_lltype.py	(original)
+++ pypy/dist/pypy/rpython/test/test_lltype.py	Thu Jun  9 20:26:52 2005
@@ -250,3 +250,28 @@
     assert S1 == S
     assert S == S1
     assert hash(S1) == hash(S)
+
+def test_array_with_non_container_elements():
+    As = GcArray(Signed)
+    a = malloc(As, 3)
+    assert typeOf(a) == Ptr(As)
+    assert a[0] == 0
+    assert a[1] == 0
+    assert a[2] == 0
+    a[1] = 3
+    assert a[1] == 3
+    S = GcStruct('s', ('x', Signed))
+    s = malloc(S)
+    py.test.raises(TypeError, "a[1] = s")
+    S = GcStruct('s', ('x', Signed))
+    py.test.raises(TypeError, "Array(S)")
+    py.test.raises(TypeError, "Array(As)")
+    S = Struct('s', ('x', Signed))
+    A = Array(S)
+    a = malloc(A, 2)
+    s = S._container_example() # should not happen anyway
+    py.test.raises(TypeError, "a[0] = s")
+    S = Struct('s', ('last', A))
+    py.test.raises(TypeError, "Array(S)")
+    
+    



More information about the Pypy-commit mailing list