[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