Commit 6eaa7283 authored by Kevin Modzelewski's avatar Kevin Modzelewski

2-arg form for long()

parent 20ae648b
...@@ -133,7 +133,7 @@ extern "C" BoxedLong* boxLong(int64_t n) { ...@@ -133,7 +133,7 @@ extern "C" BoxedLong* boxLong(int64_t n) {
return rtn; return rtn;
} }
extern "C" Box* longNew(Box* _cls, Box* val) { extern "C" Box* longNew(Box* _cls, Box* val, Box* _base) {
if (!isSubclass(_cls->cls, type_cls)) if (!isSubclass(_cls->cls, type_cls))
raiseExcHelper(TypeError, "long.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str()); raiseExcHelper(TypeError, "long.__new__(X): X is not a type object (%s)", getTypeName(_cls)->c_str());
...@@ -147,16 +147,39 @@ extern "C" Box* longNew(Box* _cls, Box* val) { ...@@ -147,16 +147,39 @@ extern "C" Box* longNew(Box* _cls, Box* val) {
BoxedLong* rtn = ::new (mem) BoxedLong(cls); BoxedLong* rtn = ::new (mem) BoxedLong(cls);
initUserAttrs(rtn, cls); initUserAttrs(rtn, cls);
if (val->cls == int_cls) { if (_base) {
mpz_init_set_si(rtn->n, static_cast<BoxedInt*>(val)->n); if (!isSubclass(_base->cls, int_cls))
} else if (val->cls == str_cls) { raiseExcHelper(TypeError, "an integer is required");
const std::string& s = static_cast<BoxedString*>(val)->s; int base = static_cast<BoxedInt*>(_base)->n;
int r = mpz_init_set_str(rtn->n, s.c_str(), 10);
if (!isSubclass(val->cls, str_cls))
raiseExcHelper(TypeError, "long() can't convert non-string with explicit base");
BoxedString* s = static_cast<BoxedString*>(val);
if (base == 0) {
// mpz_init_set_str has the ability to auto-detect the base, but I doubt it's
// quite the same as Python's (ex might be missing octal or binary)
Py_FatalError("unimplemented");
}
if (base < 2 || base > 36) {
raiseExcHelper(TypeError, "long() arg2 must be >= 2 and <= 36");
}
int r = mpz_init_set_str(rtn->n, s->s.c_str(), base);
RELEASE_ASSERT(r == 0, ""); RELEASE_ASSERT(r == 0, "");
} else { } else {
fprintf(stderr, "TypeError: int() argument must be a string or a number, not '%s'\n", if (val->cls == int_cls) {
getTypeName(val)->c_str()); mpz_init_set_si(rtn->n, static_cast<BoxedInt*>(val)->n);
raiseExcHelper(TypeError, ""); } else if (val->cls == str_cls) {
const std::string& s = static_cast<BoxedString*>(val)->s;
int r = mpz_init_set_str(rtn->n, s.c_str(), 10);
RELEASE_ASSERT(r == 0, "");
} else {
fprintf(stderr, "TypeError: int() argument must be a string or a number, not '%s'\n",
getTypeName(val)->c_str());
raiseExcHelper(TypeError, "");
}
} }
return rtn; return rtn;
} }
...@@ -607,8 +630,8 @@ Box* longNonzero(BoxedLong* self) { ...@@ -607,8 +630,8 @@ Box* longNonzero(BoxedLong* self) {
void setupLong() { void setupLong() {
long_cls->giveAttr("__name__", boxStrConstant("long")); long_cls->giveAttr("__name__", boxStrConstant("long"));
long_cls->giveAttr("__new__", long_cls->giveAttr(
new BoxedFunction(boxRTFunction((void*)longNew, UNKNOWN, 2, 1, false, false), { boxInt(0) })); "__new__", new BoxedFunction(boxRTFunction((void*)longNew, UNKNOWN, 3, 2, false, false), { boxInt(0), NULL }));
long_cls->giveAttr("__mul__", new BoxedFunction(boxRTFunction((void*)longMul, UNKNOWN, 2))); long_cls->giveAttr("__mul__", new BoxedFunction(boxRTFunction((void*)longMul, UNKNOWN, 2)));
long_cls->giveAttr("__rmul__", long_cls->getattr("__mul__")); long_cls->giveAttr("__rmul__", long_cls->getattr("__mul__"));
......
...@@ -41,3 +41,7 @@ try: ...@@ -41,3 +41,7 @@ try:
print (1L) << (-1) print (1L) << (-1)
except ValueError, e: except ValueError, e:
print e print e
print long("100", 16)
print long("100", 10)
print long("100", 26)
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