Commit 4b40c012 authored by Marius Wachtler's avatar Marius Wachtler

Add int.bit_length, function.func_doc, fix '(-1)**0'

parent a58e93a3
...@@ -338,11 +338,8 @@ extern "C" Box* pow_i64_i64(i64 lhs, i64 rhs) { ...@@ -338,11 +338,8 @@ extern "C" Box* pow_i64_i64(i64 lhs, i64 rhs) {
if (rhs < 0) if (rhs < 0)
return boxFloat(pow_float_float(lhs, rhs)); return boxFloat(pow_float_float(lhs, rhs));
if (rhs == 0) { if (rhs == 0)
if (lhs < 0)
return boxInt(-1);
return boxInt(1); return boxInt(1);
}
assert(rhs > 0); assert(rhs > 0);
while (true) { while (true) {
...@@ -1035,6 +1032,34 @@ extern "C" Box* intNew(Box* _cls, Box* val, Box* base) { ...@@ -1035,6 +1032,34 @@ extern "C" Box* intNew(Box* _cls, Box* val, Box* base) {
return new (cls) BoxedInt(n->n); return new (cls) BoxedInt(n->n);
} }
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 };
static int bits_in_ulong(unsigned long d) noexcept {
int d_bits = 0;
while (d >= 32) {
d_bits += 6;
d >>= 6;
}
d_bits += (int)BitLengthTable[d];
return d_bits;
}
extern "C" Box* intBitLength(BoxedInt* v) {
if (!isSubclass(v->cls, int_cls))
raiseExcHelper(TypeError, "descriptor 'bit_length' requires a 'int' object but received a '%s'",
getTypeName(v));
unsigned long n;
if (v->n < 0)
/* avoid undefined behaviour when v->n == -LONG_MAX-1 */
n = 0U - (unsigned long)v->n;
else
n = (unsigned long)v->n;
return PyInt_FromLong(bits_in_ulong(n));
}
static void _addFuncIntFloatUnknown(const char* name, void* int_func, void* float_func, void* boxed_func) { static void _addFuncIntFloatUnknown(const char* name, void* int_func, void* float_func, void* boxed_func) {
std::vector<ConcreteCompilerType*> v_ii, v_if, v_iu; std::vector<ConcreteCompilerType*> v_ii, v_if, v_iu;
assert(BOXED_INT); assert(BOXED_INT);
...@@ -1131,6 +1156,8 @@ void setupInt() { ...@@ -1131,6 +1156,8 @@ void setupInt() {
ParamNames({ "", "x", "base" }, "", "")), ParamNames({ "", "x", "base" }, "", "")),
{ boxInt(0), NULL })); { boxInt(0), NULL }));
int_cls->giveAttr("bit_length", new BoxedFunction(boxRTFunction((void*)intBitLength, BOXED_INT, 1)));
int_cls->giveAttr("real", new (pyston_getset_cls) BoxedGetsetDescriptor(intInt, NULL, NULL)); int_cls->giveAttr("real", new (pyston_getset_cls) BoxedGetsetDescriptor(intInt, NULL, NULL));
int_cls->giveAttr("imag", new (pyston_getset_cls) BoxedGetsetDescriptor(int0, NULL, NULL)); int_cls->giveAttr("imag", new (pyston_getset_cls) BoxedGetsetDescriptor(int0, NULL, NULL));
int_cls->giveAttr("conjugate", new BoxedFunction(boxRTFunction((void*)intInt, BOXED_INT, 1))); int_cls->giveAttr("conjugate", new BoxedFunction(boxRTFunction((void*)intInt, BOXED_INT, 1)));
......
...@@ -2616,6 +2616,7 @@ void setupRuntime() { ...@@ -2616,6 +2616,7 @@ void setupRuntime() {
offsetof(BoxedFunction, modname), false)); offsetof(BoxedFunction, modname), false));
function_cls->giveAttr( function_cls->giveAttr(
"__doc__", new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedFunction, doc), false)); "__doc__", new BoxedMemberDescriptor(BoxedMemberDescriptor::OBJECT, offsetof(BoxedFunction, doc), false));
function_cls->giveAttr("func_doc", function_cls->getattr("__doc__"));
function_cls->giveAttr("__globals__", new (pyston_getset_cls) BoxedGetsetDescriptor(functionGlobals, NULL, NULL)); function_cls->giveAttr("__globals__", new (pyston_getset_cls) BoxedGetsetDescriptor(functionGlobals, NULL, NULL));
function_cls->giveAttr("__get__", new BoxedFunction(boxRTFunction((void*)functionGet, UNKNOWN, 3))); function_cls->giveAttr("__get__", new BoxedFunction(boxRTFunction((void*)functionGet, UNKNOWN, 3)));
function_cls->giveAttr("__call__", function_cls->giveAttr("__call__",
......
# expected: fail
from decimal import Decimal from decimal import Decimal
for d in (Decimal("0.5"), Decimal("0"), Decimal(0), Decimal(1.0)): for d in (Decimal("0.5"), Decimal("0"), Decimal(0), Decimal(1.0)):
......
def f(): def f():
"""very nice function"""
print "f" print "f"
return 2 return 2
print f.__call__() print f.__call__()
print f.__doc__
print f.func_doc
def g(): def g():
print "g" print "g"
return 3 return 3
print g.__doc__
print type(f).__call__(f) print type(f).__call__(f)
print type(f).__call__(g) print type(f).__call__(g)
......
...@@ -12,13 +12,14 @@ for i in xrange(1, 12): ...@@ -12,13 +12,14 @@ for i in xrange(1, 12):
print 1 ** 0 print 1 ** 0
print 0 ** 0 print 0 ** 0
print -1 ** 0 print -1 ** 0, (-1) ** 0, (-5) ** 0
print (11).__pow__(5, 50) print (11).__pow__(5, 50)
print (11).__pow__(32, 50) print (11).__pow__(32, 50)
print (11).__index__() print (11).__index__()
for i in (-10, 10, 0, -15): for i in (-10, 10, 0, -15):
print i, i.__hex__(), i.__oct__() print i, i.__hex__(), i.__oct__()
print i.bit_length()
# Testing int.__new__: # Testing int.__new__:
class C(int): class C(int):
......
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