Commit b5682e5d authored by Boxiang Sun's avatar Boxiang Sun

add tp_new to these class

parent b33228cd
......@@ -46,13 +46,23 @@ Box* boolHash(BoxedBool* v) {
return boxInt(bool_hash(v));
}
extern "C" Box* boolNew(Box* cls, Box* val) {
template <ExceptionStyle S> static Box* boolNew(Box* cls, Box* val) noexcept {
assert(cls == bool_cls);
bool b = nonzero(val);
return boxBool(b);
}
static Box* bool_new(BoxedClass* type, Box* args, Box* kwds) noexcept {
PyObject* x = Py_False;
static char* kwlist[3] = { NULL, NULL };
kwlist[0] = const_cast<char*>("x");
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:bool", kwlist, &x))
return NULL;
return boolNew<CAPI>(type, x);
}
extern "C" Box* boolAnd(BoxedBool* lhs, BoxedBool* rhs) {
if (lhs->cls != bool_cls)
raiseExcHelper(TypeError, "descriptor '__and__' requires a 'bool' object but received a '%s'",
......@@ -94,8 +104,10 @@ void setupBool() {
bool_cls->giveAttr("__repr__", new BoxedFunction(FunctionMetadata::create((void*)boolRepr, STR, 1)));
bool_cls->giveAttr("__hash__", new BoxedFunction(FunctionMetadata::create((void*)boolHash, BOXED_INT, 1)));
bool_cls->giveAttr("__new__",
new BoxedFunction(FunctionMetadata::create((void*)boolNew, UNKNOWN, 2, false, false), { None }));
auto bool_new_fm
= FunctionMetadata::create((void*)boolNew<CXX>, UNKNOWN, 2, false, false, ParamNames({ "", "x" }, "", ""), CXX);
bool_new_fm->addVersion((void*)boolNew<CAPI>, UNKNOWN, CAPI);
bool_cls->giveAttr("__new__", new BoxedFunction(bool_new_fm, { None, NULL }));
bool_cls->giveAttr("__and__", new BoxedFunction(FunctionMetadata::create((void*)boolAnd, BOXED_BOOL, 2)));
bool_cls->giveAttr("__or__", new BoxedFunction(FunctionMetadata::create((void*)boolOr, BOXED_BOOL, 2)));
......@@ -103,6 +115,7 @@ void setupBool() {
bool_cls->freeze();
bool_cls->tp_hash = (hashfunc)bool_hash;
bool_cls->tp_new = (newfunc)bool_new;
}
void teardownBool() {
......
......@@ -1267,6 +1267,9 @@ void setupComplex() {
_addFunc("__div__", BOXED_COMPLEX, (void*)complexDivComplex, (void*)complexDivFloat, (void*)complexDivInt,
(void*)complexDiv);
_addFunc("__truediv__", BOXED_COMPLEX, (void*)complexDivComplex, (void*)complexDivFloat, (void*)complexDivInt,
(void*)complexDiv);
complex_cls->giveAttr("__rsub__", new BoxedFunction(FunctionMetadata::create((void*)complexRSub, UNKNOWN, 2)));
complex_cls->giveAttr("__rdiv__", new BoxedFunction(FunctionMetadata::create((void*)complexRDiv, UNKNOWN, 2)));
complex_cls->giveAttr(
......@@ -1279,8 +1282,6 @@ void setupComplex() {
complex_cls->giveAttr("__floordiv__",
new BoxedFunction(FunctionMetadata::create((void*)complexFloordiv, UNKNOWN, 2)));
complex_cls->giveAttr("__truediv__",
new BoxedFunction(FunctionMetadata::create((void*)complexDivComplex, BOXED_COMPLEX, 2)));
complex_cls->giveAttr("conjugate",
new BoxedFunction(FunctionMetadata::create((void*)complexConjugate, BOXED_COMPLEX, 1)));
complex_cls->giveAttr("__coerce__", new BoxedFunction(FunctionMetadata::create((void*)complexCoerce, UNKNOWN, 2)));
......
......@@ -854,8 +854,14 @@ template <ExceptionStyle S> static BoxedFloat* _floatNew(Box* a) noexcept(S == C
} else if (PyLong_Check(a)) {
double a_f = PyLong_AsDouble(a);
if (a_f == -1.0 && PyErr_Occurred()) {
if (S == CAPI)
return NULL;
else
throwCAPIException();
}
// Make sure that we're not in an error state when we return a non-NULL value.
assert(!PyErr_Occurred());
return new BoxedFloat(a_f);
} else if (a->cls == str_cls || a->cls == unicode_cls) {
BoxedFloat* res = (BoxedFloat*)PyFloat_FromString(a, NULL);
......@@ -928,6 +934,22 @@ template <ExceptionStyle S> Box* floatNew(BoxedClass* _cls, Box* a) noexcept(S =
return new (cls) BoxedFloat(f->d);
}
// Roughly analogous to CPython's float_new.
// The arguments need to be unpacked from args and kwds.
static Box* float_new(BoxedClass* type, Box* args, Box* kwds) noexcept {
PyObject* x = False;
static char* kwlist[2] = { NULL, NULL };
kwlist[0] = const_cast<char*>("x");
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x))
return NULL;
if (x == NULL)
return floatNew<CAPI>(type, None);
else
return floatNew<CAPI>(type, x);
}
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);
......@@ -1602,9 +1624,10 @@ void setupFloat() {
_addFunc("__sub__", BOXED_FLOAT, (void*)floatSubFloat, (void*)floatSubInt, (void*)floatSub);
_addFunc("__rsub__", BOXED_FLOAT, (void*)floatRSubFloat, (void*)floatRSubInt, (void*)floatRSub);
auto float_new = FunctionMetadata::create((void*)floatNew<CXX>, UNKNOWN, 2, false, false, ParamNames::empty(), CXX);
float_new->addVersion((void*)floatNew<CAPI>, UNKNOWN, CAPI);
float_cls->giveAttr("__new__", new BoxedFunction(float_new, { boxFloat(0.0) }));
auto float_new_fm
= FunctionMetadata::create((void*)floatNew<CXX>, UNKNOWN, 2, false, false, ParamNames::empty(), CXX);
float_new_fm->addVersion((void*)floatNew<CAPI>, UNKNOWN, CAPI);
float_cls->giveAttr("__new__", new BoxedFunction(float_new_fm, { boxFloat(0.0) }));
float_cls->giveAttr("__eq__", new BoxedFunction(FunctionMetadata::create((void*)floatEq, UNKNOWN, 2)));
float_cls->giveAttr("__ne__", new BoxedFunction(FunctionMetadata::create((void*)floatNe, UNKNOWN, 2)));
......@@ -1647,6 +1670,7 @@ void setupFloat() {
float_cls->tp_str = float_str;
float_cls->tp_as_number->nb_power = float_pow;
float_cls->tp_new = (newfunc)float_new;
}
void teardownFloat() {
......
......@@ -1046,6 +1046,27 @@ template <ExceptionStyle S> Box* intNew(Box* _cls, Box* val, Box* base) noexcept
return new (cls) BoxedInt(n->n);
}
// Roughly analogous to CPython's int_new.
// The arguments need to be unpacked from args and kwds.
static Box* int_new(BoxedClass* type, Box* args, Box* kwds) noexcept {
PyObject* x = NULL;
int base = -909;
static char* kwlist[3] = { NULL, NULL, NULL };
kwlist[0] = const_cast<char*>("x");
kwlist[1] = const_cast<char*>("base");
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist, &x, &base))
return NULL;
if (x == NULL)
x = None;
if (base == -909)
return intNew<CAPI>(type, x, NULL);
else
return intNew<CAPI>(type, x, boxInt(base));
}
static const unsigned char BitLengthTable[32]
= { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
......@@ -1206,10 +1227,10 @@ void setupInt() {
int_cls->giveAttr("__index__", new BoxedFunction(FunctionMetadata::create((void*)intIndex, BOXED_INT, 1)));
int_cls->giveAttr("__int__", new BoxedFunction(FunctionMetadata::create((void*)intInt, BOXED_INT, 1)));
auto int_new = FunctionMetadata::create((void*)intNew<CXX>, UNKNOWN, 3, false, false,
auto int_new_fm = FunctionMetadata::create((void*)intNew<CXX>, UNKNOWN, 3, false, false,
ParamNames({ "", "x", "base" }, "", ""), CXX);
int_new->addVersion((void*)intNew<CAPI>, UNKNOWN, CAPI);
int_cls->giveAttr("__new__", new BoxedFunction(int_new, { None, NULL }));
int_new_fm->addVersion((void*)intNew<CAPI>, UNKNOWN, CAPI);
int_cls->giveAttr("__new__", new BoxedFunction(int_new_fm, { None, NULL }));
int_cls->giveAttr("bit_length", new BoxedFunction(FunctionMetadata::create((void*)intBitLength, BOXED_INT, 1)));
......@@ -1224,6 +1245,7 @@ void setupInt() {
int_cls->freeze();
int_cls->tp_repr = (reprfunc)int_to_decimal_string;
int_cls->tp_new = (newfunc)int_new;
}
void teardownInt() {
......
......@@ -766,6 +766,26 @@ template <ExceptionStyle S> Box* longNew(Box* _cls, Box* val, Box* base) noexcep
return rtn;
}
// For tp_new, unpack the arguments from args and kwds
static Box* long_new(BoxedClass* type, Box* args, Box* kwds) noexcept {
PyObject* x = NULL;
int base = -909;
static char* kwlist[3] = { NULL, NULL, NULL };
kwlist[0] = const_cast<char*>("x");
kwlist[1] = const_cast<char*>("base");
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:long", kwlist, &x, &base))
return NULL;
if (x == NULL)
x = None;
if (base == -909)
return longNew<CAPI>(type, x, NULL);
else
return longNew<CAPI>(type, x, boxInt(base));
}
Box* longInt(Box* v) {
if (!PyLong_Check(v))
raiseExcHelper(TypeError, "descriptor '__int__' requires a 'long' object but received a '%s'", getTypeName(v));
......@@ -1547,10 +1567,10 @@ void setupLong() {
mp_set_memory_functions(customised_allocation, customised_realloc, customised_free);
_addFuncPow("__pow__", UNKNOWN, (void*)longPowFloat, (void*)longPow);
auto long_new = FunctionMetadata::create((void*)longNew<CXX>, UNKNOWN, 3, false, false,
auto long_new_fm = FunctionMetadata::create((void*)longNew<CXX>, UNKNOWN, 3, false, false,
ParamNames({ "", "x", "base" }, "", ""), CXX);
long_new->addVersion((void*)longNew<CAPI>, UNKNOWN, CAPI);
long_cls->giveAttr("__new__", new BoxedFunction(long_new, { boxInt(0), NULL }));
long_new_fm->addVersion((void*)longNew<CAPI>, UNKNOWN, CAPI);
long_cls->giveAttr("__new__", new BoxedFunction(long_new_fm, { boxInt(0), NULL }));
long_cls->giveAttr("__mul__", new BoxedFunction(FunctionMetadata::create((void*)longMul, UNKNOWN, 2)));
long_cls->giveAttr("__rmul__", long_cls->getattr(internStringMortal("__mul__")));
......@@ -1615,5 +1635,6 @@ void setupLong() {
long_cls->freeze();
long_cls->tp_as_number->nb_power = long_pow;
long_cls->tp_new = (newfunc)long_new;
}
}
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