コード例 #1
0
ファイル: int.cpp プロジェクト: guangwong/pyston
static Box* _intNew(Box* val, Box* base) {
    if (isSubclass(val->cls, int_cls)) {
        RELEASE_ASSERT(!base, "");
        BoxedInt* n = static_cast<BoxedInt*>(val);
        if (val->cls == int_cls)
            return n;
        return new BoxedInt(n->n);
    } else if (isSubclass(val->cls, str_cls)) {
        int base_n;
        if (!base)
            base_n = 10;
        else {
            RELEASE_ASSERT(base->cls == int_cls, "");
            base_n = static_cast<BoxedInt*>(base)->n;
        }

        BoxedString* s = static_cast<BoxedString*>(val);

        RELEASE_ASSERT(s->size() == strlen(s->data()), "");
        Box* r = PyInt_FromString(s->data(), NULL, base_n);
        if (!r)
            throwCAPIException();
        return r;
    } else if (isSubclass(val->cls, unicode_cls)) {
        int base_n;
        if (!base)
            base_n = 10;
        else {
            RELEASE_ASSERT(base->cls == int_cls, "");
            base_n = static_cast<BoxedInt*>(base)->n;
        }

        Box* r = PyInt_FromUnicode(PyUnicode_AS_UNICODE(val), PyUnicode_GET_SIZE(val), base_n);
        if (!r)
            throwCAPIException();
        return r;
    } else if (val->cls == float_cls) {
        RELEASE_ASSERT(!base, "");
        double d = static_cast<BoxedFloat*>(val)->d;
        return new BoxedInt(d);
    } else {
        RELEASE_ASSERT(!base, "");
        static const std::string int_str("__int__");
        Box* r = callattr(val, &int_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }),
                          ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);

        if (!r) {
            fprintf(stderr, "TypeError: int() argument must be a string or a number, not '%s'\n", getTypeName(val));
            raiseExcHelper(TypeError, "");
        }

        if (!isSubclass(r->cls, int_cls) && !isSubclass(r->cls, long_cls)) {
            raiseExcHelper(TypeError, "__int__ returned non-int (type %s)", r->cls->tp_name);
        }
        return r;
    }
コード例 #2
0
ファイル: long.cpp プロジェクト: lameiro/pyston
BoxedLong* _longNew(Box* val, Box* _base) {
    BoxedLong* rtn = new BoxedLong();
    if (_base) {
        if (!isSubclass(_base->cls, int_cls))
            raiseExcHelper(TypeError, "an integer is required");
        int base = static_cast<BoxedInt*>(_base)->n;

        if (!isSubclass(val->cls, str_cls))
            raiseExcHelper(TypeError, "long() can't convert non-string with explicit base");
        BoxedString* s = static_cast<BoxedString*>(val);

        rtn = (BoxedLong*)PyLong_FromString(s->data(), NULL, base);
        checkAndThrowCAPIException();
    } else {
        if (isSubclass(val->cls, long_cls)) {
            BoxedLong* l = static_cast<BoxedLong*>(val);
            if (val->cls == long_cls)
                return l;
            BoxedLong* rtn = new BoxedLong();
            mpz_init_set(rtn->n, l->n);
            return rtn;
        } else if (isSubclass(val->cls, int_cls)) {
            mpz_init_set_si(rtn->n, static_cast<BoxedInt*>(val)->n);
        } else if (val->cls == str_cls) {
            llvm::StringRef s = static_cast<BoxedString*>(val)->s();
            assert(s.data()[s.size()] == '\0');
            int r = mpz_init_set_str(rtn->n, s.data(), 10);
            RELEASE_ASSERT(r == 0, "");
        } else if (val->cls == float_cls) {
            mpz_init_set_si(rtn->n, static_cast<BoxedFloat*>(val)->d);
        } else {
            static BoxedString* long_str = static_cast<BoxedString*>(PyString_InternFromString("__long__"));
            Box* r = callattr(val, long_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }),
                              ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);

            if (!r) {
                fprintf(stderr, "TypeError: long() argument must be a string or a number, not '%s'\n",
                        getTypeName(val));
                raiseExcHelper(TypeError, "");
            }

            if (isSubclass(r->cls, int_cls)) {
                mpz_init_set_si(rtn->n, static_cast<BoxedInt*>(r)->n);
            } else if (!isSubclass(r->cls, long_cls)) {
                raiseExcHelper(TypeError, "__long__ returned non-long (type %s)", r->cls->tp_name);
            } else {
                return static_cast<BoxedLong*>(r);
            }
        }
    }