[pypy-svn] r48332 - in pypy/branch/pypy-rpython-unicode/rpython: . lltypesystem test
fijal at codespeak.net
fijal at codespeak.net
Tue Nov 6 12:38:03 CET 2007
Author: fijal
Date: Tue Nov 6 12:38:02 2007
New Revision: 48332
Modified:
pypy/branch/pypy-rpython-unicode/rpython/lltypesystem/rstr.py
pypy/branch/pypy-rpython-unicode/rpython/rstr.py
pypy/branch/pypy-rpython-unicode/rpython/test/test_rstr.py
pypy/branch/pypy-rpython-unicode/rpython/test/test_runicode.py
Log:
Some support for unicode strings. This is work in progress, not all tests
are really testing what they should.
Modified: pypy/branch/pypy-rpython-unicode/rpython/lltypesystem/rstr.py
==============================================================================
--- pypy/branch/pypy-rpython-unicode/rpython/lltypesystem/rstr.py (original)
+++ pypy/branch/pypy-rpython-unicode/rpython/lltypesystem/rstr.py Tue Nov 6 12:38:02 2007
@@ -12,7 +12,7 @@
from pypy.rpython.lltypesystem import ll_str
from pypy.rpython.lltypesystem.lltype import \
GcStruct, Signed, Array, Char, UniChar, Ptr, malloc, \
- Bool, Void, GcArray, nullptr, pyobjectptr, cast_primitive
+ Bool, Void, GcArray, nullptr, pyobjectptr, cast_primitive, typeOf
# ____________________________________________________________
@@ -31,6 +31,7 @@
('chars', Array(UniChar, hints={'immutable': True})))
SIGNED_ARRAY = GcArray(Signed)
CONST_STR_CACHE = WeakValueDictionary()
+CONST_UNICODE_CACHE = WeakValueDictionary()
class BaseStringRepr(AbstractStringRepr):
def __init__(self, *args):
@@ -44,20 +45,21 @@
if not isinstance(value, self.basetype):
raise TyperError("not a str: %r" % (value,))
try:
- return CONST_STR_CACHE[value]
+ return self.CACHE[value]
except KeyError:
p = self.malloc(len(value))
for i in range(len(value)):
p.chars[i] = cast_primitive(self.base, value[i])
p.hash = 0
self.ll.ll_strhash(p) # precompute the hash
- CONST_STR_CACHE[value] = p
+ self.CACHE[value] = p
return p
def make_iterator_repr(self):
return string_iterator_repr
def can_ll_be_null(self, s_value):
+ # XXX unicode
if self is string_repr:
return s_value.can_be_none()
else:
@@ -75,6 +77,7 @@
lowleveltype = Ptr(STR)
basetype = str
base = Char
+ CACHE = CONST_STR_CACHE
def __init__(self, *args):
BaseStringRepr.__init__(self, *args)
@@ -84,6 +87,7 @@
lowleveltype = Ptr(UNICODE)
basetype = basestring
base = UniChar
+ CACHE = CONST_UNICODE_CACHE
def __init__(self, *args):
BaseStringRepr.__init__(self, *args)
@@ -163,9 +167,13 @@
class LLHelpers(AbstractLLHelpers):
def ll_char_mul(ch, times):
+ if typeOf(ch) is Char:
+ malloc = mallocstr
+ else:
+ malloc = mallocunicode
if times < 0:
times = 0
- newstr = mallocstr(times)
+ newstr = malloc(times)
j = 0
while j < times:
newstr.chars[j] = ch
@@ -183,7 +191,11 @@
ll_stritem_nonneg._annenforceargs_ = [None, int]
def ll_chr2str(ch):
- s = mallocstr(1)
+ if typeOf(ch) is Char:
+ malloc = mallocstr
+ else:
+ malloc = mallocunicode
+ s = malloc(1)
s.chars[0] = ch
return s
@@ -204,7 +216,12 @@
def ll_strconcat(s1, s2):
len1 = len(s1.chars)
len2 = len(s2.chars)
- newstr = mallocstr(len1 + len2)
+ if typeOf(s1).TO.chars.OF is Char and typeOf(s2).TO.chars.OF is Char:
+ malloc = mallocstr
+ else:
+ malloc = mallocunicode
+
+ newstr = malloc(len1 + len2)
j = 0
while j < len1:
newstr.chars[j] = s1.chars[j]
Modified: pypy/branch/pypy-rpython-unicode/rpython/rstr.py
==============================================================================
--- pypy/branch/pypy-rpython-unicode/rpython/rstr.py (original)
+++ pypy/branch/pypy-rpython-unicode/rpython/rstr.py Tue Nov 6 12:38:02 2007
@@ -47,6 +47,9 @@
class __extend__(AbstractStringRepr):
+ def _str_reprs(self, hop):
+ return hop.args_r[0].repr, hop.args_r[1].repr
+
def get_ll_eq_function(self):
return self.ll.ll_streq
@@ -64,7 +67,7 @@
def rtype_is_true(self, hop):
s_str = hop.args_s[0]
if s_str.can_be_None:
- string_repr = hop.rtyper.type_system.rstr.string_repr
+ string_repr = hop.args_r[0].repr
v_str, = hop.inputargs(string_repr)
return hop.gendirectcall(self.ll.ll_str_is_true, v_str)
else:
@@ -72,25 +75,26 @@
return super(AbstractStringRepr, self).rtype_is_true(hop)
def rtype_ord(self, hop):
- string_repr = hop.rtyper.type_system.rstr.string_repr
+ string_repr = hop.args_r[0].repr
v_str, = hop.inputargs(string_repr)
c_zero = inputconst(Signed, 0)
v_chr = hop.gendirectcall(self.ll.ll_stritem_nonneg, v_str, c_zero)
return hop.genop('cast_char_to_int', [v_chr], resulttype=Signed)
def rtype_method_startswith(self, hop):
- string_repr = hop.rtyper.type_system.rstr.string_repr
- v_str, v_value = hop.inputargs(string_repr, string_repr)
+ str1_repr, str2_repr = self._str_reprs(hop)
+ v_str, v_value = hop.inputargs(str1_repr, str2_repr)
hop.exception_cannot_occur()
return hop.gendirectcall(self.ll.ll_startswith, v_str, v_value)
def rtype_method_endswith(self, hop):
- string_repr = hop.rtyper.type_system.rstr.string_repr
- v_str, v_value = hop.inputargs(string_repr, string_repr)
+ str1_repr, str2_repr = self._str_reprs(hop)
+ v_str, v_value = hop.inputargs(str1_repr, str2_repr)
hop.exception_cannot_occur()
return hop.gendirectcall(self.ll.ll_endswith, v_str, v_value)
def rtype_method_find(self, hop, reverse=False):
+ # XXX binaryop
rstr = hop.rtyper.type_system.rstr
v_str = hop.inputarg(rstr.string_repr, arg=0)
if hop.args_r[1] == rstr.char_repr:
@@ -294,13 +298,20 @@
return hop.gendirectcall(r_str.ll.ll_stringslice_minusone, v_str)
raise TyperError(r_slic)
+def most_general_strrepr(repr1, repr2, rtyper):
+ string_repr = rtyper.type_system.rstr.string_repr
+ if repr1 is string_repr and repr2 is string_repr:
+ return string_repr
+ return rtyper_type_system.rstr.unicode_repr
class __extend__(pairtype(AbstractStringRepr, AbstractStringRepr)):
def rtype_add((r_str1, r_str2), hop):
- string_repr = hop.rtyper.type_system.rstr.string_repr
+ str1_repr = r_str1.repr
+ str2_repr = r_str2.repr
if hop.s_result.is_constant():
- return hop.inputconst(string_repr, hop.s_result.const)
- v_str1, v_str2 = hop.inputargs(string_repr, string_repr)
+ res_repr = most_general_strrepr(str1_repr, str2_repr, hop.rtyper)
+ return hop.inputconst(res_repr, hop.s_result.const)
+ v_str1, v_str2 = hop.inputargs(str1_repr, str2_repr)
return hop.gendirectcall(r_str1.ll.ll_strconcat, v_str1, v_str2)
rtype_inplace_add = rtype_add
Modified: pypy/branch/pypy-rpython-unicode/rpython/test/test_rstr.py
==============================================================================
--- pypy/branch/pypy-rpython-unicode/rpython/test/test_rstr.py (original)
+++ pypy/branch/pypy-rpython-unicode/rpython/test/test_rstr.py Tue Nov 6 12:38:02 2007
@@ -14,26 +14,31 @@
assert parse('%s') == [('s',)]
assert parse("name '%s' is not defined") == ["name '", ("s",), "' is not defined"]
-class BaseTestRstr(BaseRtypingTest):
-
+class AbstractTestRstr(BaseRtypingTest):
def test_simple(self):
+ const = self.const
def fn(i):
- s = 'hello'
+ s = const('hello')
return s[i]
for i in range(5):
res = self.interpret(fn, [i])
- assert res == 'hello'[i]
+ expected = fn(i)
+ assert res == expected
+ assert res.__class__ is expected.__class__
def test_implicit_index_error(self):
+ const = self.const
def fn(i):
- s = 'hello'
+ s = const('hello')
try:
return s[i]
except IndexError:
- return '*'
+ return const('*')
for i in range(-5, 5):
res = self.interpret(fn, [i])
- assert res == 'hello'[i]
+ expected = fn(i)
+ assert res == expected
+ assert res.__class__ is expected.__class__
res = self.interpret(fn, [5])
assert res == '*'
res = self.interpret(fn, [6])
@@ -42,8 +47,9 @@
assert res == '*'
def test_nonzero(self):
+ const = self.const
def fn(i, j):
- s = ['', 'xx'][j]
+ s = [const(''), const('xx')][j]
if i < 0:
s = None
if i > -2:
@@ -56,9 +62,10 @@
assert res is fn(i, j)
def test_concat(self):
+ const = self.const
def fn(i, j):
- s1 = ['', 'a', 'ab']
- s2 = ['', 'x', 'xy']
+ s1 = [const(''), const('a'), const('ab')]
+ s2 = [const(''), const('x'), const('xy')]
return s1[i] + s2[j]
for i in range(3):
for j in range(3):
@@ -779,6 +786,9 @@
res = interpret(g, [-2])
assert res._obj.value == 42
+class BaseTestRstr(AbstractTestRstr):
+ const = str
+
class TestLLtype(BaseTestRstr, LLRtypeMixin):
EMPTY_STRING_HASH = -1
Modified: pypy/branch/pypy-rpython-unicode/rpython/test/test_runicode.py
==============================================================================
--- pypy/branch/pypy-rpython-unicode/rpython/test/test_runicode.py (original)
+++ pypy/branch/pypy-rpython-unicode/rpython/test/test_runicode.py Tue Nov 6 12:38:02 2007
@@ -1,19 +1,12 @@
-from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin
+from pypy.rpython.test.tool import LLRtypeMixin
+from pypy.rpython.test.test_rstr import AbstractTestRstr
-class BaseTestRUnicode(BaseRtypingTest):
- def test_simple(self):
- def f(n):
- if n % 2 == 0:
- x = 'xxx'
- else:
- x = u'x\u221Ex'
- return x[n]
+# ====> test_rstr.py
- for i in range(0, 3):
- res = self.interpret(f, [i])
- assert res == f(i)
+class BaseTestRUnicode(AbstractTestRstr):
+ const = unicode
class TestLLtype(BaseTestRUnicode, LLRtypeMixin):
pass
More information about the Pypy-commit
mailing list