Commit da9f8db9 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Make bool a proper subclass of int

Required a small amount of object changes, and then a large
number of replacements where we directly compared the class
to int_cls.  We now check that it's a subclass, since you
are allowed to use True/False anywhere that you could use
an int.  ex "xrange(0, n, step=True)"
parent 68af64c1
...@@ -1269,7 +1269,10 @@ public: ...@@ -1269,7 +1269,10 @@ public:
void drop(IREmitter& emitter, VAR* var) override { emitter.getGC()->dropPointer(emitter, var->getValue()); } void drop(IREmitter& emitter, VAR* var) override { emitter.getGC()->dropPointer(emitter, var->getValue()); }
void grab(IREmitter& emitter, VAR* var) override { emitter.getGC()->grabPointer(emitter, var->getValue()); } void grab(IREmitter& emitter, VAR* var) override { emitter.getGC()->grabPointer(emitter, var->getValue()); }
bool isFitBy(BoxedClass* c) override { return c == cls; } bool isFitBy(BoxedClass* c) override {
// I don't think it's ok to accept subclasses
return c == cls;
}
CompilerType* getattrType(const std::string* attr, bool cls_only) override { CompilerType* getattrType(const std::string* attr, bool cls_only) override {
if (cls->is_constant && !cls->instancesHaveAttrs() && cls->hasGenericGetattr()) { if (cls->is_constant && !cls->instancesHaveAttrs() && cls->hasGenericGetattr()) {
......
...@@ -26,24 +26,12 @@ extern "C" PyObject* PyBool_FromLong(long n) { ...@@ -26,24 +26,12 @@ extern "C" PyObject* PyBool_FromLong(long n) {
return boxBool(n != 0); return boxBool(n != 0);
} }
extern "C" Box* boolInvert(BoxedBool* v) {
return boxInt(~v->b);
}
extern "C" Box* boolPos(BoxedBool* v) {
return boxInt(v->b ? 1 : 0);
}
extern "C" Box* boolNeg(BoxedBool* v) {
return boxInt(v->b ? -1 : 0);
}
extern "C" Box* boolNonzero(BoxedBool* v) { extern "C" Box* boolNonzero(BoxedBool* v) {
return v; return v;
} }
extern "C" Box* boolRepr(BoxedBool* v) { extern "C" Box* boolRepr(BoxedBool* v) {
if (v->b) if (v == True)
return boxStrConstant("True"); return boxStrConstant("True");
return boxStrConstant("False"); return boxStrConstant("False");
} }
...@@ -62,9 +50,6 @@ extern "C" Box* boolNew(Box* cls, Box* val) { ...@@ -62,9 +50,6 @@ extern "C" Box* boolNew(Box* cls, Box* val) {
void setupBool() { void setupBool() {
bool_cls->giveAttr("__name__", boxStrConstant("bool")); bool_cls->giveAttr("__name__", boxStrConstant("bool"));
bool_cls->giveAttr("__invert__", new BoxedFunction(boxRTFunction((void*)boolInvert, BOXED_INT, 1)));
bool_cls->giveAttr("__pos__", new BoxedFunction(boxRTFunction((void*)boolPos, BOXED_INT, 1)));
bool_cls->giveAttr("__neg__", new BoxedFunction(boxRTFunction((void*)boolNeg, BOXED_INT, 1)));
bool_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)boolNonzero, BOXED_BOOL, 1))); bool_cls->giveAttr("__nonzero__", new BoxedFunction(boxRTFunction((void*)boolNonzero, BOXED_BOOL, 1)));
bool_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)boolRepr, STR, 1))); bool_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)boolRepr, STR, 1)));
bool_cls->giveAttr("__str__", bool_cls->getattr("__repr__")); bool_cls->giveAttr("__str__", bool_cls->getattr("__repr__"));
......
...@@ -106,7 +106,7 @@ extern "C" Box* vars(Box* obj) { ...@@ -106,7 +106,7 @@ extern "C" Box* vars(Box* obj) {
} }
extern "C" Box* abs_(Box* x) { extern "C" Box* abs_(Box* x) {
if (x->cls == int_cls) { if (isSubclass(x->cls, int_cls)) {
i64 n = static_cast<BoxedInt*>(x)->n; i64 n = static_cast<BoxedInt*>(x)->n;
return boxInt(n >= 0 ? n : -n); return boxInt(n >= 0 ? n : -n);
} else if (x->cls == float_cls) { } else if (x->cls == float_cls) {
...@@ -267,22 +267,22 @@ extern "C" Box* ord(Box* arg) { ...@@ -267,22 +267,22 @@ extern "C" Box* ord(Box* arg) {
Box* range(Box* start, Box* stop, Box* step) { Box* range(Box* start, Box* stop, Box* step) {
i64 istart, istop, istep; i64 istart, istop, istep;
if (stop == NULL) { if (stop == NULL) {
RELEASE_ASSERT(start->cls == int_cls, "%s", getTypeName(start)->c_str()); RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start)->c_str());
istart = 0; istart = 0;
istop = static_cast<BoxedInt*>(start)->n; istop = static_cast<BoxedInt*>(start)->n;
istep = 1; istep = 1;
} else if (step == NULL) { } else if (step == NULL) {
RELEASE_ASSERT(start->cls == int_cls, "%s", getTypeName(start)->c_str()); RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start)->c_str());
RELEASE_ASSERT(stop->cls == int_cls, "%s", getTypeName(stop)->c_str()); RELEASE_ASSERT(isSubclass(stop->cls, int_cls), "%s", getTypeName(stop)->c_str());
istart = static_cast<BoxedInt*>(start)->n; istart = static_cast<BoxedInt*>(start)->n;
istop = static_cast<BoxedInt*>(stop)->n; istop = static_cast<BoxedInt*>(stop)->n;
istep = 1; istep = 1;
} else { } else {
RELEASE_ASSERT(start->cls == int_cls, "%s", getTypeName(start)->c_str()); RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start)->c_str());
RELEASE_ASSERT(stop->cls == int_cls, "%s", getTypeName(stop)->c_str()); RELEASE_ASSERT(isSubclass(stop->cls, int_cls), "%s", getTypeName(stop)->c_str());
RELEASE_ASSERT(step->cls == int_cls, "%s", getTypeName(step)->c_str()); RELEASE_ASSERT(isSubclass(step->cls, int_cls), "%s", getTypeName(step)->c_str());
istart = static_cast<BoxedInt*>(start)->n; istart = static_cast<BoxedInt*>(start)->n;
istop = static_cast<BoxedInt*>(stop)->n; istop = static_cast<BoxedInt*>(stop)->n;
...@@ -607,7 +607,7 @@ public: ...@@ -607,7 +607,7 @@ public:
static Box* new_(Box* cls, Box* obj, Box* start) { static Box* new_(Box* cls, Box* obj, Box* start) {
RELEASE_ASSERT(cls == enumerate_cls, ""); RELEASE_ASSERT(cls == enumerate_cls, "");
RELEASE_ASSERT(start->cls == int_cls, ""); RELEASE_ASSERT(isSubclass(start->cls, int_cls), "");
int64_t idx = static_cast<BoxedInt*>(start)->n; int64_t idx = static_cast<BoxedInt*>(start)->n;
llvm::iterator_range<BoxIterator> range = obj->pyElements(); llvm::iterator_range<BoxIterator> range = obj->pyElements();
......
...@@ -35,7 +35,7 @@ Box* timeTime() { ...@@ -35,7 +35,7 @@ Box* timeTime() {
Box* timeSleep(Box* arg) { Box* timeSleep(Box* arg) {
double secs; double secs;
if (arg->cls == int_cls) if (isSubclass(arg->cls, int_cls))
secs = static_cast<BoxedInt*>(arg)->n; secs = static_cast<BoxedInt*>(arg)->n;
else if (arg->cls == float_cls) else if (arg->cls == float_cls)
secs = static_cast<BoxedFloat*>(arg)->d; secs = static_cast<BoxedFloat*>(arg)->d;
......
...@@ -283,7 +283,8 @@ extern "C" PyObject* PyObject_GetItem(PyObject* o, PyObject* key) { ...@@ -283,7 +283,8 @@ extern "C" PyObject* PyObject_GetItem(PyObject* o, PyObject* key) {
try { try {
return getitem(o, key); return getitem(o, key);
} catch (Box* b) { } catch (Box* b) {
Py_FatalError("unimplemented"); PyErr_SetObject(b->cls, b);
return NULL;
} }
} }
...@@ -488,13 +489,16 @@ void checkAndThrowCAPIException() { ...@@ -488,13 +489,16 @@ void checkAndThrowCAPIException() {
RELEASE_ASSERT(threading::cur_thread_state.curexc_traceback == NULL, "unsupported"); RELEASE_ASSERT(threading::cur_thread_state.curexc_traceback == NULL, "unsupported");
// This doesn't seem like the right behavior... // This doesn't seem like the right behavior...
if (value->cls == tuple_cls) { if (value->cls != threading::cur_thread_state.curexc_type) {
BoxedTuple* args = static_cast<BoxedTuple*>(value); if (value->cls == tuple_cls)
value = runtimeCall(threading::cur_thread_state.curexc_type, ArgPassSpec(0, 0, true, false), args, NULL, value = runtimeCall(threading::cur_thread_state.curexc_type, ArgPassSpec(0, 0, true, false), value,
NULL, NULL, NULL); NULL, NULL, NULL, NULL);
else
value = runtimeCall(threading::cur_thread_state.curexc_type, ArgPassSpec(1), value, NULL, NULL, NULL,
NULL);
} }
RELEASE_ASSERT(value->cls == threading::cur_thread_state.curexc_type, "unsupported");
RELEASE_ASSERT(value->cls == threading::cur_thread_state.curexc_type, "unsupported");
PyErr_Clear(); PyErr_Clear();
throw value; throw value;
} }
...@@ -766,7 +770,7 @@ extern "C" PyObject* PyNumber_ToBase(PyObject* n, int base) { ...@@ -766,7 +770,7 @@ extern "C" PyObject* PyNumber_ToBase(PyObject* n, int base) {
extern "C" Py_ssize_t PyNumber_AsSsize_t(PyObject* o, PyObject* exc) { extern "C" Py_ssize_t PyNumber_AsSsize_t(PyObject* o, PyObject* exc) {
RELEASE_ASSERT(o->cls != long_cls, "unhandled"); RELEASE_ASSERT(o->cls != long_cls, "unhandled");
RELEASE_ASSERT(o->cls == int_cls, "??"); RELEASE_ASSERT(isSubclass(o->cls, int_cls), "??");
int64_t n = static_cast<BoxedInt*>(o)->n; int64_t n = static_cast<BoxedInt*>(o)->n;
static_assert(sizeof(n) == sizeof(Py_ssize_t), ""); static_assert(sizeof(n) == sizeof(Py_ssize_t), "");
return n; return n;
......
...@@ -50,13 +50,13 @@ extern "C" Box* complexAddFloat(BoxedComplex* lhs, BoxedFloat* rhs) { ...@@ -50,13 +50,13 @@ extern "C" Box* complexAddFloat(BoxedComplex* lhs, BoxedFloat* rhs) {
extern "C" Box* complexAddInt(BoxedComplex* lhs, BoxedInt* rhs) { extern "C" Box* complexAddInt(BoxedComplex* lhs, BoxedInt* rhs) {
assert(lhs->cls == complex_cls); assert(lhs->cls == complex_cls);
assert(rhs->cls == int_cls); assert(isSubclass(rhs->cls, int_cls));
return boxComplex(lhs->real + (double)rhs->n, lhs->imag); return boxComplex(lhs->real + (double)rhs->n, lhs->imag);
} }
extern "C" Box* complexAdd(BoxedComplex* lhs, Box* rhs) { extern "C" Box* complexAdd(BoxedComplex* lhs, Box* rhs) {
assert(lhs->cls == complex_cls); assert(lhs->cls == complex_cls);
if (rhs->cls == int_cls) { if (isSubclass(rhs->cls, int_cls)) {
return complexAddInt(lhs, static_cast<BoxedInt*>(rhs)); return complexAddInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) { } else if (rhs->cls == float_cls) {
return complexAddFloat(lhs, static_cast<BoxedFloat*>(rhs)); return complexAddFloat(lhs, static_cast<BoxedFloat*>(rhs));
...@@ -83,13 +83,13 @@ extern "C" Box* complexSubFloat(BoxedComplex* lhs, BoxedFloat* rhs) { ...@@ -83,13 +83,13 @@ extern "C" Box* complexSubFloat(BoxedComplex* lhs, BoxedFloat* rhs) {
extern "C" Box* complexSubInt(BoxedComplex* lhs, BoxedInt* rhs) { extern "C" Box* complexSubInt(BoxedComplex* lhs, BoxedInt* rhs) {
assert(lhs->cls == complex_cls); assert(lhs->cls == complex_cls);
assert(rhs->cls == int_cls); assert(isSubclass(rhs->cls, int_cls));
return boxComplex(lhs->real - (double)rhs->n, lhs->imag); return boxComplex(lhs->real - (double)rhs->n, lhs->imag);
} }
extern "C" Box* complexSub(BoxedComplex* lhs, Box* rhs) { extern "C" Box* complexSub(BoxedComplex* lhs, Box* rhs) {
assert(lhs->cls == complex_cls); assert(lhs->cls == complex_cls);
if (rhs->cls == int_cls) { if (isSubclass(rhs->cls, int_cls)) {
return complexSubInt(lhs, static_cast<BoxedInt*>(rhs)); return complexSubInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) { } else if (rhs->cls == float_cls) {
return complexSubFloat(lhs, static_cast<BoxedFloat*>(rhs)); return complexSubFloat(lhs, static_cast<BoxedFloat*>(rhs));
...@@ -116,13 +116,13 @@ extern "C" Box* complexMulFloat(BoxedComplex* lhs, BoxedFloat* rhs) { ...@@ -116,13 +116,13 @@ extern "C" Box* complexMulFloat(BoxedComplex* lhs, BoxedFloat* rhs) {
extern "C" Box* complexMulInt(BoxedComplex* lhs, BoxedInt* rhs) { extern "C" Box* complexMulInt(BoxedComplex* lhs, BoxedInt* rhs) {
assert(lhs->cls == complex_cls); assert(lhs->cls == complex_cls);
assert(rhs->cls == int_cls); assert(isSubclass(rhs->cls, int_cls));
return boxComplex(lhs->real * (double)rhs->n, lhs->imag * (double)rhs->n); return boxComplex(lhs->real * (double)rhs->n, lhs->imag * (double)rhs->n);
} }
extern "C" Box* complexMul(BoxedComplex* lhs, Box* rhs) { extern "C" Box* complexMul(BoxedComplex* lhs, Box* rhs) {
assert(lhs->cls == complex_cls); assert(lhs->cls == complex_cls);
if (rhs->cls == int_cls) { if (isSubclass(rhs->cls, int_cls)) {
return complexMulInt(lhs, static_cast<BoxedInt*>(rhs)); return complexMulInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) { } else if (rhs->cls == float_cls) {
return complexMulFloat(lhs, static_cast<BoxedFloat*>(rhs)); return complexMulFloat(lhs, static_cast<BoxedFloat*>(rhs));
...@@ -153,7 +153,7 @@ extern "C" Box* complexDivFloat(BoxedComplex* lhs, BoxedFloat* rhs) { ...@@ -153,7 +153,7 @@ extern "C" Box* complexDivFloat(BoxedComplex* lhs, BoxedFloat* rhs) {
extern "C" Box* complexDivInt(BoxedComplex* lhs, BoxedInt* rhs) { extern "C" Box* complexDivInt(BoxedComplex* lhs, BoxedInt* rhs) {
assert(lhs->cls == complex_cls); assert(lhs->cls == complex_cls);
assert(rhs->cls == int_cls); assert(isSubclass(rhs->cls, int_cls));
if (rhs->n == 0) { if (rhs->n == 0) {
raiseDivZeroExc(); raiseDivZeroExc();
} }
...@@ -162,7 +162,7 @@ extern "C" Box* complexDivInt(BoxedComplex* lhs, BoxedInt* rhs) { ...@@ -162,7 +162,7 @@ extern "C" Box* complexDivInt(BoxedComplex* lhs, BoxedInt* rhs) {
extern "C" Box* complexDiv(BoxedComplex* lhs, Box* rhs) { extern "C" Box* complexDiv(BoxedComplex* lhs, Box* rhs) {
assert(lhs->cls == complex_cls); assert(lhs->cls == complex_cls);
if (rhs->cls == int_cls) { if (isSubclass(rhs->cls, int_cls)) {
return complexDivInt(lhs, static_cast<BoxedInt*>(rhs)); return complexDivInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) { } else if (rhs->cls == float_cls) {
return complexDivFloat(lhs, static_cast<BoxedFloat*>(rhs)); return complexDivFloat(lhs, static_cast<BoxedFloat*>(rhs));
...@@ -212,7 +212,7 @@ Box* complexNew(Box* _cls, Box* real, Box* imag) { ...@@ -212,7 +212,7 @@ Box* complexNew(Box* _cls, Box* real, Box* imag) {
RELEASE_ASSERT(_cls == complex_cls, ""); RELEASE_ASSERT(_cls == complex_cls, "");
double real_f; double real_f;
if (real->cls == int_cls) { if (isSubclass(real->cls, int_cls)) {
real_f = static_cast<BoxedInt*>(real)->n; real_f = static_cast<BoxedInt*>(real)->n;
} else if (real->cls == float_cls) { } else if (real->cls == float_cls) {
real_f = static_cast<BoxedFloat*>(real)->d; real_f = static_cast<BoxedFloat*>(real)->d;
...@@ -222,7 +222,7 @@ Box* complexNew(Box* _cls, Box* real, Box* imag) { ...@@ -222,7 +222,7 @@ Box* complexNew(Box* _cls, Box* real, Box* imag) {
} }
double imag_f; double imag_f;
if (imag->cls == int_cls) { if (isSubclass(imag->cls, int_cls)) {
imag_f = static_cast<BoxedInt*>(imag)->n; imag_f = static_cast<BoxedInt*>(imag)->n;
} else if (imag->cls == float_cls) { } else if (imag->cls == float_cls) {
imag_f = static_cast<BoxedFloat*>(imag)->d; imag_f = static_cast<BoxedFloat*>(imag)->d;
......
This diff is collapsed.
...@@ -81,21 +81,21 @@ Box* xrange(Box* cls, Box* start, Box* stop, Box** args) { ...@@ -81,21 +81,21 @@ Box* xrange(Box* cls, Box* start, Box* stop, Box** args) {
Box* step = args[0]; Box* step = args[0];
if (stop == NULL) { if (stop == NULL) {
RELEASE_ASSERT(start->cls == int_cls, "%s", getTypeName(start)->c_str()); RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start)->c_str());
i64 istop = static_cast<BoxedInt*>(start)->n; i64 istop = static_cast<BoxedInt*>(start)->n;
return new BoxedXrange(0, istop, 1); return new BoxedXrange(0, istop, 1);
} else if (step == NULL) { } else if (step == NULL) {
RELEASE_ASSERT(start->cls == int_cls, "%s", getTypeName(start)->c_str()); RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start)->c_str());
RELEASE_ASSERT(stop->cls == int_cls, "%s", getTypeName(stop)->c_str()); RELEASE_ASSERT(isSubclass(stop->cls, int_cls), "%s", getTypeName(stop)->c_str());
i64 istart = static_cast<BoxedInt*>(start)->n; i64 istart = static_cast<BoxedInt*>(start)->n;
i64 istop = static_cast<BoxedInt*>(stop)->n; i64 istop = static_cast<BoxedInt*>(stop)->n;
return new BoxedXrange(istart, istop, 1); return new BoxedXrange(istart, istop, 1);
} else { } else {
RELEASE_ASSERT(start->cls == int_cls, "%s", getTypeName(start)->c_str()); RELEASE_ASSERT(isSubclass(start->cls, int_cls), "%s", getTypeName(start)->c_str());
RELEASE_ASSERT(stop->cls == int_cls, "%s", getTypeName(stop)->c_str()); RELEASE_ASSERT(isSubclass(stop->cls, int_cls), "%s", getTypeName(stop)->c_str());
RELEASE_ASSERT(step->cls == int_cls, "%s", getTypeName(step)->c_str()); RELEASE_ASSERT(isSubclass(step->cls, int_cls), "%s", getTypeName(step)->c_str());
i64 istart = static_cast<BoxedInt*>(start)->n; i64 istart = static_cast<BoxedInt*>(start)->n;
i64 istop = static_cast<BoxedInt*>(stop)->n; i64 istop = static_cast<BoxedInt*>(stop)->n;
......
This diff is collapsed.
...@@ -140,7 +140,7 @@ extern "C" Box* listGetitemUnboxed(BoxedList* self, int64_t n) { ...@@ -140,7 +140,7 @@ extern "C" Box* listGetitemUnboxed(BoxedList* self, int64_t n) {
} }
extern "C" Box* listGetitemInt(BoxedList* self, BoxedInt* slice) { extern "C" Box* listGetitemInt(BoxedList* self, BoxedInt* slice) {
assert(slice->cls == int_cls); assert(isSubclass(slice->cls, int_cls));
return listGetitemUnboxed(self, slice->n); return listGetitemUnboxed(self, slice->n);
} }
...@@ -166,7 +166,7 @@ extern "C" Box* listGetitemSlice(BoxedList* self, BoxedSlice* slice) { ...@@ -166,7 +166,7 @@ extern "C" Box* listGetitemSlice(BoxedList* self, BoxedSlice* slice) {
extern "C" Box* listGetitem(BoxedList* self, Box* slice) { extern "C" Box* listGetitem(BoxedList* self, Box* slice) {
assert(self->cls == list_cls); assert(self->cls == list_cls);
if (slice->cls == int_cls) { if (isSubclass(slice->cls, int_cls)) {
return listGetitemInt(self, static_cast<BoxedInt*>(slice)); return listGetitemInt(self, static_cast<BoxedInt*>(slice));
} else if (slice->cls == slice_cls) { } else if (slice->cls == slice_cls) {
return listGetitemSlice(self, static_cast<BoxedSlice*>(slice)); return listGetitemSlice(self, static_cast<BoxedSlice*>(slice));
...@@ -181,7 +181,7 @@ extern "C" Box* listSetitemInt(BoxedList* self, BoxedInt* slice, Box* v) { ...@@ -181,7 +181,7 @@ extern "C" Box* listSetitemInt(BoxedList* self, BoxedInt* slice, Box* v) {
LOCK_REGION(self->lock.asRead()); LOCK_REGION(self->lock.asRead());
assert(self->cls == list_cls); assert(self->cls == list_cls);
assert(slice->cls == int_cls); assert(isSubclass(slice->cls, int_cls));
int64_t n = slice->n; int64_t n = slice->n;
if (n < 0) if (n < 0)
n = self->size + n; n = self->size + n;
...@@ -229,7 +229,7 @@ extern "C" Box* listSetitemSlice(BoxedList* self, BoxedSlice* slice, Box* v) { ...@@ -229,7 +229,7 @@ extern "C" Box* listSetitemSlice(BoxedList* self, BoxedSlice* slice, Box* v) {
extern "C" Box* listSetitem(BoxedList* self, Box* slice, Box* v) { extern "C" Box* listSetitem(BoxedList* self, Box* slice, Box* v) {
assert(self->cls == list_cls); assert(self->cls == list_cls);
if (slice->cls == int_cls) { if (isSubclass(slice->cls, int_cls)) {
return listSetitemInt(self, static_cast<BoxedInt*>(slice), v); return listSetitemInt(self, static_cast<BoxedInt*>(slice), v);
} else if (slice->cls == slice_cls) { } else if (slice->cls == slice_cls) {
return listSetitemSlice(self, static_cast<BoxedSlice*>(slice), v); return listSetitemSlice(self, static_cast<BoxedSlice*>(slice), v);
...@@ -276,7 +276,7 @@ extern "C" Box* listDelitem(BoxedList* self, Box* slice) { ...@@ -276,7 +276,7 @@ extern "C" Box* listDelitem(BoxedList* self, Box* slice) {
Box* rtn; Box* rtn;
if (slice->cls == int_cls) { if (isSubclass(slice->cls, int_cls)) {
rtn = listDelitemInt(self, static_cast<BoxedInt*>(slice)); rtn = listDelitemInt(self, static_cast<BoxedInt*>(slice));
} else if (slice->cls == slice_cls) { } else if (slice->cls == slice_cls) {
rtn = listDelitemSlice(self, static_cast<BoxedSlice*>(slice)); rtn = listDelitemSlice(self, static_cast<BoxedSlice*>(slice));
......
...@@ -215,7 +215,7 @@ extern "C" Box* longNew(Box* _cls, Box* val, Box* _base) { ...@@ -215,7 +215,7 @@ extern "C" Box* longNew(Box* _cls, Box* val, Box* _base) {
int r = mpz_init_set_str(rtn->n, s->s.c_str(), base); int r = mpz_init_set_str(rtn->n, s->s.c_str(), base);
RELEASE_ASSERT(r == 0, ""); RELEASE_ASSERT(r == 0, "");
} else { } else {
if (val->cls == int_cls) { if (isSubclass(val->cls, int_cls)) {
mpz_init_set_si(rtn->n, static_cast<BoxedInt*>(val)->n); mpz_init_set_si(rtn->n, static_cast<BoxedInt*>(val)->n);
} else if (val->cls == str_cls) { } else if (val->cls == str_cls) {
const std::string& s = static_cast<BoxedString*>(val)->s; const std::string& s = static_cast<BoxedString*>(val)->s;
......
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
#define ATTRLIST_KIND_OFFSET ((char*)&(((HCAttrs::AttrList*)0x01)->gc_header.kind_id) - (char*)0x1) #define ATTRLIST_KIND_OFFSET ((char*)&(((HCAttrs::AttrList*)0x01)->gc_header.kind_id) - (char*)0x1)
#define INSTANCEMETHOD_FUNC_OFFSET ((char*)&(((BoxedInstanceMethod*)0x01)->func) - (char*)0x1) #define INSTANCEMETHOD_FUNC_OFFSET ((char*)&(((BoxedInstanceMethod*)0x01)->func) - (char*)0x1)
#define INSTANCEMETHOD_OBJ_OFFSET ((char*)&(((BoxedInstanceMethod*)0x01)->obj) - (char*)0x1) #define INSTANCEMETHOD_OBJ_OFFSET ((char*)&(((BoxedInstanceMethod*)0x01)->obj) - (char*)0x1)
#define BOOL_B_OFFSET ((char*)&(((BoxedBool*)0x01)->b) - (char*)0x1) #define BOOL_B_OFFSET ((char*)&(((BoxedBool*)0x01)->n) - (char*)0x1)
#define INT_N_OFFSET ((char*)&(((BoxedInt*)0x01)->n) - (char*)0x1) #define INT_N_OFFSET ((char*)&(((BoxedInt*)0x01)->n) - (char*)0x1)
namespace pyston { namespace pyston {
...@@ -209,18 +209,14 @@ bool PyEq::operator()(Box* lhs, Box* rhs) const { ...@@ -209,18 +209,14 @@ bool PyEq::operator()(Box* lhs, Box* rhs) const {
// TODO fix this // TODO fix this
Box* cmp = compareInternal(lhs, rhs, AST_TYPE::Eq, NULL); Box* cmp = compareInternal(lhs, rhs, AST_TYPE::Eq, NULL);
assert(cmp->cls == bool_cls); assert(cmp->cls == bool_cls);
BoxedBool* b = static_cast<BoxedBool*>(cmp); return cmp == True;
bool rtn = b->b;
return rtn;
} }
bool PyLt::operator()(Box* lhs, Box* rhs) const { bool PyLt::operator()(Box* lhs, Box* rhs) const {
// TODO fix this // TODO fix this
Box* cmp = compareInternal(lhs, rhs, AST_TYPE::Lt, NULL); Box* cmp = compareInternal(lhs, rhs, AST_TYPE::Lt, NULL);
assert(cmp->cls == bool_cls); assert(cmp->cls == bool_cls);
BoxedBool* b = static_cast<BoxedBool*>(cmp); return cmp == True;
bool rtn = b->b;
return rtn;
} }
extern "C" bool softspace(Box* b, bool newval) { extern "C" bool softspace(Box* b, bool newval) {
...@@ -1568,13 +1564,14 @@ extern "C" bool nonzero(Box* obj) { ...@@ -1568,13 +1564,14 @@ extern "C" bool nonzero(Box* obj) {
} }
if (obj->cls == bool_cls) { if (obj->cls == bool_cls) {
// TODO: is it faster to compare to True? (especially since it will be a constant we can embed in the rewrite)
if (rewriter.get()) { if (rewriter.get()) {
RewriterVar* b = r_obj->getAttr(BOOL_B_OFFSET, rewriter->getReturnDestination()); RewriterVar* b = r_obj->getAttr(BOOL_B_OFFSET, rewriter->getReturnDestination());
rewriter->commitReturning(b); rewriter->commitReturning(b);
} }
BoxedBool* bool_obj = static_cast<BoxedBool*>(obj); BoxedBool* bool_obj = static_cast<BoxedBool*>(obj);
return bool_obj->b; return bool_obj->n;
} else if (obj->cls == int_cls) { } else if (obj->cls == int_cls) {
if (rewriter.get()) { if (rewriter.get()) {
// TODO should do: // TODO should do:
...@@ -1623,7 +1620,7 @@ extern "C" bool nonzero(Box* obj) { ...@@ -1623,7 +1620,7 @@ extern "C" bool nonzero(Box* obj) {
Box* r = runtimeCall0(func, ArgPassSpec(0)); Box* r = runtimeCall0(func, ArgPassSpec(0));
if (r->cls == bool_cls) { if (r->cls == bool_cls) {
BoxedBool* b = static_cast<BoxedBool*>(r); BoxedBool* b = static_cast<BoxedBool*>(r);
bool rtn = b->b; bool rtn = b->n;
return rtn; return rtn;
} else if (r->cls == int_cls) { } else if (r->cls == int_cls) {
BoxedInt* b = static_cast<BoxedInt*>(r); BoxedInt* b = static_cast<BoxedInt*>(r);
......
...@@ -163,7 +163,7 @@ extern "C" Box* strMod(BoxedString* lhs, Box* rhs) { ...@@ -163,7 +163,7 @@ extern "C" Box* strMod(BoxedString* lhs, Box* rhs) {
elt_num++; elt_num++;
} }
RELEASE_ASSERT(val_to_use->cls == int_cls, "unsupported"); RELEASE_ASSERT(isSubclass(val_to_use->cls, int_cls), "unsupported");
RELEASE_ASSERT(nspace == 0, "unsupported"); RELEASE_ASSERT(nspace == 0, "unsupported");
RELEASE_ASSERT(ndot == 0, "unsupported"); RELEASE_ASSERT(ndot == 0, "unsupported");
RELEASE_ASSERT(nzero == 0, "unsupported"); RELEASE_ASSERT(nzero == 0, "unsupported");
...@@ -183,7 +183,7 @@ extern "C" Box* strMod(BoxedString* lhs, Box* rhs) { ...@@ -183,7 +183,7 @@ extern "C" Box* strMod(BoxedString* lhs, Box* rhs) {
elt_num++; elt_num++;
} }
RELEASE_ASSERT(val_to_use->cls == int_cls, "unsupported"); RELEASE_ASSERT(isSubclass(val_to_use->cls, int_cls), "unsupported");
std::ostringstream fmt(""); std::ostringstream fmt("");
fmt << '%'; fmt << '%';
...@@ -210,7 +210,7 @@ extern "C" Box* strMod(BoxedString* lhs, Box* rhs) { ...@@ -210,7 +210,7 @@ extern "C" Box* strMod(BoxedString* lhs, Box* rhs) {
double d; double d;
if (val_to_use->cls == float_cls) { if (val_to_use->cls == float_cls) {
d = static_cast<BoxedFloat*>(val_to_use)->d; d = static_cast<BoxedFloat*>(val_to_use)->d;
} else if (val_to_use->cls == int_cls) { } else if (isSubclass(val_to_use->cls, int_cls)) {
d = static_cast<BoxedInt*>(val_to_use)->n; d = static_cast<BoxedInt*>(val_to_use)->n;
} else { } else {
RELEASE_ASSERT(0, "unsupported"); RELEASE_ASSERT(0, "unsupported");
...@@ -251,8 +251,6 @@ extern "C" Box* strMul(BoxedString* lhs, Box* rhs) { ...@@ -251,8 +251,6 @@ extern "C" Box* strMul(BoxedString* lhs, Box* rhs) {
int n; int n;
if (isSubclass(rhs->cls, int_cls)) if (isSubclass(rhs->cls, int_cls))
n = static_cast<BoxedInt*>(rhs)->n; n = static_cast<BoxedInt*>(rhs)->n;
else if (isSubclass(rhs->cls, bool_cls))
n = static_cast<BoxedBool*>(rhs)->b;
else else
return NotImplemented; return NotImplemented;
...@@ -622,7 +620,7 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) { ...@@ -622,7 +620,7 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
Box* _count = _args[0]; Box* _count = _args[0];
RELEASE_ASSERT(_count->cls == int_cls, "an integer is required"); RELEASE_ASSERT(isSubclass(_count->cls, int_cls), "an integer is required");
BoxedInt* count = static_cast<BoxedInt*>(_count); BoxedInt* count = static_cast<BoxedInt*>(_count);
RELEASE_ASSERT(count->n < 0, "'count' argument unsupported"); RELEASE_ASSERT(count->n < 0, "'count' argument unsupported");
...@@ -696,7 +694,7 @@ Box* strSplit(BoxedString* self, BoxedString* sep, BoxedInt* _max_split) { ...@@ -696,7 +694,7 @@ Box* strSplit(BoxedString* self, BoxedString* sep, BoxedInt* _max_split) {
Box* strRsplit(BoxedString* self, BoxedString* sep, BoxedInt* _max_split) { Box* strRsplit(BoxedString* self, BoxedString* sep, BoxedInt* _max_split) {
// TODO: implement this for real // TODO: implement this for real
// for now, just forward rsplit() to split() in the cases they have to return the same value // for now, just forward rsplit() to split() in the cases they have to return the same value
assert(_max_split->cls == int_cls); assert(isSubclass(_max_split->cls, int_cls));
RELEASE_ASSERT(_max_split->n <= 0, ""); RELEASE_ASSERT(_max_split->n <= 0, "");
return strSplit(self, sep, _max_split); return strSplit(self, sep, _max_split);
} }
...@@ -834,7 +832,7 @@ Box* strContains(BoxedString* self, Box* elt) { ...@@ -834,7 +832,7 @@ Box* strContains(BoxedString* self, Box* elt) {
Box* strStartswith(BoxedString* self, Box* elt) { Box* strStartswith(BoxedString* self, Box* elt) {
if (self->cls != str_cls) if (self->cls != str_cls)
raiseExcHelper(TypeError, "descriptor 'startswith' requires a 'str' object but received a '%s'", raiseExcHelper(TypeError, "descriptor 'startswith' requires a 'str' object but received a '%s'",
getTypeName(elt)->c_str()); getTypeName(self)->c_str());
if (elt->cls != str_cls) if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object"); raiseExcHelper(TypeError, "expected a character buffer object");
...@@ -847,7 +845,7 @@ Box* strStartswith(BoxedString* self, Box* elt) { ...@@ -847,7 +845,7 @@ Box* strStartswith(BoxedString* self, Box* elt) {
Box* strEndswith(BoxedString* self, Box* elt) { Box* strEndswith(BoxedString* self, Box* elt) {
if (self->cls != str_cls) if (self->cls != str_cls)
raiseExcHelper(TypeError, "descriptor 'endswith' requires a 'str' object but received a '%s'", raiseExcHelper(TypeError, "descriptor 'endswith' requires a 'str' object but received a '%s'",
getTypeName(elt)->c_str()); getTypeName(self)->c_str());
if (elt->cls != str_cls) if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object"); raiseExcHelper(TypeError, "expected a character buffer object");
...@@ -860,7 +858,7 @@ Box* strEndswith(BoxedString* self, Box* elt) { ...@@ -860,7 +858,7 @@ Box* strEndswith(BoxedString* self, Box* elt) {
Box* strFind(BoxedString* self, Box* elt, Box* _start) { Box* strFind(BoxedString* self, Box* elt, Box* _start) {
if (self->cls != str_cls) if (self->cls != str_cls)
raiseExcHelper(TypeError, "descriptor 'find' requires a 'str' object but received a '%s'", raiseExcHelper(TypeError, "descriptor 'find' requires a 'str' object but received a '%s'",
getTypeName(elt)->c_str()); getTypeName(self)->c_str());
if (elt->cls != str_cls) if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object"); raiseExcHelper(TypeError, "expected a character buffer object");
...@@ -888,7 +886,7 @@ Box* strFind(BoxedString* self, Box* elt, Box* _start) { ...@@ -888,7 +886,7 @@ Box* strFind(BoxedString* self, Box* elt, Box* _start) {
Box* strRfind(BoxedString* self, Box* elt) { Box* strRfind(BoxedString* self, Box* elt) {
if (self->cls != str_cls) if (self->cls != str_cls)
raiseExcHelper(TypeError, "descriptor 'rfind' requires a 'str' object but received a '%s'", raiseExcHelper(TypeError, "descriptor 'rfind' requires a 'str' object but received a '%s'",
getTypeName(elt)->c_str()); getTypeName(self)->c_str());
if (elt->cls != str_cls) if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object"); raiseExcHelper(TypeError, "expected a character buffer object");
...@@ -905,7 +903,7 @@ Box* strRfind(BoxedString* self, Box* elt) { ...@@ -905,7 +903,7 @@ Box* strRfind(BoxedString* self, Box* elt) {
extern "C" Box* strGetitem(BoxedString* self, Box* slice) { extern "C" Box* strGetitem(BoxedString* self, Box* slice) {
assert(self->cls == str_cls); assert(self->cls == str_cls);
if (slice->cls == int_cls) { if (isSubclass(slice->cls, int_cls)) {
BoxedInt* islice = static_cast<BoxedInt*>(slice); BoxedInt* islice = static_cast<BoxedInt*>(slice);
int64_t n = islice->n; int64_t n = islice->n;
int size = self->s.size(); int size = self->s.size();
......
...@@ -108,7 +108,7 @@ extern "C" PyObject* PyTuple_GetSlice(PyObject* p, Py_ssize_t low, Py_ssize_t hi ...@@ -108,7 +108,7 @@ extern "C" PyObject* PyTuple_GetSlice(PyObject* p, Py_ssize_t low, Py_ssize_t hi
Box* tupleGetitem(BoxedTuple* self, Box* slice) { Box* tupleGetitem(BoxedTuple* self, Box* slice) {
assert(self->cls == tuple_cls); assert(self->cls == tuple_cls);
if (slice->cls == int_cls) if (isSubclass(slice->cls, int_cls))
return tupleGetitemInt(self, static_cast<BoxedInt*>(slice)); return tupleGetitemInt(self, static_cast<BoxedInt*>(slice));
else if (slice->cls == slice_cls) else if (slice->cls == slice_cls)
return tupleGetitemSlice(self, static_cast<BoxedSlice*>(slice)); return tupleGetitemSlice(self, static_cast<BoxedSlice*>(slice));
...@@ -289,7 +289,7 @@ Box* tupleHash(BoxedTuple* self) { ...@@ -289,7 +289,7 @@ Box* tupleHash(BoxedTuple* self) {
int64_t rtn = 3527539; int64_t rtn = 3527539;
for (Box* e : self->elts) { for (Box* e : self->elts) {
BoxedInt* h = hash(e); BoxedInt* h = hash(e);
assert(h->cls == int_cls); assert(isSubclass(h->cls, int_cls));
rtn ^= h->n + 0x9e3779b9 + (rtn << 6) + (rtn >> 2); rtn ^= h->n + 0x9e3779b9 + (rtn << 6) + (rtn >> 2);
} }
......
...@@ -825,8 +825,8 @@ void setupRuntime() { ...@@ -825,8 +825,8 @@ void setupRuntime() {
// TODO it'd be nice to be able to do these in the respective setupType methods, // TODO it'd be nice to be able to do these in the respective setupType methods,
// but those setup methods probably want access to these objects. // but those setup methods probably want access to these objects.
// We could have a multi-stage setup process, but that seems overkill for now. // We could have a multi-stage setup process, but that seems overkill for now.
bool_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedBool), false);
int_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedInt), false); int_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedInt), false);
bool_cls = new BoxedHeapClass(type_cls, int_cls, NULL, 0, sizeof(BoxedBool), false);
complex_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedComplex), false); complex_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedComplex), false);
// TODO we're leaking long memory! // TODO we're leaking long memory!
long_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedLong), false); long_cls = new BoxedHeapClass(type_cls, object_cls, NULL, 0, sizeof(BoxedLong), false);
......
...@@ -308,11 +308,9 @@ public: ...@@ -308,11 +308,9 @@ public:
BoxedComplex(double r, double i) __attribute__((visibility("default"))) : Box(complex_cls), real(r), imag(i) {} BoxedComplex(double r, double i) __attribute__((visibility("default"))) : Box(complex_cls), real(r), imag(i) {}
}; };
class BoxedBool : public Box { class BoxedBool : public BoxedInt {
public: public:
bool b; BoxedBool(bool b) __attribute__((visibility("default"))) : BoxedInt(bool_cls, b ? 1 : 0) {}
BoxedBool(bool b) __attribute__((visibility("default"))) : Box(bool_cls), b(b) {}
}; };
class BoxedString : public Box { class BoxedString : public Box {
......
...@@ -30,22 +30,22 @@ void parseSlice(BoxedSlice* slice, int size, i64* out_start, i64* out_stop, i64* ...@@ -30,22 +30,22 @@ void parseSlice(BoxedSlice* slice, int size, i64* out_start, i64* out_stop, i64*
Box* step = sslice->step; Box* step = sslice->step;
assert(step); assert(step);
RELEASE_ASSERT(start->cls == int_cls || start->cls == none_cls, ""); RELEASE_ASSERT(isSubclass(start->cls, int_cls) || start->cls == none_cls, "");
RELEASE_ASSERT(stop->cls == int_cls || stop->cls == none_cls, ""); RELEASE_ASSERT(isSubclass(stop->cls, int_cls) || stop->cls == none_cls, "");
RELEASE_ASSERT(step->cls == int_cls || step->cls == none_cls, ""); RELEASE_ASSERT(isSubclass(step->cls, int_cls) || step->cls == none_cls, "");
int64_t istart; int64_t istart;
int64_t istop; int64_t istop;
int64_t istep = 1; int64_t istep = 1;
if (step->cls == int_cls) { if (isSubclass(step->cls, int_cls)) {
istep = static_cast<BoxedInt*>(step)->n; istep = static_cast<BoxedInt*>(step)->n;
if (istep == 0) { if (istep == 0) {
raiseExcHelper(ValueError, "slice step cannot be zero"); raiseExcHelper(ValueError, "slice step cannot be zero");
} }
} }
if (start->cls == int_cls) { if (isSubclass(start->cls, int_cls)) {
istart = static_cast<BoxedInt*>(start)->n; istart = static_cast<BoxedInt*>(start)->n;
if (istart < 0) if (istart < 0)
istart = size + istart; istart = size + istart;
...@@ -55,7 +55,7 @@ void parseSlice(BoxedSlice* slice, int size, i64* out_start, i64* out_stop, i64* ...@@ -55,7 +55,7 @@ void parseSlice(BoxedSlice* slice, int size, i64* out_start, i64* out_stop, i64*
else else
istart = size - 1; istart = size - 1;
} }
if (stop->cls == int_cls) { if (isSubclass(stop->cls, int_cls)) {
istop = static_cast<BoxedInt*>(stop)->n; istop = static_cast<BoxedInt*>(stop)->n;
if (istop < 0) if (istop < 0)
istop = size + istop; istop = size + istop;
......
...@@ -15,3 +15,6 @@ print int(1.9) ...@@ -15,3 +15,6 @@ print int(1.9)
print int(-1.1) print int(-1.1)
print int(-1.5) print int(-1.5)
print int(-1.9) print int(-1.9)
print int(True)
print int(False)
...@@ -15,3 +15,28 @@ f(()) ...@@ -15,3 +15,28 @@ f(())
f("") f("")
f(0.0) f(0.0)
f(1L) f(1L)
# Bools are subclasses of ints:
print 1 == True
print 0 == False
print 1 == False
print 0 == True
print True == 0
print type(hash(True))
print hash(0) == hash(False)
print hash(1) == hash(True)
print isinstance(True, int)
print isinstance(False, int)
print range(False, True, True)
print abs(True), abs(False)
d = {}
d[1] = "hello"
d[False] = "world"
print d[True], d[0]
print long(True), float(False)
1.0 + True
# expected: fail
# - C API exceptions are not yet supported
import math import math
print math.sqrt(-1) try:
print math.sqrt(-1)
except ValueError, e:
print e
...@@ -76,3 +76,5 @@ for i in xrange(-10, 10): ...@@ -76,3 +76,5 @@ for i in xrange(-10, 10):
print "hello world".partition("hi") print "hello world".partition("hi")
print "hello world".partition("hello") print "hello world".partition("hello")
print "hello world".partition("o") print "hello world".partition("o")
print "hello world"[False:True:True]
import time import time
print type(time) print type(time)
time.sleep(0)
time.sleep(False)
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