[pypy-svn] r14280 - in pypy/dist/pypy: annotation rpython rpython/test

bert at codespeak.net bert at codespeak.net
Tue Jul 5 14:37:47 CEST 2005


Author: bert
Date: Tue Jul  5 14:37:44 2005
New Revision: 14280

Modified:
   pypy/dist/pypy/annotation/builtin.py
   pypy/dist/pypy/rpython/rbuiltin.py
   pypy/dist/pypy/rpython/rstr.py
   pypy/dist/pypy/rpython/test/test_rstr.py
Log:
(bert,arre):

- implemented int(string) and int(string, base) for bases 2-36


Modified: pypy/dist/pypy/annotation/builtin.py
==============================================================================
--- pypy/dist/pypy/annotation/builtin.py	(original)
+++ pypy/dist/pypy/annotation/builtin.py	Tue Jul  5 14:37:44 2005
@@ -67,9 +67,8 @@
     return constpropagate(bool, [s_obj], SomeBool())
 
 def builtin_int(s_obj, s_base=None):
-    assert (s_base is None or s_base.is_constant() 
-            and s_base.const == 16
-            and s_obj.knowntype == str), "only int(v|string) or int(string,16) expected"
+    assert (s_base is None or isinstance(s_base, SomeInteger)
+            and s_obj.knowntype == str), "only int(v|string) or int(string,int) expected"
     if s_base is not None:
         args_s = [s_obj, s_base]
     else:

Modified: pypy/dist/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/rbuiltin.py	(original)
+++ pypy/dist/pypy/rpython/rbuiltin.py	Tue Jul  5 14:37:44 2005
@@ -87,7 +87,8 @@
 
 def rtype_builtin_int(hop):
     if isinstance(hop.args_s[0], annmodel.SomeString):
-        raise TyperError('int("string") not supported')
+	assert 1 <= hop.nb_args <= 2
+	return hop.args_r[0].rtype_int(hop)
     assert hop.nb_args == 1
     return hop.args_r[0].rtype_int(hop)
 

Modified: pypy/dist/pypy/rpython/rstr.py
==============================================================================
--- pypy/dist/pypy/rpython/rstr.py	(original)
+++ pypy/dist/pypy/rpython/rstr.py	Tue Jul  5 14:37:44 2005
@@ -142,6 +142,16 @@
         v_str, v_c1, v_c2 = hop.inputargs(string_repr, char_repr, char_repr)
         return hop.gendirectcall(ll_replace_chr_chr, v_str, v_c1, v_c2)
 
+    def rtype_int(_, hop):
+	if hop.nb_args == 1:
+	    v_str, = hop.inputargs(string_repr)
+	    c_base = inputconst(Signed, 10)
+	    return hop.gendirectcall(ll_int, v_str, c_base)
+        if not hop.args_r[1] == rint.signed_repr:
+            raise TyperError, 'base needs to be an int'
+	v_str, v_base= hop.inputargs(string_repr, rint.signed_repr)
+	return hop.gendirectcall(ll_int, v_str, v_base)
+
     def ll_str(s, r):
         if typeOf(s) == Char:
             return ll_chr2str(s)
@@ -768,6 +778,47 @@
         i += 1
     return False
 
+def ll_int(s, base):
+    if not 2 <= base <= 36:
+	raise ValueError
+    chars = s.chars
+    strlen = len(chars)
+    i = 0
+    #XXX: only space is allowed as white space for now
+    while i < strlen and chars[i] == ' ':
+	i += 1
+    if not i < strlen:
+	raise ValueError
+    #check sign
+    sign = 1
+    if chars[i] == '-':
+	sign = -1
+	i += 1
+    elif chars[i] == '+':
+	i += 1;
+    #now get digits
+    val = 0
+    while i < strlen:
+	c = ord(chars[i])
+	if ord('a') <= c <= ord('z'):
+	    digit = c - ord('a') + 10
+	elif ord('A') <= c <= ord('Z'):
+	    digit = c - ord('A') + 10
+	elif ord('0') <= c <= ord('9'):
+	    digit = c - ord('0')
+	else:
+	    break
+	if digit >= base:
+	    break
+	val = val * base + digit
+	i += 1
+    #skip trailing whitespace
+    while i < strlen and chars[i] == ' ':
+	i += 1
+    if not i == strlen:
+	raise ValueError
+    return sign * val
+
 # ____________________________________________________________
 #
 #  Iteration.

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 Jul  5 14:37:44 2005
@@ -2,8 +2,8 @@
 from pypy.rpython.lltype import *
 from pypy.rpython.rstr import parse_fmt_string
 from pypy.rpython.rtyper import RPythonTyper, TyperError
-from pypy.rpython.test.test_llinterp import interpret
-
+from pypy.rpython.test.test_llinterp import interpret,find_exception
+from pypy.rpython.llinterp import LLException
 
 def test_simple():
     def fn(i):
@@ -356,3 +356,20 @@
         s = 'abbccc'
         s = s.replace('abb', 'c')
     raises (TyperError, interpret, fn, ())
+
+def test_int():
+    s1 = [ '42', '01001', 'abc', 'ABC', '4aBc', ' 12ef ', '+42', 'foo', '42foo', '42.1', '']
+    def fn(i, base):
+        s = s1[i]
+        res = int(s, base)
+        return res
+    for j in (10, 16, 2, 1, 36, 42, -3):
+	for i in range(len(s1)):
+	    try:
+		expected = fn(i, j)
+	    except ValueError:
+		info = raises(LLException, interpret, fn, [i, j])
+		assert find_exception(info.value) is ValueError
+	    else:
+		res = interpret(fn, [i, j])
+		assert res == expected



More information about the Pypy-commit mailing list