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

Merge pull request #43 from undingen/specialice

Type specialice buildin math support
parents e550e6e5 df431b4e
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#include "runtime/util.h" #include "runtime/util.h"
#include "runtime/inline/boxing.h" #include "runtime/inline/boxing.h"
#include "codegen/compvars.h"
namespace pyston { namespace pyston {
BoxedModule* math_module; BoxedModule* math_module;
...@@ -38,16 +40,46 @@ static double _extractFloat(Box* b) { ...@@ -38,16 +40,46 @@ static double _extractFloat(Box* b) {
return static_cast<BoxedFloat*>(b)->d; return static_cast<BoxedFloat*>(b)->d;
} }
Box* mathSqrtFloat(Box* b) {
assert(b->cls == float_cls);
double d = static_cast<BoxedFloat*>(b)->d;
if (d < 0) {
fprintf(stderr, "ValueError: math domain error\n");
raiseExc();
}
return boxFloat(sqrt(d));
}
Box* mathSqrtInt(Box* b) {
assert(b->cls == int_cls);
double d = static_cast<BoxedInt*>(b)->n;
if (d < 0) {
fprintf(stderr, "ValueError: math domain error\n");
raiseExc();
}
return boxFloat(sqrt(d));
}
Box* mathSqrt(Box* b) { Box* mathSqrt(Box* b) {
double d = _extractFloat(b); double d = _extractFloat(b);
if (d < 0) { if (d < 0) {
fprintf(stderr, "ValueError: math domain error\n"); fprintf(stderr, "ValueError: math domain error\n");
raiseExc(); raiseExc();
} }
return boxFloat(sqrt(d));
}
double r = sqrt(d); Box* mathTanFloat(Box* b) {
assert(b->cls == float_cls);
double d = static_cast<BoxedFloat*>(b)->d;
return boxFloat(tan(d));
}
return boxFloat(r); Box* mathTanInt(Box* b) {
assert(b->cls == int_cls);
double d = static_cast<BoxedInt*>(b)->n;
return boxFloat(tan(d));
} }
Box* mathTan(Box* b) { Box* mathTan(Box* b) {
...@@ -55,13 +87,27 @@ Box* mathTan(Box* b) { ...@@ -55,13 +87,27 @@ Box* mathTan(Box* b) {
return boxFloat(tan(d)); return boxFloat(tan(d));
} }
static void _addFunc(const char* name, void* int_func, void* float_func, void* boxed_func) {
std::vector<ConcreteCompilerType*> v_i, v_f, v_u;
assert(BOXED_INT);
v_i.push_back(BOXED_INT);
v_f.push_back(BOXED_FLOAT);
v_u.push_back(NULL);
CLFunction *cl = createRTFunction();
addRTFunction(cl, int_func, BOXED_FLOAT, v_i, false);
addRTFunction(cl, float_func, BOXED_FLOAT, v_f, false);
addRTFunction(cl, boxed_func, NULL, v_u, false);
math_module->giveAttr(name, new BoxedFunction(cl));
}
void setupMath() { void setupMath() {
math_module = createModule("math", "__builtin__"); math_module = createModule("math", "__builtin__");
math_module->giveAttr("pi", boxFloat(M_PI)); math_module->giveAttr("pi", boxFloat(M_PI));
math_module->giveAttr("sqrt", new BoxedFunction(boxRTFunction((void*)mathSqrt, NULL, 1, false))); _addFunc("sqrt", (void*)mathSqrtInt, (void*)mathSqrtFloat, (void*)mathSqrt);
math_module->giveAttr("tan", new BoxedFunction(boxRTFunction((void*)mathTan, NULL, 1, false))); _addFunc("tan", (void*)mathTanInt, (void*)mathTanFloat, (void*)mathSqrt);
} }
} }
...@@ -28,11 +28,17 @@ ...@@ -28,11 +28,17 @@
namespace pyston { namespace pyston {
extern "C" double mod_float_float(double lhs, double rhs) { template<typename T>
if (rhs == 0) { static inline void raiseDivZeroExcIfZero(T var)
{
if (var == 0) {
fprintf(stderr, "float divide by zero\n"); fprintf(stderr, "float divide by zero\n");
raiseExc(); raiseExc();
} }
}
extern "C" double mod_float_float(double lhs, double rhs) {
raiseDivZeroExcIfZero(rhs);
double r = fmod(lhs, rhs); double r = fmod(lhs, rhs);
// Have to be careful here with signed zeroes: // Have to be careful here with signed zeroes:
if (std::signbit(r) != std::signbit(rhs)) { if (std::signbit(r) != std::signbit(rhs)) {
...@@ -49,81 +55,78 @@ extern "C" double pow_float_float(double lhs, double rhs) { ...@@ -49,81 +55,78 @@ extern "C" double pow_float_float(double lhs, double rhs) {
} }
extern "C" double div_float_float(double lhs, double rhs) { extern "C" double div_float_float(double lhs, double rhs) {
if (rhs == 0) { raiseDivZeroExcIfZero(rhs);
fprintf(stderr, "float divide by zero\n");
raiseExc();
}
return lhs / rhs; return lhs / rhs;
} }
extern "C" Box* floatAddFloat(BoxedFloat* lhs, BoxedFloat *rhs) { extern "C" Box* floatAddFloat(BoxedFloat* lhs, BoxedFloat *rhs) {
assert(lhs->cls == float_cls); assert(lhs->cls == float_cls);
assert(rhs->cls == float_cls); assert(rhs->cls == float_cls);
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return boxFloat(lhs->d + rhs->d);
return boxFloat(lhs->d + rhs_float->d); }
extern "C" Box* floatAddInt(BoxedFloat* lhs, BoxedInt *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == int_cls);
return boxFloat(lhs->d + rhs->n);
} }
extern "C" Box* floatAdd(BoxedFloat* lhs, Box *rhs) { extern "C" Box* floatAdd(BoxedFloat* lhs, Box *rhs) {
assert(lhs->cls == float_cls); assert(lhs->cls == float_cls);
//printf("floatAdd %p %p\n", lhs, rhs);
if (rhs->cls == int_cls) { if (rhs->cls == int_cls) {
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs); return floatAddInt(lhs, static_cast<BoxedInt*>(rhs));
return boxFloat(lhs->d + rhs_int->n);
} else if (rhs->cls == float_cls) { } else if (rhs->cls == float_cls) {
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return floatAddFloat(lhs, static_cast<BoxedFloat*>(rhs));
return boxFloat(lhs->d + rhs_float->d);
} else { } else {
return NotImplemented; return NotImplemented;
} }
} }
extern "C" Box* floatDivFloat(BoxedFloat* lhs, BoxedFloat *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == float_cls);
raiseDivZeroExcIfZero(rhs->d);
return boxFloat(lhs->d / rhs->d);
}
extern "C" Box* floatDivInt(BoxedFloat* lhs, BoxedInt *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == int_cls);
raiseDivZeroExcIfZero(rhs->n);
return boxFloat(lhs->d / rhs->n);
}
extern "C" Box* floatDiv(BoxedFloat* lhs, Box *rhs) { extern "C" Box* floatDiv(BoxedFloat* lhs, Box *rhs) {
assert(lhs->cls == float_cls); assert(lhs->cls == float_cls);
if (rhs->cls == int_cls) { if (rhs->cls == int_cls) {
BoxedInt *rhs_int = static_cast<BoxedInt*>(rhs); return floatDivInt(lhs, static_cast<BoxedInt*>(rhs));
if (rhs_int->n == 0) {
fprintf(stderr, "float divide by zero\n");
raiseExc();
}
return boxFloat(lhs->d / rhs_int->n);
} else if (rhs->cls == float_cls) { } else if (rhs->cls == float_cls) {
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return floatDivFloat(lhs, static_cast<BoxedFloat*>(rhs));
if (rhs_float->d == 0) {
fprintf(stderr, "float divide by zero\n");
raiseExc();
}
return boxFloat(lhs->d / rhs_float->d);
} else { } else {
return NotImplemented; return NotImplemented;
} }
} }
extern "C" Box* floatRDiv(BoxedFloat* lhs, Box *rhs) { extern "C" Box* floatRDivFloat(BoxedFloat* lhs, BoxedFloat *rhs) {
assert(lhs->cls == float_cls); assert(lhs->cls == float_cls);
if (lhs->d == 0) { assert(rhs->cls == float_cls);
fprintf(stderr, "float divide by zero\n"); raiseDivZeroExcIfZero(lhs->d);
raiseExc(); return boxFloat(rhs->d / lhs->d);
} }
if (rhs->cls == int_cls) { extern "C" Box* floatRDivInt(BoxedFloat* lhs, BoxedInt *rhs) {
BoxedInt *rhs_int = static_cast<BoxedInt*>(rhs); assert(lhs->cls == float_cls);
return boxFloat(rhs_int->n / lhs->d); assert(rhs->cls == int_cls);
} else if (rhs->cls == float_cls) { raiseDivZeroExcIfZero(lhs->d);
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return boxFloat(rhs->n / lhs->d);
return boxFloat(rhs_float->d / lhs->d);
} else {
return NotImplemented;
}
} }
extern "C" Box* floatEq(BoxedFloat* lhs, Box *rhs) { extern "C" Box* floatRDiv(BoxedFloat* lhs, Box *rhs) {
assert(lhs->cls == float_cls); assert(lhs->cls == float_cls);
if (rhs->cls == float_cls) { if (rhs->cls == int_cls) {
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return floatRDivInt(lhs, static_cast<BoxedInt*>(rhs));
return boxBool(lhs->d == rhs_float->d); } else if (rhs->cls == float_cls) {
} else if (rhs->cls == int_cls) { return floatRDivFloat(lhs, static_cast<BoxedFloat*>(rhs));
BoxedInt *rhs_int = static_cast<BoxedInt*>(rhs);
return boxBool(lhs->d == rhs_int->n);
} else { } else {
return NotImplemented; return NotImplemented;
} }
...@@ -135,154 +138,212 @@ extern "C" Box* floatFloorDiv(BoxedFloat* lhs, Box *rhs) { ...@@ -135,154 +138,212 @@ extern "C" Box* floatFloorDiv(BoxedFloat* lhs, Box *rhs) {
return NotImplemented; return NotImplemented;
} }
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs);
if (rhs_float->d == 0) { raiseDivZeroExcIfZero(rhs_float->d);
fprintf(stderr, "float divide by zero\n");
raiseExc();
}
return boxFloat(floor(lhs->d / rhs_float->d)); return boxFloat(floor(lhs->d / rhs_float->d));
} }
extern "C" Box* floatEqFloat(BoxedFloat* lhs, BoxedFloat *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == float_cls);
return boxBool(lhs->d == rhs->d);
}
extern "C" Box* floatEqInt(BoxedFloat* lhs, BoxedInt *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == int_cls);
return boxBool(lhs->d == rhs->n);
}
extern "C" Box* floatEq(BoxedFloat* lhs, Box *rhs) {
assert(lhs->cls == float_cls);
if (rhs->cls == int_cls) {
return floatEqInt(lhs, static_cast<BoxedInt*>(rhs));
} else if (rhs->cls == float_cls) {
return floatEqFloat(lhs, static_cast<BoxedFloat*>(rhs));
} else {
return NotImplemented;
}
}
extern "C" Box* floatNeFloat(BoxedFloat* lhs, BoxedFloat *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == float_cls);
return boxBool(lhs->d != rhs->d);
}
extern "C" Box* floatNeInt(BoxedFloat* lhs, BoxedInt *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == int_cls);
return boxBool(lhs->d != rhs->n);
}
extern "C" Box* floatNe(BoxedFloat* lhs, Box *rhs) { extern "C" Box* floatNe(BoxedFloat* lhs, Box *rhs) {
assert(lhs->cls == float_cls); assert(lhs->cls == float_cls);
if (rhs->cls == float_cls) { if (rhs->cls == int_cls) {
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return floatNeInt(lhs, static_cast<BoxedInt*>(rhs));
return boxBool(lhs->d != rhs_float->d); } else if (rhs->cls == float_cls) {
} else if (rhs->cls == int_cls) { return floatNeFloat(lhs, static_cast<BoxedFloat*>(rhs));
BoxedInt *rhs_int = static_cast<BoxedInt*>(rhs);
return boxBool(lhs->d != rhs_int->n);
} else { } else {
return NotImplemented; return NotImplemented;
} }
} }
extern "C" Box* floatLtFloat(BoxedFloat* lhs, BoxedFloat *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == float_cls);
return boxBool(lhs->d < rhs->d);
}
extern "C" Box* floatLtInt(BoxedFloat* lhs, BoxedInt *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == int_cls);
return boxBool(lhs->d < rhs->n);
}
extern "C" Box* floatLt(BoxedFloat* lhs, Box *rhs) { extern "C" Box* floatLt(BoxedFloat* lhs, Box *rhs) {
assert(lhs->cls == float_cls); assert(lhs->cls == float_cls);
if (rhs->cls == float_cls) { if (rhs->cls == int_cls) {
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return floatLtInt(lhs, static_cast<BoxedInt*>(rhs));
return boxBool(lhs->d < rhs_float->d); } else if (rhs->cls == float_cls) {
} else if (rhs->cls == int_cls) { return floatLtFloat(lhs, static_cast<BoxedFloat*>(rhs));
BoxedInt *rhs_int = static_cast<BoxedInt*>(rhs);
return boxBool(lhs->d < rhs_int->n);
} else { } else {
return NotImplemented; return NotImplemented;
} }
} }
extern "C" Box* floatLeFloat(BoxedFloat* lhs, BoxedFloat *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == float_cls);
return boxBool(lhs->d <= rhs->d);
}
extern "C" Box* floatLeInt(BoxedFloat* lhs, BoxedInt *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == int_cls);
return boxBool(lhs->d <= rhs->n);
}
extern "C" Box* floatLe(BoxedFloat* lhs, Box *rhs) { extern "C" Box* floatLe(BoxedFloat* lhs, Box *rhs) {
assert(lhs->cls == float_cls); assert(lhs->cls == float_cls);
if (rhs->cls == float_cls) { if (rhs->cls == int_cls) {
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return floatLeInt(lhs, static_cast<BoxedInt*>(rhs));
return boxBool(lhs->d <= rhs_float->d); } else if (rhs->cls == float_cls) {
} else if (rhs->cls == int_cls) { return floatLeFloat(lhs, static_cast<BoxedFloat*>(rhs));
BoxedInt *rhs_int = static_cast<BoxedInt*>(rhs);
return boxBool(lhs->d <= rhs_int->n);
} else { } else {
return NotImplemented; return NotImplemented;
} }
} }
extern "C" Box* floatGtFloat(BoxedFloat* lhs, BoxedFloat *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == float_cls);
return boxBool(lhs->d > rhs->d);
}
extern "C" Box* floatGtInt(BoxedFloat* lhs, BoxedInt *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == int_cls);
return boxBool(lhs->d > rhs->n);
}
extern "C" Box* floatGt(BoxedFloat* lhs, Box *rhs) { extern "C" Box* floatGt(BoxedFloat* lhs, Box *rhs) {
assert(lhs->cls == float_cls); assert(lhs->cls == float_cls);
if (rhs->cls == float_cls) { if (rhs->cls == int_cls) {
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return floatGtInt(lhs, static_cast<BoxedInt*>(rhs));
return boxBool(lhs->d > rhs_float->d); } else if (rhs->cls == float_cls) {
} else if (rhs->cls == int_cls) { return floatGtFloat(lhs, static_cast<BoxedFloat*>(rhs));
BoxedInt *rhs_int = static_cast<BoxedInt*>(rhs);
return boxBool(lhs->d > rhs_int->n);
} else { } else {
return NotImplemented; return NotImplemented;
} }
} }
extern "C" Box* floatGeFloat(BoxedFloat* lhs, BoxedFloat *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == float_cls);
return boxBool(lhs->d >= rhs->d);
}
extern "C" Box* floatGeInt(BoxedFloat* lhs, BoxedInt *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == int_cls);
return boxBool(lhs->d >= rhs->n);
}
extern "C" Box* floatGe(BoxedFloat* lhs, Box *rhs) { extern "C" Box* floatGe(BoxedFloat* lhs, Box *rhs) {
assert(lhs->cls == float_cls); assert(lhs->cls == float_cls);
if (rhs->cls == float_cls) { if (rhs->cls == int_cls) {
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return floatGeInt(lhs, static_cast<BoxedInt*>(rhs));
return boxBool(lhs->d >= rhs_float->d); } else if (rhs->cls == float_cls) {
} else if (rhs->cls == int_cls) { return floatGeFloat(lhs, static_cast<BoxedFloat*>(rhs));
BoxedInt *rhs_int = static_cast<BoxedInt*>(rhs);
return boxBool(lhs->d >= rhs_int->n);
} else { } else {
return NotImplemented; return NotImplemented;
} }
} }
extern "C" Box* floatModFloat(BoxedFloat* lhs, Box *rhs) { extern "C" Box* floatModFloat(BoxedFloat* lhs, BoxedFloat *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == float_cls); assert(rhs->cls == float_cls);
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return boxFloat(mod_float_float(lhs->d, rhs->d));
double drhs = rhs_float->d; }
if (drhs == 0) {
fprintf(stderr, "float div by zero\n");
raiseExc();
}
return boxFloat(mod_float_float(lhs->d, drhs)); extern "C" Box* floatModInt(BoxedFloat* lhs, BoxedInt *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == int_cls);
return boxFloat(mod_float_float(lhs->d, rhs->n));
} }
extern "C" Box* floatMod(BoxedFloat* lhs, Box *rhs) { extern "C" Box* floatMod(BoxedFloat* lhs, Box *rhs) {
assert(lhs->cls == float_cls); assert(lhs->cls == float_cls);
double drhs;
if (rhs->cls == int_cls) { if (rhs->cls == int_cls) {
BoxedInt *rhs_int = static_cast<BoxedInt*>(rhs); return floatModInt(lhs, static_cast<BoxedInt*>(rhs));
drhs = rhs_int->n;
} else if (rhs->cls == float_cls) { } else if (rhs->cls == float_cls) {
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return floatModFloat(lhs, static_cast<BoxedFloat*>(rhs));
drhs = rhs_float->d;
} else { } else {
return NotImplemented; return NotImplemented;
} }
if (drhs == 0) {
fprintf(stderr, "float div by zero\n");
raiseExc();
}
return boxFloat(mod_float_float(lhs->d, drhs));
} }
extern "C" Box* floatRModFloat(BoxedFloat* lhs, Box *rhs) { extern "C" Box* floatRModFloat(BoxedFloat* lhs, BoxedFloat *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == float_cls); assert(rhs->cls == float_cls);
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return boxFloat(mod_float_float(rhs->d, lhs->d));
double drhs = rhs_float->d; }
if (lhs->d == 0) {
fprintf(stderr, "float div by zero\n");
raiseExc();
}
return boxFloat(mod_float_float(drhs, lhs->d)); extern "C" Box* floatRModInt(BoxedFloat* lhs, BoxedInt *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == int_cls);
return boxFloat(mod_float_float(rhs->n, lhs->d));
} }
extern "C" Box* floatRMod(BoxedFloat* lhs, Box *rhs) { extern "C" Box* floatRMod(BoxedFloat* lhs, Box *rhs) {
assert(lhs->cls == float_cls); assert(lhs->cls == float_cls);
double drhs;
if (rhs->cls == int_cls) { if (rhs->cls == int_cls) {
BoxedInt *rhs_int = static_cast<BoxedInt*>(rhs); return floatRModInt(lhs, static_cast<BoxedInt*>(rhs));
drhs = rhs_int->n;
} else if (rhs->cls == float_cls) { } else if (rhs->cls == float_cls) {
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return floatRModFloat(lhs, static_cast<BoxedFloat*>(rhs));
drhs = rhs_float->d;
} else { } else {
return NotImplemented; return NotImplemented;
} }
}
if (lhs->d == 0) { extern "C" Box* floatPowFloat(BoxedFloat* lhs, BoxedFloat *rhs) {
fprintf(stderr, "float div by zero\n"); assert(lhs->cls == float_cls);
raiseExc(); assert(rhs->cls == float_cls);
} return boxFloat(pow(lhs->d, rhs->d));
}
return boxFloat(mod_float_float(drhs, lhs->d)); extern "C" Box* floatPowInt(BoxedFloat* lhs, BoxedInt *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == int_cls);
return boxFloat(pow(lhs->d, rhs->n));
} }
extern "C" Box* floatPow(BoxedFloat* lhs, Box *rhs) { extern "C" Box* floatPow(BoxedFloat* lhs, Box *rhs) {
assert(lhs->cls == float_cls); assert(lhs->cls == float_cls);
if (rhs->cls == int_cls) { if (rhs->cls == int_cls) {
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs); return floatPowInt(lhs, static_cast<BoxedInt*>(rhs));
return boxFloat(pow(lhs->d, rhs_int->n));
} else if (rhs->cls == float_cls) { } else if (rhs->cls == float_cls) {
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return floatPowFloat(lhs, static_cast<BoxedFloat*>(rhs));
return boxFloat(pow(lhs->d, rhs_float->d));
} else { } else {
return NotImplemented; return NotImplemented;
} }
...@@ -291,18 +352,21 @@ extern "C" Box* floatPow(BoxedFloat* lhs, Box *rhs) { ...@@ -291,18 +352,21 @@ extern "C" Box* floatPow(BoxedFloat* lhs, Box *rhs) {
extern "C" Box* floatMulFloat(BoxedFloat* lhs, BoxedFloat *rhs) { extern "C" Box* floatMulFloat(BoxedFloat* lhs, BoxedFloat *rhs) {
assert(lhs->cls == float_cls); assert(lhs->cls == float_cls);
assert(rhs->cls == float_cls); assert(rhs->cls == float_cls);
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return boxFloat(lhs->d * rhs->d);
return boxFloat(lhs->d * rhs_float->d); }
extern "C" Box* floatMulInt(BoxedFloat* lhs, BoxedInt *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == int_cls);
return boxFloat(lhs->d * rhs->n);
} }
extern "C" Box* floatMul(BoxedFloat* lhs, Box *rhs) { extern "C" Box* floatMul(BoxedFloat* lhs, Box *rhs) {
assert(lhs->cls == float_cls); assert(lhs->cls == float_cls);
if (rhs->cls == int_cls) { if (rhs->cls == int_cls) {
BoxedInt *rhs_int = static_cast<BoxedInt*>(rhs); return floatMulInt(lhs, static_cast<BoxedInt*>(rhs));
return boxFloat(lhs->d * rhs_int->n);
} else if (rhs->cls == float_cls) { } else if (rhs->cls == float_cls) {
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return floatMulFloat(lhs, static_cast<BoxedFloat*>(rhs));
return boxFloat(lhs->d * rhs_float->d);
} else { } else {
return NotImplemented; return NotImplemented;
} }
...@@ -311,31 +375,44 @@ extern "C" Box* floatMul(BoxedFloat* lhs, Box *rhs) { ...@@ -311,31 +375,44 @@ extern "C" Box* floatMul(BoxedFloat* lhs, Box *rhs) {
extern "C" Box* floatSubFloat(BoxedFloat* lhs, BoxedFloat *rhs) { extern "C" Box* floatSubFloat(BoxedFloat* lhs, BoxedFloat *rhs) {
assert(lhs->cls == float_cls); assert(lhs->cls == float_cls);
assert(rhs->cls == float_cls); assert(rhs->cls == float_cls);
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return boxFloat(lhs->d - rhs->d);
return boxFloat(lhs->d - rhs_float->d); }
extern "C" Box* floatSubInt(BoxedFloat* lhs, BoxedInt *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == int_cls);
return boxFloat(lhs->d - rhs->n);
} }
extern "C" Box* floatSub(BoxedFloat* lhs, Box *rhs) { extern "C" Box* floatSub(BoxedFloat* lhs, Box *rhs) {
assert(lhs->cls == float_cls); assert(lhs->cls == float_cls);
if (rhs->cls == int_cls) { if (rhs->cls == int_cls) {
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs); return floatSubInt(lhs, static_cast<BoxedInt*>(rhs));
return boxFloat(lhs->d - rhs_int->n);
} else if (rhs->cls == float_cls) { } else if (rhs->cls == float_cls) {
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return floatSubFloat(lhs, static_cast<BoxedFloat*>(rhs));
return boxFloat(lhs->d - rhs_float->d);
} else { } else {
return NotImplemented; return NotImplemented;
} }
} }
extern "C" Box* floatRSubFloat(BoxedFloat* lhs, BoxedFloat *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == float_cls);
return boxFloat(rhs->d - lhs->d);
}
extern "C" Box* floatRSubInt(BoxedFloat* lhs, BoxedInt *rhs) {
assert(lhs->cls == float_cls);
assert(rhs->cls == int_cls);
return boxFloat(rhs->n - lhs->d);
}
extern "C" Box* floatRSub(BoxedFloat* lhs, Box *rhs) { extern "C" Box* floatRSub(BoxedFloat* lhs, Box *rhs) {
assert(lhs->cls == float_cls); assert(lhs->cls == float_cls);
if (rhs->cls == int_cls) { if (rhs->cls == int_cls) {
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs); return floatRSubInt(lhs, static_cast<BoxedInt*>(rhs));
return boxFloat(rhs_int->n - lhs->d);
} else if (rhs->cls == float_cls) { } else if (rhs->cls == float_cls) {
BoxedFloat *rhs_float = static_cast<BoxedFloat*>(rhs); return floatRSubFloat(lhs, static_cast<BoxedFloat*>(rhs));
return boxFloat(rhs_float->d - lhs->d);
} else { } else {
return NotImplemented; return NotImplemented;
} }
...@@ -473,13 +550,15 @@ extern "C" void printFloat(double d) { ...@@ -473,13 +550,15 @@ extern "C" void printFloat(double d) {
printf("%s", s.c_str()); printf("%s", s.c_str());
} }
static void _addFunc(const char* name, void* float_func, void* boxed_func) { static void _addFunc(const char* name, ConcreteCompilerType* rtn_type, void* float_func, void* int_func, void* boxed_func) {
std::vector<ConcreteCompilerType*> v_ff, v_fu; std::vector<ConcreteCompilerType*> v_ff, v_fi, v_fu;
v_ff.push_back(BOXED_FLOAT); v_ff.push_back(BOXED_FLOAT); v_ff.push_back(BOXED_FLOAT); v_ff.push_back(BOXED_FLOAT);
v_fi.push_back(BOXED_FLOAT); v_ff.push_back(BOXED_INT);
v_fu.push_back(BOXED_FLOAT); v_fu.push_back(NULL); v_fu.push_back(BOXED_FLOAT); v_fu.push_back(NULL);
CLFunction *cl = createRTFunction(); CLFunction *cl = createRTFunction();
addRTFunction(cl, float_func, BOXED_FLOAT, v_ff, false); addRTFunction(cl, float_func, rtn_type, v_ff, false);
addRTFunction(cl, int_func, rtn_type, v_fi, false);
addRTFunction(cl, boxed_func, NULL, v_fu, false); addRTFunction(cl, boxed_func, NULL, v_fu, false);
float_cls->giveAttr(name, new BoxedFunction(cl)); float_cls->giveAttr(name, new BoxedFunction(cl));
} }
...@@ -487,26 +566,28 @@ static void _addFunc(const char* name, void* float_func, void* boxed_func) { ...@@ -487,26 +566,28 @@ static void _addFunc(const char* name, void* float_func, void* boxed_func) {
void setupFloat() { void setupFloat() {
float_cls->giveAttr("__name__", boxStrConstant("float")); float_cls->giveAttr("__name__", boxStrConstant("float"));
_addFunc("__add__", (void*)floatAddFloat, (void*)floatAdd); _addFunc("__add__", BOXED_FLOAT, (void*)floatAddFloat, (void*)floatAddInt, (void*)floatAdd);
//float_cls->giveAttr("__add__", new BoxedFunction(boxRTFunction((void*)floatAdd, NULL, 2, false)));
float_cls->setattr("__radd__", float_cls->peekattr("__add__"), NULL, NULL); float_cls->setattr("__radd__", float_cls->peekattr("__add__"), NULL, NULL);
float_cls->giveAttr("__div__", new BoxedFunction(boxRTFunction((void*)floatDiv, NULL, 2, false)));
float_cls->giveAttr("__rdiv__", new BoxedFunction(boxRTFunction((void*)floatRDiv, NULL, 2, false))); _addFunc("__div__", BOXED_FLOAT, (void*)floatDivFloat, (void*)floatDivInt, (void*)floatDiv);
float_cls->giveAttr("__eq__", new BoxedFunction(boxRTFunction((void*)floatEq, NULL, 2, false))); _addFunc("__rdiv__", BOXED_FLOAT, (void*)floatRDivFloat, (void*)floatRDivInt, (void*)floatRDiv);
float_cls->giveAttr("__floordiv__", new BoxedFunction(boxRTFunction((void*)floatFloorDiv, NULL, 2, false))); float_cls->giveAttr("__floordiv__", new BoxedFunction(boxRTFunction((void*)floatFloorDiv, NULL, 2, false)));
float_cls->giveAttr("__ge__", new BoxedFunction(boxRTFunction((void*)floatGe, NULL, 2, false)));
float_cls->giveAttr("__gt__", new BoxedFunction(boxRTFunction((void*)floatGt, NULL, 2, false))); _addFunc("__eq__", BOXED_BOOL, (void*)floatEqFloat, (void*)floatEqInt, (void*)floatEq);
float_cls->giveAttr("__le__", new BoxedFunction(boxRTFunction((void*)floatLe, NULL, 2, false))); _addFunc("__ge__", BOXED_BOOL, (void*)floatGeFloat, (void*)floatGeInt, (void*)floatGe);
float_cls->giveAttr("__lt__", new BoxedFunction(boxRTFunction((void*)floatLt, NULL, 2, false))); _addFunc("__gt__", BOXED_BOOL, (void*)floatGtFloat, (void*)floatGtInt, (void*)floatGt);
_addFunc("__mod__", (void*)floatModFloat, (void*)floatMod); _addFunc("__le__", BOXED_BOOL, (void*)floatLeFloat, (void*)floatLeInt, (void*)floatLe);
_addFunc("__rmod__", (void*)floatRModFloat, (void*)floatRMod); _addFunc("__lt__", BOXED_BOOL, (void*)floatLtFloat, (void*)floatLtInt, (void*)floatLt);
_addFunc("__mul__", (void*)floatMulFloat, (void*)floatMul); _addFunc("__ne__", BOXED_BOOL, (void*)floatNeFloat, (void*)floatNeInt, (void*)floatNe);
_addFunc("__mod__", BOXED_FLOAT, (void*)floatModFloat, (void*)floatModInt, (void*)floatMod);
_addFunc("__rmod__", BOXED_FLOAT, (void*)floatRModFloat, (void*)floatRModInt, (void*)floatRMod);
_addFunc("__mul__", BOXED_FLOAT, (void*)floatMulFloat, (void*)floatMulInt, (void*)floatMul);
float_cls->setattr("__rmul__", float_cls->peekattr("__mul__"), NULL, NULL); float_cls->setattr("__rmul__", float_cls->peekattr("__mul__"), NULL, NULL);
float_cls->giveAttr("__ne__", new BoxedFunction(boxRTFunction((void*)floatNe, NULL, 2, false)));
float_cls->giveAttr("__pow__", new BoxedFunction(boxRTFunction((void*)floatPow, NULL, 2, false))); _addFunc("__pow__", BOXED_FLOAT, (void*)floatPowFloat, (void*)floatPowInt, (void*)floatPow);
//float_cls->giveAttr("__sub__", new BoxedFunction(boxRTFunction((void*)floatSub, NULL, 2, false))); _addFunc("__sub__", BOXED_FLOAT, (void*)floatSubFloat, (void*)floatSubInt, (void*)floatSub);
_addFunc("__sub__", (void*)floatSubFloat, (void*)floatSub); _addFunc("__rsub__", BOXED_FLOAT, (void*)floatRSubFloat, (void*)floatRSubInt, (void*)floatRSub);
float_cls->giveAttr("__rsub__", new BoxedFunction(boxRTFunction((void*)floatRSub, NULL, 2, false)));
CLFunction *__new__ = boxRTFunction((void*)floatNew1, NULL, 1, false); CLFunction *__new__ = boxRTFunction((void*)floatNew1, NULL, 1, false);
addRTFunction(__new__, (void*)floatNew2, NULL, 2, false); addRTFunction(__new__, (void*)floatNew2, NULL, 2, 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