[pypy-svn] rev 2219 - in pypy/trunk/src/pypy/translator: . test

arigo at codespeak.net arigo at codespeak.net
Tue Nov 18 14:01:51 CET 2003


Author: arigo
Date: Tue Nov 18 14:01:50 2003
New Revision: 2219

Modified:
   pypy/trunk/src/pypy/translator/annheap.py
   pypy/trunk/src/pypy/translator/annrpython.py
   pypy/trunk/src/pypy/translator/test/snippet.py
   pypy/trunk/src/pypy/translator/test/test_annrpython.py
Log:
Annotations about mutable objects work!
See the new poor_man_rev_range() in snippet.py.  The result is correctly
inferred to be a list of integers.

Hum, powerset fails in test_cltrans.py.  Will investigate.



Modified: pypy/trunk/src/pypy/translator/annheap.py
==============================================================================
--- pypy/trunk/src/pypy/translator/annheap.py	(original)
+++ pypy/trunk/src/pypy/translator/annheap.py	Tue Nov 18 14:01:50 2003
@@ -133,10 +133,7 @@
         self.heap = heap
         self.using_annotations = []  # annotations that we have used
 
-    def get(self, opname, args):
-        """Return the Cell with the annotation 'opname(args) -> Cell',
-        or None if there is no such annotation or several different ones.
-        Hack to generalize: a None in the args matches anything."""
+    def _list_annotations(self, opname, args):
         # patch(arglist) -> arglist with None plugged where
         #                   there is a None in the input 'args'
         def patch(arglist):
@@ -152,6 +149,13 @@
         for ann in self.heap.annlist:
             if ann.opname == opname and patch(ann.args) == args:
                 matchann.append(ann)
+        return matchann
+
+    def get(self, opname, args):
+        """Return the Cell with the annotation 'opname(args) -> Cell',
+        or None if there is no such annotation or several different ones.
+        Hack to generalize: a None in the args matches anything."""
+        matchann = self._list_annotations(opname, args)
         if not matchann:
             return None
         else:
@@ -163,6 +167,11 @@
                 self.using(ann)
             return result
 
+    def delete(self, opname, args):
+        """Kill the annotations 'opname(args) -> *'."""
+        matchann = self._list_annotations(opname, args)
+        self.heap.simplify(kill=matchann)
+
     def set(self, opname, args, result):
         """Put a new annotation into the AnnotationHeap."""
         ann = Annotation(opname, args, result)

Modified: pypy/trunk/src/pypy/translator/annrpython.py
==============================================================================
--- pypy/trunk/src/pypy/translator/annrpython.py	(original)
+++ pypy/trunk/src/pypy/translator/annrpython.py	Tue Nov 18 14:01:50 2003
@@ -16,6 +16,12 @@
         self.pendingblocks = []  # list of (block, list-of-XCells)
         self.bindings = {}       # map Variables/Constants to XCells/XConstants
         self.annotated = {}      # set of blocks already seen
+        # build default annotations
+        t = self.transaction()
+        self.any_immutable = XCell()
+        t.set('immutable', [], self.any_immutable)
+        self.any_int = XCell()
+        t.set_type(self.any_int, int)
 
 
     #___ convenience high-level interface __________________
@@ -156,8 +162,28 @@
             t.set_type(result, str)
         if type1 is list and type2 is list:
             t.set_type(result, list)
+            # XXX propagate information about the type of the elements
 
-    consider_op_inplace_add = consider_op_add
+    def consider_op_inplace_add(self, (arg1,arg2), result, t):
+        type1 = t.get_type(arg1)
+        type2 = t.get_type(arg1)
+        if type1 is list and type2 is list:
+            # Annotations about the items of arg2 are merged with the ones about
+            # the items of arg1.  arg2 is not modified during this operation.
+            # result is arg1.
+            result.share(arg1)
+            t.delete('len', [arg1])
+            item1 = t.get('getitem', [arg1, None])
+            if item1 is not None:
+                item2 = t.get('getitem', [arg2, None])
+                if item2 is None:
+                    item2 = XCell()   # anything at all
+                item3 = self.heap.merge(item1, item2)
+                if item3 != item1:
+                    t.delete('getitem', [arg1, None])
+                    t.set('getitem', [arg1, self.any_int], item3)
+        else:
+            self.consider_op_add((arg1,arg2), result, t)
 
     def consider_op_sub(self, (arg1,arg2), result, t):
         type1 = t.get_type(arg1)
@@ -192,6 +218,11 @@
 
     def consider_op_newlist(self, args, result, t):
         t.set_type(result, list)
+        t.set("len", [result], self.constant(len(args)))
+        item_cell = nothingyet
+        for a in args:
+            item_cell = self.heap.merge(item_cell, a)
+        t.set("getitem", [result, self.any_int], item_cell)
 
     def consider_op_newslice(self, args, result, t):
         t.set_type(result, slice)
@@ -219,9 +250,7 @@
         t = self.transaction()
         t.set('immutable', [], to_var)
         t.set_type(to_var,type(const.value))
-        if isinstance(const.value, list):
-            pass # XXX say something about the type of the elements
-        elif isinstance(const.value, tuple):
+        if isinstance(const.value, tuple):
             pass # XXX say something about the elements
 
 

Modified: pypy/trunk/src/pypy/translator/test/snippet.py
==============================================================================
--- pypy/trunk/src/pypy/translator/test/snippet.py	(original)
+++ pypy/trunk/src/pypy/translator/test/snippet.py	Tue Nov 18 14:01:50 2003
@@ -105,6 +105,13 @@
     lst.reverse()
     return lst
 
+def poor_man_rev_range(i):
+    lst = []
+    while i > 0:
+        i = i - 1
+        lst += [i]
+    return lst
+
 def simple_id(x):
     return x
 

Modified: pypy/trunk/src/pypy/translator/test/test_annrpython.py
==============================================================================
--- pypy/trunk/src/pypy/translator/test/test_annrpython.py	(original)
+++ pypy/trunk/src/pypy/translator/test/test_annrpython.py	Tue Nov 18 14:01:50 2003
@@ -6,6 +6,8 @@
 from pypy.translator.annrpython import RPythonAnnotator
 from pypy.objspace.flow.model import *
 
+from pypy.translator.test import snippet
+
 class AnnonateTestCase(test.IntTestCase):
     def setUp(self):
         self.space = test.objspace('flow')
@@ -109,12 +111,26 @@
         end_cell = a.binding(fun.getreturnvar())
         self.assertEquals(a.transaction().get_type(end_cell), int)
 
-    def test_simplify_calls(self):
-        fun = self.make_fun(f_calls_g)
+    #def test_simplify_calls(self):
+    #    fun = self.make_fun(f_calls_g)
+    #    a = RPythonAnnotator()
+    #    a.build_types(fun, [int])
+    #    a.simplify_calls()
+    #    #self.reallyshow(fun)
+    # XXX write test_transform.py
+
+    def test_lists(self):
+        fun = self.make_fun(snippet.poor_man_rev_range)
         a = RPythonAnnotator()
         a.build_types(fun, [int])
-        a.simplify_calls()
-        #self.reallyshow(fun)
+        # result should be a list of integers
+        t = a.transaction()
+        end_cell = a.binding(fun.getreturnvar())
+        self.assertEquals(t.get_type(end_cell), list)
+        item_cell = t.get('getitem', [end_cell, None])
+        self.failIf(item_cell is None)
+        self.assertEquals(t.get_type(item_cell), int)
+
 
 def g(n):
     return [0,1,2,n]


More information about the Pypy-commit mailing list