Commit c1de0f17 authored by Boxiang Sun's avatar Boxiang Sun

enable PyFloat_FromString, and improve floatNew, repr, str method

parent 84370f29
...@@ -173,8 +173,6 @@ Since we can't change the interface of a public API function, pend is ...@@ -173,8 +173,6 @@ Since we can't change the interface of a public API function, pend is
still supported but now *officially* useless: if pend is not NULL, still supported but now *officially* useless: if pend is not NULL,
*pend is set to NULL. *pend is set to NULL.
**************************************************************************/ **************************************************************************/
// pyston change: comment this out
#if 0
PyObject * PyObject *
PyFloat_FromString(PyObject *v, char **pend) PyFloat_FromString(PyObject *v, char **pend)
{ {
...@@ -240,7 +238,6 @@ PyFloat_FromString(PyObject *v, char **pend) ...@@ -240,7 +238,6 @@ PyFloat_FromString(PyObject *v, char **pend)
#endif #endif
return result; return result;
} }
#endif
static void static void
float_dealloc(PyFloatObject *op) float_dealloc(PyFloatObject *op)
......
...@@ -40,10 +40,6 @@ extern "C" PyObject* PyFloat_FromDouble(double d) noexcept { ...@@ -40,10 +40,6 @@ extern "C" PyObject* PyFloat_FromDouble(double d) noexcept {
return boxFloat(d); return boxFloat(d);
} }
extern "C" PyObject* PyFloat_FromString(PyObject* v, char** pend) noexcept {
Py_FatalError("unimplemented");
}
extern "C" double PyFloat_AsDouble(PyObject* o) noexcept { extern "C" double PyFloat_AsDouble(PyObject* o) noexcept {
assert(o); assert(o);
...@@ -780,47 +776,21 @@ std::string floatFmt(double x, int precision, char code) { ...@@ -780,47 +776,21 @@ std::string floatFmt(double x, int precision, char code) {
} }
template <ExceptionStyle S> static BoxedFloat* _floatNew(Box* a) noexcept(S == CAPI) { template <ExceptionStyle S> static BoxedFloat* _floatNew(Box* a) noexcept(S == CAPI) {
// FIXME CPython uses PyUnicode_EncodeDecimal:
try {
a = coerceUnicodeToStr(a);
} catch (ExcInfo e) {
if (S == CAPI) {
throwCAPIException();
return NULL;
}
throw e;
}
if (a->cls == float_cls) { if (a->cls == float_cls) {
return static_cast<BoxedFloat*>(a); return static_cast<BoxedFloat*>(a);
} else if (PyFloat_Check(a)) {
return new BoxedFloat(static_cast<BoxedFloat*>(a)->d);
} else if (PyInt_Check(a)) { } else if (PyInt_Check(a)) {
return new BoxedFloat(static_cast<BoxedInt*>(a)->n); return new BoxedFloat(static_cast<BoxedInt*>(a)->n);
} else if (a->cls == str_cls) { } else if (a->cls == str_cls || a->cls == unicode_cls) {
llvm::StringRef s = static_cast<BoxedString*>(a)->s(); BoxedFloat* res = (BoxedFloat*)PyFloat_FromString(a, NULL);
if (s == "nan")
return new BoxedFloat(NAN); if (!res) {
if (s == "-nan") if (S == CAPI)
return new BoxedFloat(-NAN);
if (s == "inf")
return new BoxedFloat(INFINITY);
if (s == "-inf")
return new BoxedFloat(-INFINITY);
// TODO this should just use CPython's implementation:
char* endptr;
assert(s.data()[s.size()] == '\0');
const char* startptr = s.data();
double r = strtod(startptr, &endptr);
if (endptr != startptr + s.size()) {
if (S == CAPI) {
PyErr_Format(ValueError, "could not convert string to float: %s", s.data());
return NULL; return NULL;
} else else
raiseExcHelper(ValueError, "could not convert string to float: %s", s.data()); throwCAPIException();
} }
return new BoxedFloat(r);
return res;
} else { } else {
static BoxedString* float_str = internStringImmortal("__float__"); static BoxedString* float_str = internStringImmortal("__float__");
Box* r = callattrInternal<S>(a, float_str, CLASS_ONLY, NULL, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL); Box* r = callattrInternal<S>(a, float_str, CLASS_ONLY, NULL, ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);
...@@ -868,7 +838,6 @@ template <ExceptionStyle S> Box* floatNew(BoxedClass* _cls, Box* a) noexcept(S = ...@@ -868,7 +838,6 @@ template <ExceptionStyle S> Box* floatNew(BoxedClass* _cls, Box* a) noexcept(S =
} }
} }
if (cls == float_cls) if (cls == float_cls)
return _floatNew<S>(a); return _floatNew<S>(a);
...@@ -881,17 +850,36 @@ template <ExceptionStyle S> Box* floatNew(BoxedClass* _cls, Box* a) noexcept(S = ...@@ -881,17 +850,36 @@ template <ExceptionStyle S> Box* floatNew(BoxedClass* _cls, Box* a) noexcept(S =
return new (cls) BoxedFloat(f->d); return new (cls) BoxedFloat(f->d);
} }
PyObject* float_str_or_repr(double v, int precision, char format_code) {
PyObject* result;
char* buf = PyOS_double_to_string(v, format_code, precision, Py_DTSF_ADD_DOT_0, NULL);
if (!buf)
return PyErr_NoMemory();
result = PyString_FromString(buf);
PyMem_Free(buf);
return result;
}
extern "C" Box* floatFloat(BoxedFloat* self) {
if (!PyFloat_Check(self))
raiseExcHelper(TypeError, "descriptor '__float__' requires a 'float' object but received a '%s'",
getTypeName(self));
if (self->cls == float_cls)
return self;
return boxFloat(self->d);
}
Box* floatStr(BoxedFloat* self) { Box* floatStr(BoxedFloat* self) {
if (!PyFloat_Check(self)) if (!PyFloat_Check(self))
raiseExcHelper(TypeError, "descriptor '__str__' requires a 'float' object but received a '%s'", raiseExcHelper(TypeError, "descriptor '__str__' requires a 'float' object but received a '%s'",
getTypeName(self)); getTypeName(self));
return boxString(floatFmt(self->d, 12, 'g')); return float_str_or_repr(self->d, PyFloat_STR_PRECISION, 'g');
} }
Box* floatRepr(BoxedFloat* self) { Box* floatRepr(BoxedFloat* self) {
assert(self->cls == float_cls); return float_str_or_repr(self->d, 0, 'r');
return boxString(floatFmt(self->d, 16, 'g'));
} }
Box* floatTrunc(BoxedFloat* self) { Box* floatTrunc(BoxedFloat* self) {
...@@ -967,7 +955,10 @@ static void _addFuncPow(const char* name, ConcreteCompilerType* rtn_type, void* ...@@ -967,7 +955,10 @@ static void _addFuncPow(const char* name, ConcreteCompilerType* rtn_type, void*
float_cls->giveAttr(name, new BoxedFunction(cl, { None })); float_cls->giveAttr(name, new BoxedFunction(cl, { None }));
} }
static Box* floatFloat(Box* b, void*) { static Box* floatConjugate(Box* b, void*) {
if (!PyFloat_Check(b))
raiseExcHelper(TypeError, "descriptor 'conjugate' requires a 'float' object but received a '%s'",
getTypeName(b));
if (b->cls == float_cls) { if (b->cls == float_cls) {
return b; return b;
} else { } else {
...@@ -1677,15 +1668,16 @@ void setupFloat() { ...@@ -1677,15 +1668,16 @@ void setupFloat() {
float_cls->giveAttr("__nonzero__", new BoxedFunction(nonzero)); float_cls->giveAttr("__nonzero__", new BoxedFunction(nonzero));
// float_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)floatNonzero, NULL, 1))); // float_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)floatNonzero, NULL, 1)));
float_cls->giveAttr("__float__", new BoxedFunction(boxRTFunction((void*)floatFloat, BOXED_FLOAT, 1)));
float_cls->giveAttr("__str__", new BoxedFunction(boxRTFunction((void*)floatStr, STR, 1))); float_cls->giveAttr("__str__", new BoxedFunction(boxRTFunction((void*)floatStr, STR, 1)));
float_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)floatRepr, STR, 1))); float_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)floatRepr, STR, 1)));
float_cls->giveAttr("__trunc__", new BoxedFunction(boxRTFunction((void*)floatTrunc, UNKNOWN, 1))); float_cls->giveAttr("__trunc__", new BoxedFunction(boxRTFunction((void*)floatTrunc, UNKNOWN, 1)));
float_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)floatHash, BOXED_INT, 1))); float_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)floatHash, BOXED_INT, 1)));
float_cls->giveAttr("real", new (pyston_getset_cls) BoxedGetsetDescriptor(floatFloat, NULL, NULL)); float_cls->giveAttr("real", new (pyston_getset_cls) BoxedGetsetDescriptor(floatConjugate, NULL, NULL));
float_cls->giveAttr("imag", new (pyston_getset_cls) BoxedGetsetDescriptor(float0, NULL, NULL)); float_cls->giveAttr("imag", new (pyston_getset_cls) BoxedGetsetDescriptor(float0, NULL, NULL));
float_cls->giveAttr("conjugate", new BoxedFunction(boxRTFunction((void*)floatFloat, BOXED_FLOAT, 1))); float_cls->giveAttr("conjugate", new BoxedFunction(boxRTFunction((void*)floatConjugate, BOXED_FLOAT, 1)));
float_cls->giveAttr("__getformat__", float_cls->giveAttr("__getformat__",
new BoxedClassmethod(new BoxedBuiltinFunctionOrMethod( new BoxedClassmethod(new BoxedBuiltinFunctionOrMethod(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment