mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Added math library
This commit is contained in:
604
repl/lib_math.c
Normal file
604
repl/lib_math.c
Normal file
@@ -0,0 +1,604 @@
|
||||
#include "lib_math.h"
|
||||
|
||||
#include "toy_memory.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define LIB_MATH_PI 3.14159265358979323846f
|
||||
#define LIB_MATH_E 2.71828182845904523536f
|
||||
|
||||
static int nativeMod(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to sin\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the arguments
|
||||
Toy_Literal xLiteral = Toy_popLiteralArray(arguments);
|
||||
Toy_Literal yLiteral = 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 sin\n");
|
||||
Toy_freeLiteral(xLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(TOY_IS_INTEGER(yLiteral) || TOY_IS_FLOAT(yLiteral))) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to sin\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 != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to sin\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the arguments
|
||||
Toy_Literal xLiteral = Toy_popLiteralArray(arguments);
|
||||
Toy_Literal yLiteral = 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 sin\n");
|
||||
Toy_freeLiteral(xLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(TOY_IS_INTEGER(yLiteral) || TOY_IS_FLOAT(yLiteral))) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to sin\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 = powf(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 nativeSqrt(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to sin\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the argument
|
||||
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);
|
||||
}
|
||||
|
||||
//check the argument type
|
||||
if (!(TOY_IS_INTEGER(xLiteral) || TOY_IS_FLOAT(xLiteral))) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to sin\n");
|
||||
Toy_freeLiteral(xLiteral);
|
||||
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);
|
||||
|
||||
// calculate the result
|
||||
float result = sqrtf(x);
|
||||
|
||||
//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 nativeCbrt(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to sin\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the argument
|
||||
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);
|
||||
}
|
||||
|
||||
//check the argument type
|
||||
if (!(TOY_IS_INTEGER(xLiteral) || TOY_IS_FLOAT(xLiteral))) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to sin\n");
|
||||
Toy_freeLiteral(xLiteral);
|
||||
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);
|
||||
|
||||
// calculate the result
|
||||
float result = cbrtf(x);
|
||||
|
||||
//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 nativeHypot(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to sin\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the arguments
|
||||
Toy_Literal xLiteral = Toy_popLiteralArray(arguments);
|
||||
Toy_Literal yLiteral = 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 sin\n");
|
||||
Toy_freeLiteral(xLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(TOY_IS_INTEGER(yLiteral) || TOY_IS_FLOAT(yLiteral))) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to sin\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 = hypotf(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 nativeToRad(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to toRad\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the argument
|
||||
Toy_Literal degreesLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
//parse the argument (if it's an identifier)
|
||||
Toy_Literal degreesLiteralIdn = degreesLiteral;
|
||||
if (TOY_IS_IDENTIFIER(degreesLiteral) && Toy_parseIdentifierToValue(interpreter, °reesLiteral)) {
|
||||
Toy_freeLiteral(degreesLiteralIdn);
|
||||
}
|
||||
|
||||
//check the argument type
|
||||
if (!(TOY_IS_INTEGER(degreesLiteral) || TOY_IS_FLOAT(degreesLiteral))) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to toRad\n");
|
||||
Toy_freeLiteral(degreesLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// cast int to float to handle all types of numbers
|
||||
float degrees = TOY_IS_INTEGER(degreesLiteral)? TOY_AS_INTEGER(degreesLiteral) : TOY_AS_FLOAT(degreesLiteral);
|
||||
|
||||
float result = degrees * (LIB_MATH_PI / 180.0);
|
||||
|
||||
//return the result
|
||||
Toy_Literal resultLiteral = TOY_TO_FLOAT_LITERAL(result);
|
||||
Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteral(resultLiteral);
|
||||
Toy_freeLiteral(degreesLiteral);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeToDeg(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to toDeg\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 toDeg\n");
|
||||
Toy_freeLiteral(radiansLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// cast int to float to handle all types of numbers
|
||||
float radians = TOY_IS_INTEGER(radiansLiteral)? TOY_AS_INTEGER(radiansLiteral) : TOY_AS_FLOAT(radiansLiteral);
|
||||
|
||||
float result = radians * (180.0 / LIB_MATH_PI);
|
||||
|
||||
//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 nativeSin(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to sin\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 sin\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 = sinf(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 nativeCos(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to cos\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 cos\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 = cosf(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 nativeTan(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to tan\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 tan\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 = tanf(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 nativeTan(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to tan\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 tan\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 = tanf(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;
|
||||
}
|
||||
|
||||
//call the hook
|
||||
typedef struct Natives {
|
||||
char* name;
|
||||
Toy_NativeFn fn;
|
||||
} 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},
|
||||
{"cbrt", nativeCbrt},
|
||||
{"hypot", nativeHypot},
|
||||
|
||||
// Trigonometric
|
||||
{"toRad", nativeToRad},
|
||||
{"toDeg", nativeToDeg},
|
||||
{"sin", nativeSin},
|
||||
{"cos", nativeCos},
|
||||
{"tan", nativeTan},
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
// math constants
|
||||
Toy_Literal piKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("PI"));
|
||||
Toy_Literal piIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("PI"));
|
||||
Toy_Literal piLiteral = TOY_TO_FLOAT_LITERAL(LIB_MATH_PI);
|
||||
|
||||
Toy_Literal eKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("E"));
|
||||
Toy_Literal eIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("E"));
|
||||
Toy_Literal eLiteral = TOY_TO_FLOAT_LITERAL(LIB_MATH_E);
|
||||
|
||||
|
||||
//store the library in an aliased dictionary
|
||||
if (!TOY_IS_NULL(alias)) {
|
||||
//make sure the name isn't taken
|
||||
if (Toy_isDeclaredScopeVariable(interpreter->scope, alias)) {
|
||||
interpreter->errorOutput("Can't override an existing variable\n");
|
||||
Toy_freeLiteral(alias);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//create the dictionary to load up with functions
|
||||
Toy_LiteralDictionary* dictionary = TOY_ALLOCATE(Toy_LiteralDictionary, 1);
|
||||
Toy_initLiteralDictionary(dictionary);
|
||||
|
||||
//load the dict with functions
|
||||
for (int i = 0; natives[i].name; i++) {
|
||||
Toy_Literal name = TOY_TO_STRING_LITERAL(Toy_createRefString(natives[i].name));
|
||||
Toy_Literal func = TOY_TO_FUNCTION_NATIVE_LITERAL(natives[i].fn);
|
||||
|
||||
Toy_setLiteralDictionary(dictionary, name, func);
|
||||
|
||||
Toy_freeLiteral(name);
|
||||
Toy_freeLiteral(func);
|
||||
}
|
||||
|
||||
Toy_setLiteralDictionary(dictionary, piKeyLiteral, piLiteral);
|
||||
Toy_setLiteralDictionary(dictionary, eKeyLiteral, eLiteral);
|
||||
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
//default
|
||||
for (int i = 0; natives[i].name; i++) {
|
||||
Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn);
|
||||
}
|
||||
|
||||
if (
|
||||
Toy_isDeclaredScopeVariable(interpreter->scope, piKeyLiteral) ||
|
||||
Toy_isDeclaredScopeVariable(interpreter->scope, eKeyLiteral)
|
||||
) {
|
||||
interpreter->errorOutput("Can't override an existing variable\n");
|
||||
|
||||
// cleanup
|
||||
Toy_freeLiteral(alias);
|
||||
Toy_freeLiteral(piIdentifierLiteral);
|
||||
Toy_freeLiteral(piKeyLiteral);
|
||||
Toy_freeLiteral(eIdentifierLiteral);
|
||||
Toy_freeLiteral(eKeyLiteral);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_Literal floatType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FLOAT, false);
|
||||
|
||||
// pi
|
||||
Toy_declareScopeVariable(interpreter->scope, piIdentifierLiteral, floatType);
|
||||
Toy_setScopeVariable(interpreter->scope, piIdentifierLiteral, piLiteral, false);
|
||||
|
||||
// e
|
||||
Toy_declareScopeVariable(interpreter->scope, eIdentifierLiteral, floatType);
|
||||
Toy_setScopeVariable(interpreter->scope, eIdentifierLiteral, eLiteral, false);
|
||||
|
||||
// cleanup
|
||||
Toy_freeLiteral(floatType);
|
||||
Toy_freeLiteral(piKeyLiteral);
|
||||
Toy_freeLiteral(piIdentifierLiteral);
|
||||
Toy_freeLiteral(piLiteral);
|
||||
Toy_freeLiteral(eKeyLiteral);
|
||||
Toy_freeLiteral(eIdentifierLiteral);
|
||||
Toy_freeLiteral(eLiteral);
|
||||
|
||||
return 0;
|
||||
}
|
||||
5
repl/lib_math.h
Normal file
5
repl/lib_math.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "toy_interpreter.h"
|
||||
|
||||
int Toy_hookMath(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Literal alias);
|
||||
@@ -7,10 +7,6 @@
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define STD_MATH_PI 3.14159265358979323846f
|
||||
#define STD_MATH_E 2.71828182845904523536f
|
||||
#define STD_MATH_LIMIT 20
|
||||
|
||||
static int nativeClock(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 0) {
|
||||
@@ -587,178 +583,6 @@ static int nativeLerp(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeToRad(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to toRad\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//get the argument
|
||||
Toy_Literal degreesLiteral = Toy_popLiteralArray(arguments);
|
||||
|
||||
//parse the argument (if it's an identifier)
|
||||
Toy_Literal degreesLiteralIdn = degreesLiteral;
|
||||
if (TOY_IS_IDENTIFIER(degreesLiteral) && Toy_parseIdentifierToValue(interpreter, °reesLiteral)) {
|
||||
Toy_freeLiteral(degreesLiteralIdn);
|
||||
}
|
||||
|
||||
//check the argument type
|
||||
if (!(TOY_IS_INTEGER(degreesLiteral) || TOY_IS_FLOAT(degreesLiteral))) {
|
||||
interpreter->errorOutput("Incorrect argument type passed to toRad\n");
|
||||
Toy_freeLiteral(degreesLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// cast int to float to handle all types of numbers
|
||||
float degrees = TOY_IS_INTEGER(degreesLiteral)? TOY_AS_INTEGER(degreesLiteral) : TOY_AS_FLOAT(degreesLiteral);
|
||||
|
||||
float result = degrees * (STD_MATH_PI / 180.0);
|
||||
|
||||
//return the result
|
||||
Toy_Literal resultLiteral = TOY_TO_FLOAT_LITERAL(result);
|
||||
Toy_pushLiteralArray(&interpreter->stack, resultLiteral);
|
||||
|
||||
//cleanup
|
||||
Toy_freeLiteral(resultLiteral);
|
||||
Toy_freeLiteral(degreesLiteral);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nativeToDeg(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to toDeg\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 toDeg\n");
|
||||
Toy_freeLiteral(radiansLiteral);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// cast int to float to handle all types of numbers
|
||||
float radians = TOY_IS_INTEGER(radiansLiteral)? TOY_AS_INTEGER(radiansLiteral) : TOY_AS_FLOAT(radiansLiteral);
|
||||
|
||||
float result = radians * (180.0 / STD_MATH_PI);
|
||||
|
||||
//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 nativeSin(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to sin\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 sin\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
|
||||
// using Taylor series approximation
|
||||
float result = radians;
|
||||
float numerator = radians;
|
||||
float denominator = 1;
|
||||
|
||||
for (int i = 1; i <= STD_MATH_LIMIT; i++) {
|
||||
numerator *= radians * radians;
|
||||
denominator *= (2 * i) * (2 * i + 1);
|
||||
|
||||
float value = numerator / denominator;
|
||||
|
||||
if (i & 0x01)
|
||||
result -= value;
|
||||
else
|
||||
result += value;
|
||||
}
|
||||
|
||||
//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 nativeCos(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
if (arguments->count != 1) {
|
||||
interpreter->errorOutput("Incorrect number of arguments to sin\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 lerp\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
|
||||
// using Taylor series approximation
|
||||
|
||||
// TODO
|
||||
float result = -1;
|
||||
|
||||
//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 nativeConcat(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) {
|
||||
//no arguments
|
||||
if (arguments->count != 2) {
|
||||
@@ -2324,10 +2148,6 @@ int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_L
|
||||
{"normalize", nativeNormalize},
|
||||
{"clamp", nativeClamp},
|
||||
{"lerp", nativeLerp},
|
||||
{"toRad", nativeToRad},
|
||||
{"toDeg", nativeToDeg},
|
||||
{"sin", nativeSin},
|
||||
{"cos", nativeCos},
|
||||
|
||||
//compound utils
|
||||
{"concat", nativeConcat}, //array, dictionary, string
|
||||
@@ -2352,16 +2172,6 @@ int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_L
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
// math constants
|
||||
Toy_Literal piKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("PI"));
|
||||
Toy_Literal piIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("PI"));
|
||||
Toy_Literal piLiteral = TOY_TO_FLOAT_LITERAL(STD_MATH_PI);
|
||||
|
||||
Toy_Literal eKeyLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString("E"));
|
||||
Toy_Literal eIdentifierLiteral = TOY_TO_IDENTIFIER_LITERAL(Toy_createRefString("E"));
|
||||
Toy_Literal eLiteral = TOY_TO_FLOAT_LITERAL(STD_MATH_PI);
|
||||
|
||||
|
||||
//store the library in an aliased dictionary
|
||||
if (!TOY_IS_NULL(alias)) {
|
||||
//make sure the name isn't taken
|
||||
@@ -2386,31 +2196,6 @@ int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_L
|
||||
Toy_freeLiteral(func);
|
||||
}
|
||||
|
||||
Toy_setLiteralDictionary(dictionary, piKeyLiteral, piLiteral);
|
||||
Toy_setLiteralDictionary(dictionary, eKeyLiteral, eLiteral);
|
||||
|
||||
//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);
|
||||
Toy_freeLiteral(piKeyLiteral);
|
||||
Toy_freeLiteral(piIdentifierLiteral);
|
||||
Toy_freeLiteral(piLiteral);
|
||||
Toy_freeLiteral(eKeyLiteral);
|
||||
Toy_freeLiteral(eIdentifierLiteral);
|
||||
Toy_freeLiteral(eLiteral);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2419,34 +2204,5 @@ int Toy_hookStandard(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_L
|
||||
Toy_injectNativeFn(interpreter, natives[i].name, natives[i].fn);
|
||||
}
|
||||
|
||||
if (Toy_isDeclaredScopeVariable(interpreter->scope, piKeyLiteral)) {
|
||||
interpreter->errorOutput("Can't override an existing variable\n");
|
||||
|
||||
// cleanup
|
||||
Toy_freeLiteral(alias);
|
||||
Toy_freeLiteral(piKeyLiteral);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
Toy_Literal floatType = TOY_TO_TYPE_LITERAL(TOY_LITERAL_FLOAT, false);
|
||||
|
||||
// pi
|
||||
Toy_declareScopeVariable(interpreter->scope, piIdentifierLiteral, floatType);
|
||||
Toy_setScopeVariable(interpreter->scope, piIdentifierLiteral, piLiteral, false);
|
||||
|
||||
// e
|
||||
Toy_declareScopeVariable(interpreter->scope, eIdentifierLiteral, floatType);
|
||||
Toy_setScopeVariable(interpreter->scope, eIdentifierLiteral, eLiteral, false);
|
||||
|
||||
// cleanup
|
||||
Toy_freeLiteral(floatType);
|
||||
Toy_freeLiteral(piKeyLiteral);
|
||||
Toy_freeLiteral(piIdentifierLiteral);
|
||||
Toy_freeLiteral(piLiteral);
|
||||
Toy_freeLiteral(eKeyLiteral);
|
||||
Toy_freeLiteral(eIdentifierLiteral);
|
||||
Toy_freeLiteral(eLiteral);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ CC=gcc
|
||||
|
||||
IDIR+=. ../source
|
||||
CFLAGS+=$(addprefix -I,$(IDIR)) -g -Wall -W -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable
|
||||
LIBS+=-ltoy
|
||||
LIBS+=-ltoy -lm
|
||||
|
||||
ODIR = obj
|
||||
SRC = $(wildcard *.c)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "lib_standard.h"
|
||||
#include "lib_random.h"
|
||||
#include "lib_runner.h"
|
||||
#include "lib_math.h"
|
||||
|
||||
#include "toy_console_colors.h"
|
||||
|
||||
@@ -30,6 +31,7 @@ void repl(const char* initialInput) {
|
||||
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
|
||||
Toy_injectNativeHook(&interpreter, "random", Toy_hookRandom);
|
||||
Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
|
||||
Toy_injectNativeHook(&interpreter, "math", Toy_hookMath);
|
||||
|
||||
for(;;) {
|
||||
if (!initialInput) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "lib_standard.h"
|
||||
#include "lib_random.h"
|
||||
#include "lib_runner.h"
|
||||
#include "lib_math.h"
|
||||
|
||||
#include "toy_console_colors.h"
|
||||
|
||||
@@ -115,6 +116,7 @@ void Toy_runBinary(const unsigned char* tb, size_t size) {
|
||||
Toy_injectNativeHook(&interpreter, "standard", Toy_hookStandard);
|
||||
Toy_injectNativeHook(&interpreter, "random", Toy_hookRandom);
|
||||
Toy_injectNativeHook(&interpreter, "runner", Toy_hookRunner);
|
||||
Toy_injectNativeHook(&interpreter, "math", Toy_hookMath);
|
||||
|
||||
Toy_runInterpreter(&interpreter, tb, (int)size);
|
||||
Toy_freeInterpreter(&interpreter);
|
||||
|
||||
@@ -2,7 +2,7 @@ CC=gcc
|
||||
|
||||
IDIR +=. ../source ../repl
|
||||
CFLAGS +=$(addprefix -I,$(IDIR)) -g -Wall -W -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable
|
||||
LIBS +=
|
||||
LIBS +=-lm
|
||||
ODIR = obj
|
||||
TARGETS = $(wildcard ../source/*.c) $(wildcard ../repl/lib_*.c) ../repl/repl_tools.c ../repl/drive_system.c
|
||||
TESTS = $(wildcard test_*.c)
|
||||
|
||||
27
test/scripts/lib/math.toy
Normal file
27
test/scripts/lib/math.toy
Normal file
@@ -0,0 +1,27 @@
|
||||
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";
|
||||
}
|
||||
|
||||
|
||||
// test toDeg
|
||||
{
|
||||
assert toDeg(0) == 0, "toDeg 0 failed";
|
||||
assert toDeg(PI) == 180, "toDeg π failed";
|
||||
assert toDeg(2 * PI) == 360, "toDeg 2π failed";
|
||||
}
|
||||
|
||||
// test sin
|
||||
{
|
||||
assert sin(PI) == 0, "sin π failed";
|
||||
}
|
||||
|
||||
|
||||
// test cos
|
||||
{
|
||||
assert cos(PI) == -1, "cos π failed";
|
||||
}
|
||||
@@ -158,32 +158,6 @@ import standard;
|
||||
}
|
||||
|
||||
|
||||
// test toRad
|
||||
{
|
||||
assert toRad(0) == 0, "toRad 0° failed";
|
||||
assert toRad(180) == PI, "toRad 180° failed";
|
||||
assert toRad(360) == 2 * PI, "toRad 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";
|
||||
}
|
||||
|
||||
// test sin
|
||||
{
|
||||
assert sin(PI) == 0, "sin π failed";
|
||||
}
|
||||
|
||||
|
||||
// test cos
|
||||
{
|
||||
assert cos(PI) == -1, "cos π failed";
|
||||
}
|
||||
|
||||
//test concat
|
||||
{
|
||||
//test array concat
|
||||
|
||||
Reference in New Issue
Block a user