diff --git a/include/groundext.h b/include/groundext.h index 735b9b7..d3c76b5 100644 --- a/include/groundext.h +++ b/include/groundext.h @@ -14,17 +14,6 @@ extern "C" { struct GroundScope; typedef struct GroundScope GroundScope; -/* - * Stores data associated with an error thrown during Ground execution. - */ -typedef struct GroundError { - char* what; - char* type; - struct GroundInstruction* where; - size_t line; - bool hasLine; -} GroundError; - // Creates a GroundValue containing (in), with type ERROR. GroundValue createErrorGroundValue(GroundError in); diff --git a/include/groundvm.h b/include/groundvm.h index 222d867..58bb07a 100644 --- a/include/groundvm.h +++ b/include/groundvm.h @@ -11,13 +11,14 @@ #include #include #include +#include typedef enum GroundInstType { - IF, JUMP, END, INPUT, PRINT, PRINTLN, SET, GETTYPE, EXISTS, SETLIST, SETLISTAT, GETLISTAT, GETLISTSIZE, LISTAPPEND, GETSTRSIZE, GETSTRCHARAT, ADD, SUBTRACT, MULTIPLY, DIVIDE, EQUAL, INEQUAL, NOT, GREATER, LESSER, STOI, STOD, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, STRUCT, ENDSTRUCT, INIT, USE, EXTERN, CREATELABEL, PAUSE, DROP + IF, JUMP, END, INPUT, PRINT, PRINTLN, SET, GETTYPE, EXISTS, SETLIST, SETLISTAT, GETLISTAT, GETLISTSIZE, LISTAPPEND, GETSTRSIZE, GETSTRCHARAT, ADD, SUBTRACT, MULTIPLY, DIVIDE, EQUAL, INEQUAL, NOT, GREATER, LESSER, STOI, STOD, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, STRUCT, ENDSTRUCT, INIT, USE, EXTERN, CREATELABEL, PAUSE, DROP, ERRORCMD } GroundInstType; typedef enum GroundValueType { - INT, DOUBLE, STRING, CHAR, BOOL, LIST, FUNCTION, CUSTOM, NONE + INT, DOUBLE, STRING, CHAR, BOOL, LIST, FUNCTION, STRUCTVAL, CUSTOM, ERROR, NONE } GroundValueType; typedef enum GroundArgType { @@ -41,6 +42,17 @@ typedef struct List { struct GroundValue* values; } List; +/* + * Stores data associated with an error thrown during Ground execution. + */ +typedef struct GroundError { + char* what; + char* type; + struct GroundInstruction* where; + size_t line; + bool hasLine; +} GroundError; + /* * Stores literal values created in a Ground program. */ @@ -53,8 +65,10 @@ typedef struct GroundValue { char charVal; bool boolVal; List listVal; + GroundError errorVal; struct GroundFunction* fnVal; - void* customVal; + struct GroundStruct* structVal; + struct GroundObject* customVal; } data; } GroundValue; @@ -115,6 +129,39 @@ typedef struct GroundFunction { size_t startLine; } GroundFunction; +/* + * Field for a GroundStruct + */ +typedef struct GroundStructField { + char id[64]; + GroundValue value; + UT_hash_handle hh; +} GroundStructField; + +/* + * Represents a Ground struct. + */ +typedef struct GroundStruct { + GroundStructField* fields; + size_t size; +} GroundStruct; + +/* + * Field for a GroundObject + */ +typedef struct GroundObjectField { + char id[64]; + GroundValue value; + UT_hash_handle hh; +} GroundObjectField; + +/* + * Represents an initialised Ground struct. + */ +typedef struct GroundObject { + GroundObjectField* fields; +} GroundObject; + #ifdef __cplusplus extern "C" { #endif @@ -133,6 +180,9 @@ GroundValue groundCreateValue(GroundValueType type, ...); GroundProgram groundParseFile(const char* code); +GroundStruct groundCreateStruct(); +void groundAddFieldToStruct(GroundStruct* gstruct, char* name, GroundValue field); + #ifdef __cplusplus } #endif diff --git a/libs/math/math.c b/libs/math/math.c index b48744c..6969778 100644 --- a/libs/math/math.c +++ b/libs/math/math.c @@ -1,5 +1,12 @@ #include #include +#include +#include +#include +#include +#include +#include + GroundValue ground_sin(GroundScope* scope, List args) { return groundCreateValue( @@ -21,19 +28,15 @@ GroundValue ground_tan(GroundScope* scope, List args) { } GroundValue rad_to_deg(GroundScope* scope, List args) { - double radians = args.values[0].data.doubleVal; - return groundCreateValue( DOUBLE, - radians * (180.0 / M_PI) + args.values[0].data.doubleVal * (180.0 / M_PI) ); } GroundValue deg_to_rad(GroundScope* scope, List args) { - double deg = args.values[0].data.doubleVal; - return groundCreateValue( DOUBLE, - deg * (M_PI / 180.0) + args.values[0].data.doubleVal * (M_PI / 180.0) ); } @@ -62,16 +65,149 @@ GroundValue ground_sqrt(GroundScope* scope, List args) { ); } +GroundValue ground_abs(GroundScope* scope, List args) { + return groundCreateValue( + DOUBLE, + abs(args.values[0].data.doubleVal) + ); +} +GroundValue ground_min(GroundScope* scope, List args) { + double a = args.values[0].data.doubleVal; + double b = args.values[1].data.doubleVal; + + return groundCreateValue( + DOUBLE, + (a < b) ? a : b + ); +} +GroundValue ground_max(GroundScope* scope, List args) { + double a = args.values[0].data.doubleVal; + double b = args.values[1].data.doubleVal; + + return groundCreateValue( + DOUBLE, + (a > b) ? a : b + ); +} +GroundValue ground_clamp(GroundScope* scope, List args) { + double number = args.values[0].data.doubleVal; + double min = args.values[1].data.doubleVal; + double max = args.values[2].data.doubleVal; + + if (number < min) number = min; + if (number > max) number = max; + + return groundCreateValue( + DOUBLE, + number + ); +} + +GroundValue ground_round(GroundScope* scope, List args) { + double x = args.values[0].data.doubleVal; + + if (x >= 0.0) + return groundCreateValue( + INT, + (long long)(x + 0.5) + ); + else + return groundCreateValue( + INT, + (long long)(x - 0.5) + ); +} +GroundValue ground_floor(GroundScope* scope, List args) { + double x = args.values[0].data.doubleVal; + + if (x >= (double)LLONG_MAX) return groundCreateValue(INT, LLONG_MAX); + if (x <= (double)LLONG_MIN) return groundCreateValue(INT, LLONG_MIN); + + long long i = (long long)x; // truncates toward zero + + if (x < 0 && x != (double)i) { + return groundCreateValue( + INT, + i-1 + ); + } + + return groundCreateValue( + INT, + i + ); +} +GroundValue ground_ceil(GroundScope* scope, List args) { + double x = args.values[0].data.doubleVal; + + if (x >= (double)LLONG_MAX) return groundCreateValue(INT, LLONG_MAX); + if (x <= (double)LLONG_MIN) return groundCreateValue(INT, LLONG_MIN); + + + long long i = (long long)x; // truncates toward zero + + if (x > 0 && x != (double)i) { + return groundCreateValue( + INT, + i+1 + ); + } + + return groundCreateValue( + INT, + i + ); +} + +GroundValue ground_random(GroundScope* scope, List args) { + int64_t min = args.values[0].data.intVal; + int64_t max = args.values[1].data.intVal; + + return groundCreateValue( + INT, + min + rand() % (max - min) + ); +} +GroundValue ground_random_double(GroundScope* scope, List args) { + double min = args.values[0].data.doubleVal; + double max = args.values[1].data.doubleVal; + + return groundCreateValue( + DOUBLE, + min + (double)rand() / RAND_MAX * (max - min) + ); +} +GroundValue ground_random_set_seed(GroundScope* scope, List args) { + srand(args.values[0].data.intVal); + return groundCreateValue( + INT, + 0 + ); +} + void ground_init(GroundScope* scope) { + srand((unsigned)time(NULL) ^ (unsigned)clock()); + groundAddNativeFunction(scope, "math_Sin", ground_sin, DOUBLE, 1, DOUBLE, "radians"); groundAddNativeFunction(scope, "math_Cos", ground_cos, DOUBLE, 1, DOUBLE, "radians"); groundAddNativeFunction(scope, "math_Tan", ground_tan, DOUBLE, 1, DOUBLE, "radians"); - groundAddNativeFunction(scope, "math_DegreesToRadians", deg_to_rad, DOUBLE, 1, DOUBLE, "degrees"); groundAddNativeFunction(scope, "math_RadiansToDegrees", rad_to_deg, DOUBLE, 1, DOUBLE, "radians"); groundAddNativeFunction(scope, "math_Modulos", ground_modulos, DOUBLE, 2, DOUBLE, "number1", DOUBLE, "number2"); groundAddNativeFunction(scope, "math_Pow", ground_pow, DOUBLE, 2, DOUBLE, "number1", DOUBLE, "number2"); - groundAddNativeFunction(scope, "math_Sqrt", ground_sqrt, DOUBLE, 1, DOUBLE, "number"); + + groundAddNativeFunction(scope, "math_Abs", ground_abs, DOUBLE, 1, DOUBLE, "number"); + groundAddNativeFunction(scope, "math_Min", ground_min, DOUBLE, 2, DOUBLE, "number1", DOUBLE, "number2"); + groundAddNativeFunction(scope, "math_Max", ground_max, DOUBLE, 2, DOUBLE, "number1", DOUBLE, "number2"); + groundAddNativeFunction(scope, "math_Clamp", ground_clamp, DOUBLE, 2, DOUBLE, "number", DOUBLE, "min", DOUBLE, "max"); + + groundAddNativeFunction(scope, "math_Round", ground_round, INT, 1, DOUBLE, "number"); + groundAddNativeFunction(scope, "math_Floor", ground_floor, INT, 1, DOUBLE, "number"); + groundAddNativeFunction(scope, "math_Ceil", ground_ceil, INT, 1, DOUBLE, "number"); + + groundAddNativeFunction(scope, "math_Random", ground_random, INT, 2, INT, "min", INT, "max"); + groundAddNativeFunction(scope, "math_RandomDouble", ground_random_double, DOUBLE, 2, DOUBLE, "min", DOUBLE, "max"); + groundAddNativeFunction(scope, "math_RandomSetSeed", ground_random_set_seed, INT, 1, INT, "seed"); } \ No newline at end of file diff --git a/src/interface.c b/src/interface.c index e97e9b9..2f41515 100644 --- a/src/interface.c +++ b/src/interface.c @@ -78,19 +78,15 @@ GroundValue groundCreateValue(GroundValueType type, ...) { *gv.data.structVal = va_arg(args, GroundStruct); return gv; } - case CUSTOM: { - // FIXME do this later lmao - return createNoneGroundValue(); - break; - } - case ERROR: { - return createErrorGroundValue(va_arg(args, GroundError)); - break; - } case NONE: { return createNoneGroundValue(); break; } + case ERROR: + case CUSTOM: { + // FIXME + break; + } } return createNoneGroundValue();