[pypy-svn] pypy shorter-float-repr: Start to use dtoa.c in place of LL_strtod_formatd.

amauryfa commits-noreply at bitbucket.org
Thu Jan 20 22:26:32 CET 2011


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: shorter-float-repr
Changeset: r41097:e29cd443c6ea
Date: 2011-01-20 22:26 +0100
http://bitbucket.org/pypy/pypy/changeset/e29cd443c6ea/

Log:	Start to use dtoa.c in place of LL_strtod_formatd. Still very
	incomplete, and we need a translation option to enable it

diff --git a/pypy/rpython/module/ll_strtod.py b/pypy/rpython/module/ll_strtod.py
--- a/pypy/rpython/module/ll_strtod.py
+++ b/pypy/rpython/module/ll_strtod.py
@@ -9,6 +9,8 @@
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.tool.autopath import pypydir
 
+USE_DTOA = True # XXX make it a translation option
+
 class CConfig:
     _compilation_info_ = ExternalCompilationInfo(
         includes = ['src/ll_strtod.h'],
@@ -59,6 +61,10 @@
 
             return s
 
+        if USE_DTOA:
+            from pypy.rpython.module.ll_dtoa import llimpl_strtod
+            llimpl = llimpl_strtod
+
         def oofakeimpl(x, code, precision, flags):
             return ootype.oostring(rarithmetic.formatd(x, code, precision, flags), -1)
 

diff --git a/pypy/translator/c/test/test_dtoa.py b/pypy/translator/c/test/test_dtoa.py
deleted file mode 100644
--- a/pypy/translator/c/test/test_dtoa.py
+++ /dev/null
@@ -1,92 +0,0 @@
-from __future__ import with_statement
-from pypy.translator.tool.cbuild import ExternalCompilationInfo
-from pypy.tool.autopath import pypydir
-from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.rlib.rstring import StringBuilder
-import py
-
-includes = []
-libraries = []
-
-cdir = py.path.local(pypydir) / 'translator' / 'c'
-files = [cdir / 'src' / 'dtoa.c']
-include_dirs = [cdir]
-
-eci = ExternalCompilationInfo(
-    include_dirs = include_dirs,
-    libraries = libraries,
-    separate_module_files = files,
-    separate_module_sources = ['''
-        #include <stdlib.h>
-        #include <assert.h>
-        #define WITH_PYMALLOC
-        #include "src/obmalloc.c"
-    '''],
-    export_symbols = ['_Py_dg_strtod',
-                      '_Py_dg_dtoa',
-                      '_Py_dg_freedtoa',
-                      ],
-)
-
-dg_strtod = rffi.llexternal(
-    '_Py_dg_strtod', [rffi.CCHARP, rffi.CCHARPP], rffi.DOUBLE,
-    compilation_info=eci)
-
-dg_dtoa = rffi.llexternal(
-    '_Py_dg_dtoa', [rffi.DOUBLE, rffi.INT, rffi.INT,
-                    rffi.INTP, rffi.INTP, rffi.CCHARPP], rffi.CCHARP,
-    compilation_info=eci)
-
-dg_freedtoa = rffi.llexternal(
-    '_Py_dg_freedtoa', [rffi.CCHARP], lltype.Void,
-    compilation_info=eci)
-
-def strtod(input):
-    with lltype.scoped_alloc(rffi.CCHARPP.TO, 1) as end_ptr:
-        with rffi.scoped_str2charp(input) as ll_input:
-            result = dg_strtod(ll_input, end_ptr)
-            if end_ptr[0] and ord(end_ptr[0][0]):
-                offset = (rffi.cast(rffi.LONG, end_ptr[0]) -
-                          rffi.cast(rffi.LONG, ll_input))
-                raise ValueError("invalid input at position %d" % (offset,))
-            return result
-
-def dtoa(value, mode=0, precision=0):
-    builder = StringBuilder(20)
-    with lltype.scoped_alloc(rffi.INTP.TO, 1) as decpt_ptr:
-        with lltype.scoped_alloc(rffi.INTP.TO, 1) as sign_ptr:
-            with lltype.scoped_alloc(rffi.CCHARPP.TO, 1) as end_ptr:
-                output_ptr = dg_dtoa(value, mode, precision,
-                                     decpt_ptr, sign_ptr, end_ptr)
-                try:
-                    buflen = (rffi.cast(rffi.LONG, end_ptr[0]) -
-                              rffi.cast(rffi.LONG, output_ptr))
-                    intpart = rffi.cast(lltype.Signed, decpt_ptr[0])
-                    if intpart <= buflen:
-                        builder.append(rffi.charpsize2str(output_ptr, intpart))
-                    else:
-                        builder.append(rffi.charpsize2str(output_ptr, buflen))
-                        while buflen < intpart:
-                            builder.append('0')
-                            intpart -= 1
-                    builder.append('.')
-                    fracpart = buflen - intpart
-                    if fracpart > 0:
-                        ptr = rffi.ptradd(output_ptr, intpart)
-                        builder.append(rffi.charpsize2str(ptr, fracpart))
-                finally:
-                    dg_freedtoa(output_ptr)
-    return builder.build()
-
-def test_strtod():
-    assert strtod("12345") == 12345.0
-    assert strtod("1.1") == 1.1
-    assert strtod("3.47") == 3.47
-    raises(ValueError, strtod, "123A")
-
-def test_dtoa():
-    assert dtoa(3.47) == "3.47"
-    assert dtoa(1.1) == "1.1"
-    assert dtoa(12.3577) == "12.3577"
-    assert dtoa(10) == "10."
-    assert dtoa(1e100) == "1" + "0" * 100 + "."

diff --git a/pypy/rpython/module/ll_dtoa.py b/pypy/rpython/module/ll_dtoa.py
new file mode 100644
--- /dev/null
+++ b/pypy/rpython/module/ll_dtoa.py
@@ -0,0 +1,101 @@
+from __future__ import with_statement
+from pypy.rlib import rarithmetic
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
+from pypy.tool.autopath import pypydir
+from pypy.rpython.lltypesystem import lltype, rffi
+from pypy.rlib.rstring import StringBuilder
+import py
+
+cdir = py.path.local(pypydir) / 'translator' / 'c'
+include_dirs = [cdir]
+
+eci = ExternalCompilationInfo(
+    include_dirs = [cdir],
+    libraries = [],
+    separate_module_files = [cdir / 'src' / 'dtoa.c'],
+    separate_module_sources = ['''
+       #include <stdlib.h>
+       #include <assert.h>
+       #define WITH_PYMALLOC
+       #include "src/obmalloc.c"
+    '''],
+    export_symbols = ['_Py_dg_strtod',
+                      '_Py_dg_dtoa',
+                      '_Py_dg_freedtoa',
+                      ],
+    )
+
+dg_strtod = rffi.llexternal(
+    '_Py_dg_strtod', [rffi.CCHARP, rffi.CCHARPP], rffi.DOUBLE,
+    compilation_info=eci)
+
+dg_dtoa = rffi.llexternal(
+    '_Py_dg_dtoa', [rffi.DOUBLE, rffi.INT, rffi.INT,
+                    rffi.INTP, rffi.INTP, rffi.CCHARPP], rffi.CCHARP,
+    compilation_info=eci)
+
+dg_freedtoa = rffi.llexternal(
+    '_Py_dg_freedtoa', [rffi.CCHARP], lltype.Void,
+    compilation_info=eci)
+
+def strtod(input):
+    with lltype.scoped_alloc(rffi.CCHARPP.TO, 1) as end_ptr:
+        with rffi.scoped_str2charp(input) as ll_input:
+            result = dg_strtod(ll_input, end_ptr)
+            if end_ptr[0] and ord(end_ptr[0][0]):
+                offset = (rffi.cast(rffi.LONG, end_ptr[0]) -
+                          rffi.cast(rffi.LONG, ll_input))
+                raise ValueError("invalid input at position %d" % (offset,))
+            return result
+
+def dtoa(value, mode=0, precision=0, flags=0):
+    builder = StringBuilder(20)
+    with lltype.scoped_alloc(rffi.INTP.TO, 1) as decpt_ptr:
+        with lltype.scoped_alloc(rffi.INTP.TO, 1) as sign_ptr:
+            with lltype.scoped_alloc(rffi.CCHARPP.TO, 1) as end_ptr:
+                output_ptr = dg_dtoa(value, mode, precision,
+                                     decpt_ptr, sign_ptr, end_ptr)
+                try:
+                    buflen = (rffi.cast(rffi.LONG, end_ptr[0]) -
+                              rffi.cast(rffi.LONG, output_ptr))
+                    intpart = rffi.cast(lltype.Signed, decpt_ptr[0])
+                    if intpart <= buflen:
+                        builder.append(rffi.charpsize2str(output_ptr, intpart))
+                    else:
+                        builder.append(rffi.charpsize2str(output_ptr, buflen))
+                        while buflen < intpart:
+                            builder.append('0')
+                            intpart -= 1
+                    fracpart = buflen - intpart
+                    if fracpart > 0:
+                        builder.append('.')
+                        ptr = rffi.ptradd(output_ptr, intpart)
+                        builder.append(rffi.charpsize2str(ptr, fracpart))
+                    elif flags & rarithmetic.DTSF_ADD_DOT_0:
+                        builder.append('.0')
+                finally:
+                    dg_freedtoa(output_ptr)
+    return builder.build()
+
+def llimpl_strtod(value, code, precision, flags):
+    if code in 'EFG':
+        code = code.lower()
+
+    if code == 'e':
+        mode = 2
+        precision += 1
+    elif code == 'f':
+        mode = 3
+    elif code == 'g':
+        mode = 2
+        # precision 0 makes no sense for 'g' format; interpret as 1
+        if precision == 0:
+            precision = 1
+    elif code == 'r':
+        # repr format
+        mode = 0
+        assert precision == 0
+    else:
+        raise ValueError('Invalid mode')
+
+    return dtoa(value, mode=mode, precision=precision, flags=flags)

diff --git a/pypy/translator/c/test/test_dtoa.py b/pypy/rpython/module/test/test_ll_dtoa.py
copy from pypy/translator/c/test/test_dtoa.py
copy to pypy/rpython/module/test/test_ll_dtoa.py
--- a/pypy/translator/c/test/test_dtoa.py
+++ b/pypy/rpython/module/test/test_ll_dtoa.py
@@ -1,82 +1,4 @@
-from __future__ import with_statement
-from pypy.translator.tool.cbuild import ExternalCompilationInfo
-from pypy.tool.autopath import pypydir
-from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.rlib.rstring import StringBuilder
-import py
-
-includes = []
-libraries = []
-
-cdir = py.path.local(pypydir) / 'translator' / 'c'
-files = [cdir / 'src' / 'dtoa.c']
-include_dirs = [cdir]
-
-eci = ExternalCompilationInfo(
-    include_dirs = include_dirs,
-    libraries = libraries,
-    separate_module_files = files,
-    separate_module_sources = ['''
-        #include <stdlib.h>
-        #include <assert.h>
-        #define WITH_PYMALLOC
-        #include "src/obmalloc.c"
-    '''],
-    export_symbols = ['_Py_dg_strtod',
-                      '_Py_dg_dtoa',
-                      '_Py_dg_freedtoa',
-                      ],
-)
-
-dg_strtod = rffi.llexternal(
-    '_Py_dg_strtod', [rffi.CCHARP, rffi.CCHARPP], rffi.DOUBLE,
-    compilation_info=eci)
-
-dg_dtoa = rffi.llexternal(
-    '_Py_dg_dtoa', [rffi.DOUBLE, rffi.INT, rffi.INT,
-                    rffi.INTP, rffi.INTP, rffi.CCHARPP], rffi.CCHARP,
-    compilation_info=eci)
-
-dg_freedtoa = rffi.llexternal(
-    '_Py_dg_freedtoa', [rffi.CCHARP], lltype.Void,
-    compilation_info=eci)
-
-def strtod(input):
-    with lltype.scoped_alloc(rffi.CCHARPP.TO, 1) as end_ptr:
-        with rffi.scoped_str2charp(input) as ll_input:
-            result = dg_strtod(ll_input, end_ptr)
-            if end_ptr[0] and ord(end_ptr[0][0]):
-                offset = (rffi.cast(rffi.LONG, end_ptr[0]) -
-                          rffi.cast(rffi.LONG, ll_input))
-                raise ValueError("invalid input at position %d" % (offset,))
-            return result
-
-def dtoa(value, mode=0, precision=0):
-    builder = StringBuilder(20)
-    with lltype.scoped_alloc(rffi.INTP.TO, 1) as decpt_ptr:
-        with lltype.scoped_alloc(rffi.INTP.TO, 1) as sign_ptr:
-            with lltype.scoped_alloc(rffi.CCHARPP.TO, 1) as end_ptr:
-                output_ptr = dg_dtoa(value, mode, precision,
-                                     decpt_ptr, sign_ptr, end_ptr)
-                try:
-                    buflen = (rffi.cast(rffi.LONG, end_ptr[0]) -
-                              rffi.cast(rffi.LONG, output_ptr))
-                    intpart = rffi.cast(lltype.Signed, decpt_ptr[0])
-                    if intpart <= buflen:
-                        builder.append(rffi.charpsize2str(output_ptr, intpart))
-                    else:
-                        builder.append(rffi.charpsize2str(output_ptr, buflen))
-                        while buflen < intpart:
-                            builder.append('0')
-                            intpart -= 1
-                    builder.append('.')
-                    fracpart = buflen - intpart
-                    if fracpart > 0:
-                        ptr = rffi.ptradd(output_ptr, intpart)
-                        builder.append(rffi.charpsize2str(ptr, fracpart))
-                finally:
-                    dg_freedtoa(output_ptr)
-    return builder.build()
+from pypy.rpython.module.ll_dtoa import strtod, dtoa
 
 def test_strtod():
     assert strtod("12345") == 12345.0
@@ -88,5 +10,5 @@
     assert dtoa(3.47) == "3.47"
     assert dtoa(1.1) == "1.1"
     assert dtoa(12.3577) == "12.3577"
-    assert dtoa(10) == "10."
-    assert dtoa(1e100) == "1" + "0" * 100 + "."
+    assert dtoa(10.0) == "10"
+    assert dtoa(1.0e100) == "1" + "0" * 100


More information about the Pypy-commit mailing list