[pypy-svn] r13720 - in pypy/dist/pypy/rpython: . test
hpk at codespeak.net
hpk at codespeak.net
Thu Jun 23 16:41:40 CEST 2005
Author: hpk
Date: Thu Jun 23 16:41:39 2005
New Revision: 13720
Added:
pypy/dist/pypy/rpython/rdict.py (contents, props changed)
pypy/dist/pypy/rpython/test/test_rdict.py (contents, props changed)
Modified:
pypy/dist/pypy/rpython/rtyper.py
Log:
(hpk,arre,arigo)
added machinery for rdict's which at the moment
can only process exactly one key-value mapping.
Added: pypy/dist/pypy/rpython/rdict.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/rdict.py Thu Jun 23 16:41:39 2005
@@ -0,0 +1,183 @@
+from pypy.annotation.pairtype import pairtype
+from pypy.annotation import model as annmodel
+from pypy.objspace.flow.model import Constant
+from pypy.rpython import rmodel, lltype
+from pypy.rpython.rstr import STR, string_repr, ll_strhash
+
+# ____________________________________________________________
+#
+# pseudo implementation of RPython dictionary (this is per
+# dictvalue type):
+#
+# struct dictentry {
+# struct STR *key;
+# ### XXX? int state;
+# DICTVALUE value;
+# }
+#
+# struct dicttable {
+# int num_used_entries;
+# Array *entries;
+# }
+#
+#
+
+class __extend__(annmodel.SomeDict):
+ def rtyper_makerepr(self, rtyper):
+ s_key = self.dictdef.dictkey.s_value
+ if isinstance(s_key, annmodel.SomeString):
+ dictvalue = self.dictdef.dictvalue
+ return StrDictRepr(lambda: rtyper.getrepr(dictvalue.s_value),
+ dictvalue)
+ else:
+ raise rmodel.TyperError("cannot make repr of %r" %(self.dictdef,))
+
+ def rtyper_makekey(self):
+ return (self.dictdef.dictkey, self.dictdef.dictvalue)
+
+class StrDictRepr(rmodel.Repr):
+
+ def __init__(self, value_repr, dictvalue=None):
+ self.STRDICT = lltype.GcForwardReference()
+ self.lowleveltype = lltype.Ptr(self.STRDICT)
+ if not isinstance(value_repr, rmodel.Repr): # not computed yet, done by setup()
+ assert callable(value_repr)
+ self._value_repr_computer = value_repr
+ else:
+ self.value_repr = value_repr
+ self.dictvalue = dictvalue
+ #self.dict_cache = {}
+ # setup() needs to be called to finish this initialization
+
+ def setup(self):
+ if 'value_repr' not in self.__dict__:
+ self.value_repr = self._value_repr_computer()
+ if isinstance(self.STRDICT, lltype.GcForwardReference):
+ self.DICTVALUE = self.value_repr.lowleveltype
+ self.DICTENTRY = lltype.Struct("dictentry", ("key", lltype.Ptr(STR)),
+ ('value', self.DICTVALUE))
+ self.DICTENTRYARRAY = lltype.GcArray(self.DICTENTRY)
+ self.STRDICT.become(lltype.GcStruct("dicttable",
+ ("num_used_entries", lltype.Signed),
+ ("entries", lltype.Ptr(self.DICTENTRYARRAY))))
+
+ #def convert_const(self, dictobj):
+ # dictobj = getattr(dictobj, '__self__', dictobj) # for bound list methods
+ # if not isinstance(dictobj, list):
+ # raise TyperError("expected a list: %r" % (dictobj,))
+ # try:
+ # key = Constant(dictobj)
+ # return self.list_cache[key]
+ # except KeyError:
+ # self.setup()
+ # result = malloc(self.STRDICT, immortal=True)
+ # self.list_cache[key] = result
+ # result.items = malloc(self.STRDICT.items.TO, len(dictobj))
+ # r_item = self.value_repr
+ # for i in range(len(dictobj)):
+ # x = dictobj[i]
+ # result.items[i] = r_item.convert_const(x)
+ # return result
+
+ #def rtype_len(self, hop):
+ # v_lst, = hop.inputargs(self)
+ # return hop.gendirectcall(ll_len, v_lst)
+
+class __extend__(pairtype(StrDictRepr, rmodel.StringRepr)):
+
+ def rtype_getitem((r_dict, r_string), hop):
+ v_dict, v_key = hop.inputargs(r_dict, string_repr)
+ return hop.gendirectcall(ll_strdict_getitem, v_dict, v_key)
+
+ def rtype_setitem((r_dict, r_string), hop):
+ v_dict, v_key, v_value = hop.inputargs(r_dict, string_repr, r_dict.value_repr)
+ hop.gendirectcall(ll_strdict_setitem, v_dict, v_key, v_value)
+
+class __extend__(pairtype(StrDictRepr, StrDictRepr)):
+ def convert_from_to((r_dict1, r_dict2), v, llops):
+ # check that we don't convert from StrDicts with
+ # different value types
+ if r_dict1.dictvalue is None or r_dict2.dictvalue is None:
+ return NotImplemented
+ if r_dict1.dictvalue is not r_dict2.dictvalue:
+ return NotImplemented
+ return v
+
+ #def rtype_add((self, _), hop):
+ # v_lst1, v_lst2 = hop.inputargs(self, self)
+ # return hop.gendirectcall(ll_concat, v_lst1, v_lst2)
+#
+# def rtype_inplace_add((self, _), hop):
+# v_lst1, v_lst2 = hop.inputargs(self, self)
+# hop.gendirectcall(ll_extend, v_lst1, v_lst2)
+# return v_lst1
+
+# ____________________________________________________________
+#
+# Low-level methods. These can be run for testing, but are meant to
+# be direct_call'ed from rtyped flow graphs, which means that they will
+# get flowed and annotated, mostly with SomePtr.
+
+def ll_strdict_len(d):
+ return d.num_used_entries
+
+def ll_strdict_getitem(d, key):
+ return d.entries[0].value
+
+def ll_strdict_setitem(d, key, value):
+ d.entries[0].key = key
+ d.entries[0].value = value
+
+# ____________________________________________________________
+#
+# Irregular operations.
+
+def ll_newstrdict(DICTPTR):
+ d = lltype.malloc(DICTPTR.TO)
+ d.entries = lltype.malloc(DICTPTR.TO.entries.TO, 8) # everything is zeroed
+ d.num_used_entries = 0 # but still be explicit
+ return d
+
+def rtype_newdict(hop):
+ r_dict = hop.r_result
+ if not isinstance(r_dict, StrDictRepr):
+ raise rmodel.TyperError("cannot create non-StrDicts, got %r" %(r_dict,))
+ c1 = hop.inputconst(lltype.Void, r_dict.lowleveltype)
+ v_result = hop.gendirectcall(ll_newstrdict, c1)
+ return v_result
+
+# ____________________________________________________________
+#
+# Iteration.
+
+if 0:
+ class ListIteratorRepr(Repr):
+
+ def __init__(self, r_list):
+ self.r_list = r_list
+ self.lowleveltype = lltype.Ptr(GcStruct('listiter',
+ ('list', r_list.lowleveltype),
+ ('index', Signed)))
+
+ def newiter(self, hop):
+ v_lst, = hop.inputargs(self.r_list)
+ citerptr = hop.inputconst(Void, self.lowleveltype)
+ return hop.gendirectcall(ll_listiter, citerptr, v_lst)
+
+ def rtype_next(self, hop):
+ v_iter, = hop.inputargs(self)
+ return hop.gendirectcall(ll_listnext, v_iter)
+
+ def ll_listiter(ITERPTR, lst):
+ iter = malloc(ITERPTR.TO)
+ iter.list = lst
+ iter.index = 0
+ return iter
+
+ def ll_listnext(iter):
+ l = iter.list
+ index = iter.index
+ if index >= len(l.items):
+ raise StopIteration
+ iter.index = index + 1
+ return l.items[index]
Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py (original)
+++ pypy/dist/pypy/rpython/rtyper.py Thu Jun 23 16:41:39 2005
@@ -329,6 +329,9 @@
def translate_op_newlist(self, hop):
return rlist.rtype_newlist(hop)
+ def translate_op_newdict(self, hop):
+ return rdict.rtype_newdict(hop)
+
def translate_op_alloc_and_set(self, hop):
return rlist.rtype_alloc_and_set(hop)
@@ -526,6 +529,6 @@
from pypy.rpython import robject
from pypy.rpython import rint, rbool, rfloat
from pypy.rpython import rslice
-from pypy.rpython import rlist, rstr, rtuple
+from pypy.rpython import rlist, rstr, rtuple, rdict
from pypy.rpython import rclass, rbuiltin, rpbc
from pypy.rpython import rptr
Added: pypy/dist/pypy/rpython/test/test_rdict.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/test/test_rdict.py Thu Jun 23 16:41:39 2005
@@ -0,0 +1,13 @@
+
+from pypy.rpython import lltype
+from pypy.rpython.test.test_llinterp import interpret
+
+import py
+
+def test_dict_creation():
+ def createdict(i):
+ d = {'hello' : i}
+ return d['hello']
+
+ res = interpret(createdict, [42])
+ assert res == 42
More information about the Pypy-commit
mailing list