Compare commits
9 Commits
math-branc
...
32d6a029dd
| Author | SHA1 | Date | |
|---|---|---|---|
| 32d6a029dd | |||
| 0f155c80be | |||
| 4680597065 | |||
| 792aed13ae | |||
| 08b1edd7a7 | |||
| 6d0dd99406 | |||
| 7717a40574 | |||
| bbf2277b6f | |||
| fd6fbbaed5 |
@@ -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);
|
||||
|
||||
|
||||
@@ -11,13 +11,14 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <uthash.h>
|
||||
|
||||
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
|
||||
|
||||
152
libs/math/math.c
152
libs/math/math.c
@@ -1,5 +1,12 @@
|
||||
#include <groundext.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include <float.h>
|
||||
|
||||
|
||||
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");
|
||||
}
|
||||
@@ -68,11 +68,35 @@ GroundValue groundCreateValue(GroundValueType type, ...) {
|
||||
return createListGroundValue(va_arg(args, List));
|
||||
break;
|
||||
}
|
||||
case FUNCTION: {
|
||||
return createFunctionGroundValue(va_arg(args, GroundFunction*));
|
||||
break;
|
||||
}
|
||||
case STRUCTVAL: {
|
||||
GroundValue gv;
|
||||
gv.type = STRUCTVAL;
|
||||
gv.data.structVal = va_arg(args, GroundStruct*);
|
||||
return gv;
|
||||
break;
|
||||
}
|
||||
case NONE: {
|
||||
return createNoneGroundValue();
|
||||
break;
|
||||
}
|
||||
case ERROR:
|
||||
case CUSTOM: {
|
||||
// FIXME
|
||||
break;
|
||||
}
|
||||
/*
|
||||
default: {
|
||||
return createNoneGroundValue();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return createNoneGroundValue();
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,23 @@ int currentInstruction = 0;
|
||||
|
||||
bool isMainScopeGlobal = true;
|
||||
|
||||
[[noreturn]] void customError(GroundArg type, GroundArg what, GroundInstruction* where, int whereLine, int exitCode) {
|
||||
printf("Ground runtime error:\n ErrorType: ");
|
||||
printGroundArg(&type);
|
||||
printf("\n ErrorContext: ");
|
||||
printGroundArg(&what);
|
||||
printf("\n");
|
||||
if (where != NULL) {
|
||||
printf(" ErrorInstruction: ");
|
||||
printGroundInstruction(where);
|
||||
printf("\n");
|
||||
}
|
||||
if (whereLine > -1) {
|
||||
printf(" ErrorLine: %d\n", whereLine + 1);
|
||||
}
|
||||
exit(exitCode);
|
||||
}
|
||||
|
||||
[[noreturn]] void runtimeError(GroundRuntimeError error, char* what, GroundInstruction* where, int whereLine) {
|
||||
printf("Ground runtime error:\n ErrorType: ");
|
||||
switch (error) {
|
||||
@@ -813,7 +830,19 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ERRORCMD: {
|
||||
if (in->args.length < 3) {
|
||||
runtimeError(TOO_FEW_ARGS, "Expecting 3 args", in, currentInstruction);
|
||||
} else if (in->args.length > 3) {
|
||||
runtimeError(TOO_MANY_ARGS, "Expecting 3 args", in, currentInstruction);
|
||||
}
|
||||
if (in->args.args[2].value.value.type != INT ) {
|
||||
runtimeError(ARG_TYPE_MISMATCH, "Expecting an int for arg 2", in, currentInstruction);
|
||||
}
|
||||
|
||||
customError(in->args.args[0], in->args.args[1], in, currentInstruction, in->args.args[2].value.value.data.intVal);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* VARIABLES AND LISTS
|
||||
* These instructions are for initializing variables and lists.
|
||||
|
||||
@@ -137,6 +137,7 @@ static GroundInstType getInstructionType(const char* inst) {
|
||||
if (strcmp(inst, "input") == 0 || strcmp(inst, "stdin") == 0) return INPUT;
|
||||
if (strcmp(inst, "print") == 0 || strcmp(inst, "stdout") == 0) return PRINT;
|
||||
if (strcmp(inst, "println") == 0 || strcmp(inst, "stdlnout") == 0) return PRINTLN;
|
||||
if (strcmp(inst, "error") == 0) return ERRORCMD;
|
||||
if (strcmp(inst, "set") == 0) return SET;
|
||||
if (strcmp(inst, "gettype") == 0) return GETTYPE;
|
||||
if (strcmp(inst, "exists") == 0) return EXISTS;
|
||||
|
||||
@@ -412,6 +412,9 @@ void printGroundInstruction(GroundInstruction* gi) {
|
||||
break;
|
||||
case CREATELABEL:
|
||||
break;
|
||||
case ERRORCMD:
|
||||
printf("error");
|
||||
break;
|
||||
default:
|
||||
printf("FIXME");
|
||||
break;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "include/uthash.h"
|
||||
|
||||
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 {
|
||||
|
||||
2
tests/error.grnd
Normal file
2
tests/error.grnd
Normal file
@@ -0,0 +1,2 @@
|
||||
setlist &dat 1 2 3 "Hi!"
|
||||
error "Hello" $dat 1
|
||||
Reference in New Issue
Block a user