From 8714c56c3e671c2e0f070032c17ebf4f74e7c1fb Mon Sep 17 00:00:00 2001 From: Add00 Date: Wed, 2 Aug 2023 08:39:50 -0400 Subject: [PATCH] Implemented feedback --- repl/lib_math.c | 82 ++++++++------------------------------ repl/lib_standard.c | 15 ++++++- test/scripts/lib/math.toy | 83 +++++++++++++++++---------------------- test/test_libraries.c | 2 + 4 files changed, 69 insertions(+), 113 deletions(-) diff --git a/repl/lib_math.c b/repl/lib_math.c index c9f4d17..aef7a9e 100644 --- a/repl/lib_math.c +++ b/repl/lib_math.c @@ -8,59 +8,6 @@ #define LIB_MATH_E 2.71828182845904523536f #define LIB_MATH_EPSILON 0.000001f -static int nativeMod(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { - if (arguments->count != 2) { - interpreter->errorOutput("Incorrect number of arguments to mod\n"); - return -1; - } - - //get the arguments - Toy_Literal yLiteral = Toy_popLiteralArray(arguments); - Toy_Literal xLiteral = Toy_popLiteralArray(arguments); - - //parse the argument (if it's an identifier) - Toy_Literal xLiteralIdn = xLiteral; - if (TOY_IS_IDENTIFIER(xLiteral) && Toy_parseIdentifierToValue(interpreter, &xLiteral)) { - Toy_freeLiteral(xLiteralIdn); - } - - Toy_Literal yLiteralIdn = yLiteral; - if (TOY_IS_IDENTIFIER(yLiteral) && Toy_parseIdentifierToValue(interpreter, &yLiteral)) { - Toy_freeLiteral(yLiteralIdn); - } - - //check the argument types - if (!(TOY_IS_INTEGER(xLiteral) || TOY_IS_FLOAT(xLiteral))) { - interpreter->errorOutput("Incorrect argument type passed to mod\n"); - Toy_freeLiteral(xLiteral); - return -1; - } - - if (!(TOY_IS_INTEGER(yLiteral) || TOY_IS_FLOAT(yLiteral))) { - interpreter->errorOutput("Incorrect argument type passed to mod\n"); - Toy_freeLiteral(yLiteral); - return -1; - } - - // cast ints to floats to handle all types of numbers - float x = TOY_IS_INTEGER(xLiteral)? TOY_AS_INTEGER(xLiteral) : TOY_AS_FLOAT(xLiteral); - float y = TOY_IS_INTEGER(yLiteral)? TOY_AS_INTEGER(yLiteral) : TOY_AS_FLOAT(yLiteral); - - // calculate the result - float result = fmodf(x, y); - - // return the result - Toy_Literal resultLiteral = TOY_TO_FLOAT_LITERAL(result); - Toy_pushLiteralArray(&interpreter->stack, resultLiteral); - - // cleanup - Toy_freeLiteral(resultLiteral); - Toy_freeLiteral(xLiteral); - Toy_freeLiteral(yLiteral); - - return 1; -} - static int nativePow(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { if (arguments->count != 2) { interpreter->errorOutput("Incorrect number of arguments to pow\n"); @@ -86,12 +33,14 @@ static int nativePow(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) if (!(TOY_IS_INTEGER(xLiteral) || TOY_IS_FLOAT(xLiteral))) { interpreter->errorOutput("Incorrect argument type passed to pow\n"); Toy_freeLiteral(xLiteral); + Toy_freeLiteral(yLiteralIdn); return -1; } if (!(TOY_IS_INTEGER(yLiteral) || TOY_IS_FLOAT(yLiteral))) { interpreter->errorOutput("Incorrect argument type passed to pow\n"); Toy_freeLiteral(yLiteral); + Toy_freeLiteral(xLiteral); return -1; } @@ -217,12 +166,14 @@ static int nativeHypot(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments if (!(TOY_IS_INTEGER(xLiteral) || TOY_IS_FLOAT(xLiteral))) { interpreter->errorOutput("Incorrect argument type passed to hypot\n"); Toy_freeLiteral(xLiteral); + Toy_freeLiteral(yLiteral); return -1; } if (!(TOY_IS_INTEGER(yLiteral) || TOY_IS_FLOAT(yLiteral))) { interpreter->errorOutput("Incorrect argument type passed to hypot\n"); Toy_freeLiteral(yLiteral); + Toy_freeLiteral(xLiteral); return -1; } @@ -245,7 +196,7 @@ static int nativeHypot(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments return 1; } -static int nativeToRad(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { +static int nativeToRadians(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { if (arguments->count != 1) { interpreter->errorOutput("Incorrect number of arguments to toRad\n"); return -1; @@ -283,7 +234,7 @@ static int nativeToRad(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments return 1; } -static int nativeToDeg(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { +static int nativeToDegrees(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { if (arguments->count != 1) { interpreter->errorOutput("Incorrect number of arguments to toDeg\n"); return -1; @@ -580,12 +531,14 @@ static int nativeAtan2(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments if (!(TOY_IS_INTEGER(xLiteral) || TOY_IS_FLOAT(xLiteral))) { interpreter->errorOutput("Incorrect argument type passed to atan2\n"); Toy_freeLiteral(xLiteral); + Toy_freeLiteral(yLiteral); return -1; } if (!(TOY_IS_INTEGER(yLiteral) || TOY_IS_FLOAT(yLiteral))) { interpreter->errorOutput("Incorrect argument type passed to atan2\n"); Toy_freeLiteral(yLiteral); + Toy_freeLiteral(xLiteral); return -1; } @@ -607,7 +560,7 @@ static int nativeAtan2(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments return 1; } -static int nativeIsnan(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { +static int nativeCheckIsNaN(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { if (arguments->count != 1) { interpreter->errorOutput("Incorrect number of arguments to tan\n"); return -1; @@ -646,7 +599,7 @@ static int nativeIsnan(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments return 1; } -static int nativeFloatCompare(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { +static int nativeEpsilionCompare(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { if (arguments->count != 2) { interpreter->errorOutput("Incorrect number of arguments to mod\n"); return -1; @@ -708,9 +661,6 @@ typedef struct Natives { int Toy_hookMath(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias) { //build the natives list Natives natives[] = { - // Common - {"mod", nativeMod}, - // Power {"pow", nativePow}, {"sqrt", nativeSqrt}, @@ -718,8 +668,8 @@ int Toy_hookMath(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Liter {"hypot", nativeHypot}, // Trigonometric - {"toRad", nativeToRad}, - {"toDeg", nativeToDeg}, + {"toRadians", nativeToRadians}, + {"toDegrees", nativeToDegrees}, {"sin", nativeSin}, {"cos", nativeCos}, {"tan", nativeTan}, @@ -729,8 +679,8 @@ int Toy_hookMath(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Liter {"atans", nativeAtan2}, // Comparison - {"isnan", nativeIsnan}, - {"floatCompare", nativeFloatCompare}, + {"checkIsNaN", nativeCheckIsNaN}, + {"epsilionCompare", nativeEpsilionCompare}, {NULL, NULL} }; @@ -788,9 +738,9 @@ int Toy_hookMath(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Liter //build the type Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, true); - Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true); + Toy_Literal anyType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_ANY, true); Toy_Literal fnType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FUNCTION_NATIVE, true); - TOY_TYPE_PUSH_SUBTYPE(&type, strType); + TOY_TYPE_PUSH_SUBTYPE(&type, anyType); TOY_TYPE_PUSH_SUBTYPE(&type, fnType); //set scope diff --git a/repl/lib_standard.c b/repl/lib_standard.c index dde005b..786cbd3 100644 --- a/repl/lib_standard.c +++ b/repl/lib_standard.c @@ -2196,8 +2196,21 @@ int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_L Toy_freeLiteral(func); } - Toy_freeLiteralDictionary(dictionary); + //build the type + Toy_Literal type = TOY_TO_TYPE_LITERAL(TOY_LITERAL_DICTIONARY, true); + Toy_Literal strType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_STRING, true); + Toy_Literal fnType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FUNCTION_NATIVE, true); + TOY_TYPE_PUSH_SUBTYPE(&type, strType); + TOY_TYPE_PUSH_SUBTYPE(&type, fnType); + //set scope + Toy_Literal dict = TOY_TO_DICTIONARY_LITERAL(dictionary); + Toy_declareScopeVariable(interpreter->scope, alias, type); + Toy_setScopeVariable(interpreter->scope, alias, dict, false); + + //cleanup + Toy_freeLiteral(dict); + Toy_freeLiteral(type); return 0; } diff --git a/test/scripts/lib/math.toy b/test/scripts/lib/math.toy index d7a24e3..4aec783 100644 --- a/test/scripts/lib/math.toy +++ b/test/scripts/lib/math.toy @@ -1,13 +1,5 @@ import math; -// test mod -{ - assert mod(5, 3) == 2.0, "mod(5, 3) failed"; - assert mod(-5, 3) == -2.0, "mod(-5, 3) failed"; - assert mod(-5.5, 3) == -2.5, "mod(-5.5, 3) failed"; - assert mod(0, 1) == 0.0, "mod(0, 1) failed"; - assert mod(-0.0, 1) == -0.0, "mod(0, 1) failed"; -} // test pow { @@ -22,7 +14,7 @@ import math; { assert sqrt(25) == 5, "sqrt(25) failed"; assert sqrt(256.0) == 16, "sqrt(256.0) failed"; - assert isnan(sqrt(-256.0)), "sqrt(-256.0) failed"; + assert checkIsNaN(sqrt(-256.0)), "sqrt(-256.0) failed"; assert sqrt(1) == 1, "sqrt(1) failed"; assert sqrt(0) == 0, "sqrt(0) failed"; } @@ -43,87 +35,86 @@ import math; // test toRad { - assert toRad(0) == 0, "toRad 0° failed"; - assert toRad(180) == PI, "toRad 180° failed"; - assert toRad(360) == 2 * PI, "toRad 360° failed"; + assert toRadians(0) == 0, "toRadians(0) failed"; + assert toRadians(180) == PI, "toRadians(180) failed"; + assert toRadians(360) == 2 * PI, "toRadians(360) failed"; } // test toDeg { - assert toDeg(0) == 0, "toDeg 0 failed"; - assert toDeg(PI) == 180, "toDeg π failed"; - assert toDeg(2 * PI) == 360, "toDeg 2π failed"; + assert toDegrees(0) == 0, "toDegrees(0) failed"; + assert toDegrees(PI) == 180, "toDegrees(PI) failed"; + assert toDegrees(2 * PI) == 360, "toDegrees(2*PI) failed"; } // test sin { - assert floatCompare(sin(PI), 0), "sin(π) failed"; - assert floatCompare(sin(PI / 2), 1), "sin(π/2) failed"; - assert floatCompare(sin(0), 0), "sin(0) failed"; + assert epsilionCompare(sin(PI), 0), "sin(PI) failed"; + assert epsilionCompare(sin(PI / 2), 1), "sin(PI/2) failed"; + assert epsilionCompare(sin(0), 0), "sin(0) failed"; } // test cos { - assert floatCompare(cos(PI), -1), "cos(π) failed"; - assert floatCompare(cos(PI / 2), 0), "cos(π/2) failed"; - assert floatCompare(cos(0), 1), "cos(0) failed"; + assert epsilionCompare(cos(PI), -1), "cos(PI) failed"; + assert epsilionCompare(cos(PI / 2), 0), "cos(PI/2) failed"; + assert epsilionCompare(cos(0), 1), "cos(0) failed"; } // test tan { - assert floatCompare(tan(PI), 0), "tan(π) failed"; - assert floatCompare(tan(PI / 4), 1), "tan(π/4) failed"; - assert floatCompare(tan(0), 0), "tan(0) failed"; + assert epsilionCompare(tan(PI), 0), "tan(PI) failed"; + assert epsilionCompare(tan(PI / 4), 1), "tan(PI/4) failed"; + assert epsilionCompare(tan(0), 0), "tan(0) failed"; } // test asin { - assert floatCompare(asin(1), 1.570796), "asin(1) failed"; - assert floatCompare(asin(-0.5), -0.523599), "asin(-0.5) failed"; - assert floatCompare(asin(0), 0), "asin(0) failed"; + assert epsilionCompare(asin(1), 1.570796), "asin(1) failed"; + assert epsilionCompare(asin(-0.5), -0.523599), "asin(-0.5) failed"; + assert epsilionCompare(asin(0), 0), "asin(0) failed"; } // test acos { - assert floatCompare(acos(1), 0), "acos(1) failed"; - assert floatCompare(acos(0.5), 1.047198), "acos(0.5) failed"; - assert floatCompare(acos(0), 1.570796), "acos(0) failed"; + assert epsilionCompare(acos(1), 0), "acos(1) failed"; + assert epsilionCompare(acos(0.5), 1.047198), "acos(0.5) failed"; + assert epsilionCompare(acos(0), 1.570796), "acos(0) failed"; } // test atan { - assert floatCompare(atan(1), 0.785398), "acos(1) failed"; - assert floatCompare(atan(INFINITY), 1.570796), "atan(INFINITY) failed"; - assert floatCompare(atan(0), 0), "atan(0) failed"; + assert epsilionCompare(atan(1), 0.785398), "acos(1) failed"; + assert epsilionCompare(atan(INFINITY), 1.570796), "atan(INFINITY) failed"; + assert epsilionCompare(atan(0), 0), "atan(0) failed"; } // test atan2 { - assert floatCompare(atans(0, 0), 0), "atan2(0, 0) failed"; - assert floatCompare(atans(7, 0), 1.570796), "atans(7, 0) failed"; + assert epsilionCompare(atans(0, 0), 0), "atan2(0, 0) failed"; + assert epsilionCompare(atans(7, 0), 1.570796), "atans(7, 0) failed"; } -// test isnan +// test checkIsNaN { - assert isnan(NAN) == true, "isnan(NAN) failed"; - assert isnan(INFINITY) == false, "isnan(INFINITY) failed"; - assert isnan(0.0) == false, "isnan(0.0) failed"; - // assert isnan(0 / 0) == true, "isnan(0 / 0) failed"; interpreter prevents dividing by 0 - assert isnan(INFINITY - INFINITY) == true, "isnan(INFINITY - INFINITY) failed"; + assert checkIsNaN(NAN) == true, "checkIsNaN(NAN) failed"; + assert checkIsNaN(INFINITY) == false, "checkIsNaN(INFINITY) failed"; + assert checkIsNaN(0.0) == false, "checkIsNaN(0.0) failed"; + assert checkIsNaN(INFINITY - INFINITY) == true, "checkIsNaN(INFINITY - INFINITY) failed"; } -// test floatCompare +// test epsilionCompare { - assert floatCompare(1, 1) == true, "floatCompare(1, 1) failed"; - assert floatCompare(1, 1.000001) == true, "floatCompare(1, 1.000001) failed"; - assert floatCompare(1, 1.001) == false, "floatCompare(1, 1.001) failed"; - assert floatCompare(0, 0) == true, "floatCompare(0, 0) failed"; + assert epsilionCompare(1, 1) == true, "epsilionCompare(1, 1) failed"; + assert epsilionCompare(1, 1.000001) == true, "epsilionCompare(1, 1.000001) failed"; + assert epsilionCompare(1, 1.001) == false, "epsilionCompare(1, 1.001) failed"; + assert epsilionCompare(0, 0) == true, "epsilionCompare(0, 0) failed"; } \ No newline at end of file diff --git a/test/test_libraries.c b/test/test_libraries.c index 58c9e77..998c272 100644 --- a/test/test_libraries.c +++ b/test/test_libraries.c @@ -18,6 +18,7 @@ #include "../repl/lib_standard.h" #include "../repl/lib_random.h" #include "../repl/lib_runner.h" +#include "../repl/lib_math.h" //supress the print output static void noPrintFn(const char* output) { @@ -76,6 +77,7 @@ int main() { {"standard.toy", "standard", Toy_hookStandard}, {"runner.toy", "runner", Toy_hookRunner}, {"random.toy", "random", Toy_hookRandom}, + {"math.toy", "math", Toy_hookMath}, {NULL, NULL, NULL} };