[pypy-svn] r27271 - in pypy/dist/pypy: annotation rpython rpython/lltypesystem rpython/ootypesystem rpython/test
antocuni at codespeak.net
antocuni at codespeak.net
Tue May 16 14:12:32 CEST 2006
Author: antocuni
Date: Tue May 16 14:12:17 2006
New Revision: 27271
Modified:
pypy/dist/pypy/annotation/builtin.py
pypy/dist/pypy/rpython/llinterp.py
pypy/dist/pypy/rpython/lltypesystem/rstr.py
pypy/dist/pypy/rpython/ootypesystem/ootype.py
pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py
pypy/dist/pypy/rpython/ootypesystem/rclass.py
pypy/dist/pypy/rpython/ootypesystem/rlist.py
pypy/dist/pypy/rpython/ootypesystem/rstr.py
pypy/dist/pypy/rpython/rstr.py
pypy/dist/pypy/rpython/test/test_rstr.py
Log:
Added support for string formatting in ootypesystem.
Modified: pypy/dist/pypy/annotation/builtin.py
==============================================================================
--- pypy/dist/pypy/annotation/builtin.py (original)
+++ pypy/dist/pypy/annotation/builtin.py Tue May 16 14:12:17 2006
@@ -521,9 +521,9 @@
assert isinstance(i, SomeOOInstance)
return SomeInteger()
-def oostring(obj):
- assert (isinstance(obj, (SomeInteger, SomeChar)) or
- isinstance(obj, SomeOOInstance) and obj.ootype is ootype.String)
+def oostring(obj, base):
+ assert isinstance(obj, (SomeInteger, SomeChar, SomeOOInstance))
+ assert isinstance(base, SomeInteger)
return SomeOOInstance(ootype.String)
BUILTIN_ANALYZERS[ootype.instanceof] = instanceof
Modified: pypy/dist/pypy/rpython/llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/llinterp.py (original)
+++ pypy/dist/pypy/rpython/llinterp.py Tue May 16 14:12:17 2006
@@ -1020,8 +1020,8 @@
def op_ooidentityhash(self, inst):
return ootype.ooidentityhash(inst)
- def op_oostring(self, obj):
- return ootype.oostring(obj)
+ def op_oostring(self, obj, base):
+ return ootype.oostring(obj, base)
class Tracer(object):
Counter = 0
Modified: pypy/dist/pypy/rpython/lltypesystem/rstr.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rstr.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/rstr.py Tue May 16 14:12:17 2006
@@ -648,31 +648,6 @@
return hop.gendirectcall(cls.ll_join_strs, size, vtemp)
do_stringformat = classmethod(do_stringformat)
- def parse_fmt_string(fmt):
- # we support x, d, s, f, [r]
-
- it = iter(fmt)
- r = []
- curstr = ''
- for c in it:
- if c == '%':
- f = it.next()
- if f == '%':
- curstr += '%'
- continue
-
- if curstr:
- r.append(curstr)
- curstr = ''
- if f not in 'xdosrf':
- raise TyperError("Unsupported formatting specifier: %r in %r" % (f, fmt))
-
- r.append((f,))
- else:
- curstr += c
- if curstr:
- r.append(curstr)
- return r
Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Tue May 16 14:12:17 2006
@@ -1142,8 +1142,20 @@
assert isinstance(typeOf(inst), (Instance, Record))
return inst._identityhash()
-def oostring(obj):
- "Convert char, int and str to str"
+def oostring(obj, base):
+ """
+ Convert char, int, float, instances and str to str.
+
+ Base is used only for formatting int: for other types is ignored
+ and should be set to -1. For int only base 8, 10 and 16 are
+ supported.
+ """
+ if isinstance(obj, int):
+ assert base in (-1, 8, 10, 16)
+ fmt = {-1:'%d', 8:'%o', 10:'%d', 16:'%x'}[base]
+ obj = fmt % obj
+ elif isinstance(obj, _view):
+ obj = '<%s object>' % obj._inst._TYPE._name
return make_string(str(obj))
def setItemType(LIST, ITEMTYPE):
Modified: pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py Tue May 16 14:12:17 2006
@@ -60,7 +60,9 @@
def rtype_oostring(hop):
assert isinstance(hop.args_s[0],(annmodel.SomeInteger,
annmodel.SomeChar,
- annmodel.SomeString))
+ annmodel.SomeString,
+ annmodel.SomeOOInstance))
+ assert isinstance(hop.args_s[1], annmodel.SomeInteger)
return hop.genop('oostring', hop.args_v, resulttype = ootype.String)
Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Tue May 16 14:12:17 2006
@@ -379,6 +379,13 @@
vinst, = hop.inputargs(self)
return hop.genop('oononnull', [vinst], resulttype=ootype.Bool)
+ def ll_const(c):
+ return c
+ ll_const = staticmethod(ll_const)
+
+ def ll_str(self, instance):
+ return ootype.oostring(instance, self.ll_const(-1))
+
def rtype_type(self, hop):
vinst, = hop.inputargs(self)
if hop.args_s[0].can_be_none():
Modified: pypy/dist/pypy/rpython/ootypesystem/rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rlist.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/rlist.py Tue May 16 14:12:17 2006
@@ -39,7 +39,6 @@
result = self.LIST.ll_newlist(n)
return result
-
def send_message(self, hop, message, can_raise=False, v_args=None):
if v_args is None:
v_args = hop.inputargs(self, *hop.args_r[1:])
Modified: pypy/dist/pypy/rpython/ootypesystem/rstr.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rstr.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/rstr.py Tue May 16 14:12:17 2006
@@ -2,6 +2,7 @@
from pypy.rpython.rstr import AbstractStringRepr,AbstractCharRepr,\
AbstractUniCharRepr, AbstractStringIteratorRepr,\
AbstractLLHelpers
+from pypy.rpython.rmodel import IntegerRepr
from pypy.rpython.lltypesystem.lltype import Ptr, Char, UniChar
from pypy.rpython.ootypesystem import ootype
@@ -60,8 +61,11 @@
class LLHelpers(AbstractLLHelpers):
+ def ll_const(c):
+ return c
+
def ll_chr2str(ch):
- return ootype.oostring(ch)
+ return ootype.oostring(ch, LLHelpers.ll_const(-1))
def ll_char_mul(ch, times):
buf = ootype.new(ootype.StringBuilder)
@@ -143,6 +147,59 @@
def ll_stringslice_minusone(s):
return s.ll_substring(0, s.ll_strlen()-1)
+ def do_stringformat(cls, hop, sourcevarsrepr):
+ InstanceRepr = hop.rtyper.type_system.rclass.InstanceRepr
+ string_repr = hop.rtyper.type_system.rstr.string_repr
+ s_str = hop.args_s[0]
+ assert s_str.is_constant()
+ s = s_str.const
+
+ c_append = hop.inputconst(ootype.Void, 'll_append')
+ c_build = hop.inputconst(ootype.Void, 'll_build')
+ cm1 = hop.inputconst(ootype.Signed, -1)
+ c8 = hop.inputconst(ootype.Signed, 8)
+ c10 = hop.inputconst(ootype.Signed, 10)
+ c16 = hop.inputconst(ootype.Signed, 16)
+ c_StringBuilder = hop.inputconst(ootype.Void, ootype.StringBuilder)
+ v_buf = hop.genop("new", [c_StringBuilder], resulttype=ootype.StringBuilder)
+
+ things = cls.parse_fmt_string(s)
+ argsiter = iter(sourcevarsrepr)
+ for thing in things:
+ if isinstance(thing, tuple):
+ code = thing[0]
+ vitem, r_arg = argsiter.next()
+ if not hasattr(r_arg, 'll_str'):
+ raise TyperError("ll_str unsupported for: %r" % r_arg)
+ if code == 's':
+ # TODO: for now it works only with types supported by oostring
+ vchunk = hop.genop('oostring', [vitem, cm1], resulttype=ootype.String)
+ elif code == 'd':
+ assert isinstance(r_arg, IntegerRepr)
+ vchunk = hop.genop('oostring', [vitem, c10], resulttype=ootype.String)
+ elif code == 'f':
+ #assert isinstance(r_arg, FloatRepr)
+ vchunk = hop.gendirectcall(r_arg.ll_str, vitem)
+ elif code == 'x':
+ assert isinstance(r_arg, IntegerRepr)
+ vchunk = hop.genop('oostring', [vitem, c16], resulttype=ootype.String)
+ elif code == 'o':
+ assert isinstance(r_arg, IntegerRepr)
+ vchunk = hop.genop('oostring', [vitem, c8], resulttype=ootype.String)
+ elif code == 'r' and isinstance(r_arg, InstanceRepr):
+ vchunk = hop.gendirectcall(r_arg.ll_str, vitem)
+ else:
+ raise TyperError, "%%%s is not RPython" % (code, )
+ else:
+ vchunk = hop.inputconst(string_repr, thing)
+ #i = inputconst(Signed, i)
+ #hop.genop('setarrayitem', [vtemp, i, vchunk])
+ hop.genop('oosend', [c_append, v_buf, vchunk], resulttype=ootype.Void)
+
+ hop.exception_cannot_occur() # to ignore the ZeroDivisionError of '%'
+ return hop.genop('oosend', [c_build, v_buf], resulttype=ootype.String)
+ do_stringformat = classmethod(do_stringformat)
+
def add_helpers():
dic = {}
for name, meth in ootype.String._GENERIC_METHODS.iteritems():
@@ -192,3 +249,16 @@
string_iterator_repr = StringIteratorRepr()
+
+# these should be in rclass, but circular imports prevent (also it's
+# not that insane that a string constant is built in this file).
+
+instance_str_prefix = string_repr.convert_const("<")
+instance_str_suffix = string_repr.convert_const(" object>")
+
+unboxed_instance_str_prefix = string_repr.convert_const("<unboxed ")
+unboxed_instance_str_suffix = string_repr.convert_const(">")
+
+list_str_open_bracket = string_repr.convert_const("[")
+list_str_close_bracket = string_repr.convert_const("]")
+list_str_sep = string_repr.convert_const(", ")
Modified: pypy/dist/pypy/rpython/rstr.py
==============================================================================
--- pypy/dist/pypy/rpython/rstr.py (original)
+++ pypy/dist/pypy/rpython/rstr.py Tue May 16 14:12:17 2006
@@ -298,10 +298,15 @@
r_tuple = hop.args_r[1]
v_tuple = hop.args_v[1]
+ if hop.rtyper.type_system.name == 'ootypesystem':
+ getfield = 'oogetfield'
+ else:
+ getfield = 'getfiel'
+
sourcevars = []
for fname, r_arg in zip(r_tuple.fieldnames, r_tuple.items_r):
cname = hop.inputconst(Void, fname)
- vitem = hop.genop("getfield", [v_tuple, cname],
+ vitem = hop.genop(getfield, [v_tuple, cname],
resulttype=r_arg)
sourcevars.append((vitem, r_arg))
@@ -545,3 +550,28 @@
raise IndexError
return cls.ll_stritem_nonneg(s, i)
ll_stritem_checked = classmethod(ll_stritem_checked)
+
+ def parse_fmt_string(fmt):
+ # we support x, d, s, f, [r]
+ it = iter(fmt)
+ r = []
+ curstr = ''
+ for c in it:
+ if c == '%':
+ f = it.next()
+ if f == '%':
+ curstr += '%'
+ continue
+
+ if curstr:
+ r.append(curstr)
+ curstr = ''
+ if f not in 'xdosrf':
+ raise TyperError("Unsupported formatting specifier: %r in %r" % (f, fmt))
+
+ r.append((f,))
+ else:
+ curstr += c
+ if curstr:
+ r.append(curstr)
+ return r
Modified: pypy/dist/pypy/rpython/test/test_rstr.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rstr.py (original)
+++ pypy/dist/pypy/rpython/test/test_rstr.py Tue May 16 14:12:17 2006
@@ -1,5 +1,6 @@
import random
from pypy.rpython.lltypesystem.lltype import *
+from pypy.rpython.rstr import AbstractLLHelpers
from pypy.rpython.lltypesystem.rstr import LLHelpers, STR
from pypy.rpython.rtyper import RPythonTyper, TyperError
from pypy.rpython.test.test_llinterp import interpret, interpret_raises
@@ -22,6 +23,11 @@
res = LLHelpers.ll_rfind(llstr(s1), llstr(s2), 0, n1)
assert res == s1.rfind(s2)
+def test_parse_fmt():
+ assert AbstractLLHelpers.parse_fmt_string('a') == ['a']
+ assert AbstractLLHelpers.parse_fmt_string('%s') == [('s',)]
+ assert AbstractLLHelpers.parse_fmt_string("name '%s' is not defined") == ["name '", ("s",), "' is not defined"]
+
class AbstractTestRstr:
@@ -376,100 +382,99 @@
assert self.ll_to_string(res) == 'hell'
-def test_parse_fmt():
- assert LLHelpers.parse_fmt_string('a') == ['a']
- assert LLHelpers.parse_fmt_string('%s') == [('s',)]
- assert LLHelpers.parse_fmt_string("name '%s' is not defined") == ["name '", ("s",), "' is not defined"]
-
-def test_strformat():
- def percentS(s):
- return "before %s after" % (s,)
+ def test_strformat(self):
+ def percentS(s):
+ return "before %s after" % (s,)
- res = interpret(percentS, ['1'])
- assert ''.join(res.chars) == 'before 1 after'
+ res = self.interpret(percentS, ['1'])
+ assert self.ll_to_string(res) == 'before 1 after'
- def percentD(i):
- return "bing %d bang" % (i,)
-
- res = interpret(percentD, [23])
- assert ''.join(res.chars) == 'bing 23 bang'
+ def percentD(i):
+ return "bing %d bang" % (i,)
- def percentX(i):
- return "bing %x bang" % (i,)
+ res = self.interpret(percentD, [23])
+ assert self.ll_to_string(res) == 'bing 23 bang'
- res = interpret(percentX, [23])
- assert ''.join(res.chars) == 'bing 17 bang'
+ def percentX(i):
+ return "bing %x bang" % (i,)
- res = interpret(percentX, [-123])
- assert ''.join(res.chars) == 'bing -7b bang'
+ res = self.interpret(percentX, [23])
+ assert self.ll_to_string(res) == 'bing 17 bang'
- def percentO(i):
- return "bing %o bang" % (i,)
-
- res = interpret(percentO, [23])
- assert ''.join(res.chars) == 'bing 27 bang'
+ res = self.interpret(percentX, [-123])
+ assert self.ll_to_string(res) == 'bing -7b bang'
- res = interpret(percentO, [-123])
- assert ''.join(res.chars) == 'bing -173 bang'
+ def percentO(i):
+ return "bing %o bang" % (i,)
- def moreThanOne(s, d, x, o):
- return "string: %s decimal: %d hex: %x oct: %o" % (s, d, x, o)
+ res = self.interpret(percentO, [23])
+ assert self.ll_to_string(res) == 'bing 27 bang'
- args = 'a', 2, 3, 4
- res = interpret(moreThanOne, list(args))
- assert ''.join(res.chars) == moreThanOne(*args)
-
-def test_strformat_nontuple():
- def percentD(i):
- return "before %d after" % i
-
- res = interpret(percentD, [1])
- assert ''.join(res.chars) == 'before 1 after'
-
- def percentS(i):
- return "before %s after" % i
-
- res = interpret(percentS, ['D'])
- assert ''.join(res.chars) == 'before D after'
-
-def test_strformat_instance():
- class C:
- pass
- class D(C):
- pass
- def dummy(i):
- if i:
- x = C()
- else:
- x = D()
- return str(x)
-
- res = interpret(dummy, [1])
- assert ''.join(res.chars) == '<C object>'
+ res = self.interpret(percentO, [-123])
+ assert self.ll_to_string(res) == 'bing -173 bang'
- res = interpret(dummy, [0])
- assert ''.join(res.chars) == '<D object>'
+ def moreThanOne(s, d, x, o):
+ return "string: %s decimal: %d hex: %x oct: %o" % (s, d, x, o)
-def test_percentformat_instance():
- class C:
- pass
- class D(C):
- pass
-
- def dummy(i):
- if i:
- x = C()
- y = D()
- else:
- x = D()
- y = C()
- return "what a nice %s, much nicer than %r"%(x, y)
-
- res = interpret(dummy, [1])
- assert ''.join(res.chars) == 'what a nice <C object>, much nicer than <D object>'
+ args = 'a', 2, 3, 4
+ res = self.interpret(moreThanOne, list(args))
+ assert self.ll_to_string(res) == moreThanOne(*args)
+
+ def test_strformat_nontuple(self):
+ def percentD(i):
+ return "before %d after" % i
+
+ res = self.interpret(percentD, [1])
+ assert self.ll_to_string(res) == 'before 1 after'
+
+ def percentS(i):
+ return "before %s after" % i
- res = interpret(dummy, [0])
- assert ''.join(res.chars) == 'what a nice <D object>, much nicer than <C object>'
+ res = self.interpret(percentS, ['D'])
+ assert self.ll_to_string(res) == 'before D after'
+
+ def test_strformat_instance(self):
+ class C:
+ pass
+ class D(C):
+ pass
+ def dummy(i):
+ if i:
+ x = C()
+ else:
+ x = D()
+ return str(x)
+
+ res = self.ll_to_string(self.interpret(dummy, [1]))
+ assert res.startswith('<')
+ assert res.endswith('C object>')
+
+ res = self.ll_to_string(self.interpret(dummy, [0]))
+ assert res.startswith('<')
+ assert res.endswith('D object>')
+
+ def test_percentformat_instance(self):
+ class C:
+ pass
+ class D(C):
+ pass
+
+ def dummy(i):
+ if i:
+ x = C()
+ y = D()
+ else:
+ x = D()
+ y = C()
+ return "what a nice %s, much nicer than %r"%(x, y)
+
+ res = self.ll_to_string(self.interpret(dummy, [1]))
+ res = res.replace('pypy.rpython.test.test_rstr.', '')
+ assert res == 'what a nice <C object>, much nicer than <D object>'
+
+ res = self.ll_to_string(self.interpret(dummy, [0]))
+ res = res.replace('pypy.rpython.test.test_rstr.', '')
+ assert res == 'what a nice <D object>, much nicer than <C object>'
def test_split():
def fn(i):
More information about the Pypy-commit
mailing list