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;
|
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) {
|
static int nativeIsnan(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||||
if (arguments->count != 1) {
|
if (arguments->count != 1) {
|
||||||
interpreter->errorOutput("Incorrect number of arguments to tan\n");
|
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},
|
{"sin", nativeSin},
|
||||||
{"cos", nativeCos},
|
{"cos", nativeCos},
|
||||||
{"tan", nativeTan},
|
{"tan", nativeTan},
|
||||||
|
{"asin", nativeAsin},
|
||||||
|
{"acos", nativeAcos},
|
||||||
|
{"atan", nativeAtan},
|
||||||
|
{"atans", nativeAtan2},
|
||||||
|
|
||||||
// Comparison
|
// Comparison
|
||||||
{"isnan", nativeIsnan},
|
{"isnan", nativeIsnan},
|
||||||
|
|||||||
@@ -71,6 +71,44 @@ import math;
|
|||||||
assert floatCompare(cos(0), 1), "cos(0) failed";
|
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
|
// test isnan
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user