[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