mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Added arc versions of trigonometric functions
This commit is contained in:
173
repl/lib_math.c
173
repl/lib_math.c
@@ -438,6 +438,175 @@ static int nativeTan(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeAsin(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to asin\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the argument
|
||||
Toy_Literal radiansLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
//parse the argument (if it's an identifier)
|
||||
Toy_Literal radiansLiteralIdn = radiansLiteral;
|
||||
if (TOY_IS_IDENTIFIER(radiansLiteral) && Toy_parseIdentifierToValue(interpreter, &radiansLiteral)) {
|
||||
Toy_freeLiteral(radiansLiteralIdn);
|
||||
}
|
||||
|
||||
//check the argument type
|
||||
if (!(TOY_IS_INTEGER(radiansLiteral) || TOY_IS_FLOAT(radiansLiteral))) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to asin\n");
|
||||
Toy_freeLiteral(radiansLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// cast ints to floats to handle all types of numbers
|
||||
float radians = TOY_IS_INTEGER(radiansLiteral)? TOY_AS_INTEGER(radiansLiteral) : TOY_AS_FLOAT(radiansLiteral);
|
||||
|
||||
// calculate the result
|
||||
float result = asinf(radians);
|
||||
|
||||
//return the result
|
||||
Toy_Literal resultLiteral = TOY_TO_FLOAT_LITERAL(result);
|
||||
Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteral(resultLiteral);
|
||||
Toy_freeLiteral(radiansLiteral);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeAcos(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to acos\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the argument
|
||||
Toy_Literal radiansLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
//parse the argument (if it's an identifier)
|
||||
Toy_Literal radiansLiteralIdn = radiansLiteral;
|
||||
if (TOY_IS_IDENTIFIER(radiansLiteral) && Toy_parseIdentifierToValue(interpreter, &radiansLiteral)) {
|
||||
Toy_freeLiteral(radiansLiteralIdn);
|
||||
}
|
||||
|
||||
//check the argument type
|
||||
if (!(TOY_IS_INTEGER(radiansLiteral) || TOY_IS_FLOAT(radiansLiteral))) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to acos\n");
|
||||
Toy_freeLiteral(radiansLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// cast ints to floats to handle all types of numbers
|
||||
float radians = TOY_IS_INTEGER(radiansLiteral)? TOY_AS_INTEGER(radiansLiteral) : TOY_AS_FLOAT(radiansLiteral);
|
||||
|
||||
// calculate the result
|
||||
float result = acosf(radians);
|
||||
|
||||
//return the result
|
||||
Toy_Literal resultLiteral = TOY_TO_FLOAT_LITERAL(result);
|
||||
Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteral(resultLiteral);
|
||||
Toy_freeLiteral(radiansLiteral);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeAtan(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to atan\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the argument
|
||||
Toy_Literal radiansLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
//parse the argument (if it's an identifier)
|
||||
Toy_Literal radiansLiteralIdn = radiansLiteral;
|
||||
if (TOY_IS_IDENTIFIER(radiansLiteral) && Toy_parseIdentifierToValue(interpreter, &radiansLiteral)) {
|
||||
Toy_freeLiteral(radiansLiteralIdn);
|
||||
}
|
||||
|
||||
//check the argument type
|
||||
if (!(TOY_IS_INTEGER(radiansLiteral) || TOY_IS_FLOAT(radiansLiteral))) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to atan\n");
|
||||
Toy_freeLiteral(radiansLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// cast ints to floats to handle all types of numbers
|
||||
float radians = TOY_IS_INTEGER(radiansLiteral)? TOY_AS_INTEGER(radiansLiteral) : TOY_AS_FLOAT(radiansLiteral);
|
||||
|
||||
// calculate the result
|
||||
float result = atanf(radians);
|
||||
|
||||
//return the result
|
||||
Toy_Literal resultLiteral = TOY_TO_FLOAT_LITERAL(result);
|
||||
Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteral(resultLiteral);
|
||||
Toy_freeLiteral(radiansLiteral);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeAtan2(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 2) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to atan2\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the argument
|
||||
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 type
|
||||
if (!(TOY_IS_INTEGER(xLiteral) || TOY_IS_FLOAT(xLiteral))) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to atan2\n");
|
||||
Toy_freeLiteral(xLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(TOY_IS_INTEGER(yLiteral) || TOY_IS_FLOAT(yLiteral))) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to atan2\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 = atan2f(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);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeIsnan(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to tan\n");
|
||||
@@ -554,6 +723,10 @@ int Toy_hookMath(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Liter
|
||||
{"sin", nativeSin},
|
||||
{"cos", nativeCos},
|
||||
{"tan", nativeTan},
|
||||
{"asin", nativeAsin},
|
||||
{"acos", nativeAcos},
|
||||
{"atan", nativeAtan},
|
||||
{"atans", nativeAtan2},
|
||||
|
||||
// Comparison
|
||||
{"isnan", nativeIsnan},
|
||||
|
||||
@@ -71,6 +71,44 @@ import math;
|
||||
assert floatCompare(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";
|
||||
}
|
||||
|
||||
|
||||
// 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";
|
||||
}
|
||||
|
||||
|
||||
// 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";
|
||||
}
|
||||
|
||||
|
||||
// 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";
|
||||
}
|
||||
|
||||
|
||||
// test atan2
|
||||
{
|
||||
assert floatCompare(atans(0, 0), 0), "atan2(0, 0) failed";
|
||||
assert floatCompare(atans(7, 0), 1.570796), "atans(7, 0) failed";
|
||||
}
|
||||
|
||||
|
||||
// test isnan
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user