Compare commits
7 Commits
math-branc
...
8eef78c310
| Author | SHA1 | Date | |
|---|---|---|---|
| 8eef78c310 | |||
| ec23d55f9d | |||
| 724162f42e | |||
| 6d0dd99406 | |||
| 7717a40574 | |||
| bbf2277b6f | |||
| fd6fbbaed5 |
@@ -13,6 +13,23 @@ int currentInstruction = 0;
|
|||||||
|
|
||||||
bool isMainScopeGlobal = true;
|
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) {
|
[[noreturn]] void runtimeError(GroundRuntimeError error, char* what, GroundInstruction* where, int whereLine) {
|
||||||
printf("Ground runtime error:\n ErrorType: ");
|
printf("Ground runtime error:\n ErrorType: ");
|
||||||
switch (error) {
|
switch (error) {
|
||||||
@@ -382,6 +399,7 @@ GroundStruct parseStruct(GroundProgram* in, GroundScope* scope, size_t errorOffs
|
|||||||
gv.type = CUSTOM;
|
gv.type = CUSTOM;
|
||||||
gv.data.customVal = malloc(sizeof(GroundObject));
|
gv.data.customVal = malloc(sizeof(GroundObject));
|
||||||
*gv.data.customVal = createObject(*gstruct);
|
*gv.data.customVal = createObject(*gstruct);
|
||||||
|
gv.customType = gstruct;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NONE: {
|
case NONE: {
|
||||||
@@ -813,7 +831,19 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
|||||||
}
|
}
|
||||||
break;
|
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
|
* VARIABLES AND LISTS
|
||||||
* These instructions are for initializing variables and lists.
|
* These instructions are for initializing variables and lists.
|
||||||
@@ -1753,7 +1783,8 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
|||||||
if (in->args.args[i + 1].type != VALUE) {
|
if (in->args.args[i + 1].type != VALUE) {
|
||||||
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value", in, currentInstruction);
|
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value", in, currentInstruction);
|
||||||
}
|
}
|
||||||
if (in->args.args[i + 1].value.value.type != function->args[i].type) {
|
//if (in->args.args[i + 1].value.value.type != function->args[i].type) {
|
||||||
|
if (!checkFnTypes(&in->args.args[i + 1].value.value, &function->args[i])) {
|
||||||
runtimeError(ARG_TYPE_MISMATCH, "Mismatched function argument types", in, currentInstruction);
|
runtimeError(ARG_TYPE_MISMATCH, "Mismatched function argument types", in, currentInstruction);
|
||||||
}
|
}
|
||||||
appendToList(&argsList, in->args.args[i + 1].value.value);
|
appendToList(&argsList, in->args.args[i + 1].value.value);
|
||||||
@@ -1781,7 +1812,8 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
|||||||
if (in->args.args[i + 1].type != VALUE) {
|
if (in->args.args[i + 1].type != VALUE) {
|
||||||
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value", in, currentInstruction);
|
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Value", in, currentInstruction);
|
||||||
}
|
}
|
||||||
if (in->args.args[i + 1].value.value.type != function->args[i].type) {
|
//if (in->args.args[i + 1].value.value.type != function->args[i].type) {
|
||||||
|
if (!checkFnTypes(&in->args.args[i + 1].value.value, &function->args[i])) {
|
||||||
runtimeError(ARG_TYPE_MISMATCH, "Mismatched function argument types", in, currentInstruction);
|
runtimeError(ARG_TYPE_MISMATCH, "Mismatched function argument types", in, currentInstruction);
|
||||||
}
|
}
|
||||||
addVariable(newScope.variables, function->args[i].name, in->args.args[i + 1].value.value);
|
addVariable(newScope.variables, function->args[i].name, in->args.args[i + 1].value.value);
|
||||||
@@ -1979,6 +2011,7 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
|||||||
gv.type = CUSTOM;
|
gv.type = CUSTOM;
|
||||||
gv.data.customVal = malloc(sizeof(GroundObject));
|
gv.data.customVal = malloc(sizeof(GroundObject));
|
||||||
*gv.data.customVal = createObject(*gstruct);
|
*gv.data.customVal = createObject(*gstruct);
|
||||||
|
gv.customType = gstruct;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NONE: {
|
case NONE: {
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ static GroundInstType getInstructionType(const char* inst) {
|
|||||||
if (strcmp(inst, "input") == 0 || strcmp(inst, "stdin") == 0) return INPUT;
|
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, "print") == 0 || strcmp(inst, "stdout") == 0) return PRINT;
|
||||||
if (strcmp(inst, "println") == 0 || strcmp(inst, "stdlnout") == 0) return PRINTLN;
|
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, "set") == 0) return SET;
|
||||||
if (strcmp(inst, "gettype") == 0) return GETTYPE;
|
if (strcmp(inst, "gettype") == 0) return GETTYPE;
|
||||||
if (strcmp(inst, "exists") == 0) return EXISTS;
|
if (strcmp(inst, "exists") == 0) return EXISTS;
|
||||||
|
|||||||
43
src/types.c
43
src/types.c
@@ -412,6 +412,9 @@ void printGroundInstruction(GroundInstruction* gi) {
|
|||||||
break;
|
break;
|
||||||
case CREATELABEL:
|
case CREATELABEL:
|
||||||
break;
|
break;
|
||||||
|
case ERRORCMD:
|
||||||
|
printf("error");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
printf("FIXME");
|
printf("FIXME");
|
||||||
break;
|
break;
|
||||||
@@ -582,3 +585,43 @@ GroundError createGroundError(char* what, char* type, GroundInstruction* where,
|
|||||||
|
|
||||||
return ge;
|
return ge;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool checkFnTypes(GroundValue* left, GroundFunctionArgs* right) {
|
||||||
|
if (left->type != right->type) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (left->type == CUSTOM) {
|
||||||
|
if (left->customType->size != right->customType->size) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < left->customType->size; i++) {
|
||||||
|
if (strcmp(left->customType->fields[i].id, right->customType->fields[i].id) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!checkTypes(&left->customType->fields[i].value, &right->customType->fields[i].value)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkTypes(GroundValue* left, GroundValue* right) {
|
||||||
|
if (left->type != right->type) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (left->type == CUSTOM) {
|
||||||
|
if (left->customType->size != right->customType->size) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < left->customType->size; i++) {
|
||||||
|
if (strcmp(left->customType->fields[i].id, right->customType->fields[i].id) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!checkTypes(&left->customType->fields[i].value, &right->customType->fields[i].value)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include "include/uthash.h"
|
#include "include/uthash.h"
|
||||||
|
|
||||||
typedef enum GroundInstType {
|
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;
|
} GroundInstType;
|
||||||
|
|
||||||
typedef enum GroundValueType {
|
typedef enum GroundValueType {
|
||||||
@@ -62,6 +62,7 @@ typedef struct GroundError {
|
|||||||
*/
|
*/
|
||||||
typedef struct GroundValue {
|
typedef struct GroundValue {
|
||||||
GroundValueType type;
|
GroundValueType type;
|
||||||
|
struct GroundStruct* customType;
|
||||||
union {
|
union {
|
||||||
int64_t intVal;
|
int64_t intVal;
|
||||||
double doubleVal;
|
double doubleVal;
|
||||||
@@ -125,6 +126,7 @@ typedef struct GroundProgram {
|
|||||||
*/
|
*/
|
||||||
typedef struct GroundFunctionArgs {
|
typedef struct GroundFunctionArgs {
|
||||||
GroundValueType type;
|
GroundValueType type;
|
||||||
|
struct GroundStruct* customType;
|
||||||
char* name;
|
char* name;
|
||||||
} GroundFunctionArgs;
|
} GroundFunctionArgs;
|
||||||
|
|
||||||
@@ -276,6 +278,11 @@ void freeGroundObject(GroundObject* object);
|
|||||||
// Creates a GroundError.
|
// Creates a GroundError.
|
||||||
GroundError createGroundError(char* what, char* type, GroundInstruction* where, size_t* line);
|
GroundError createGroundError(char* what, char* type, GroundInstruction* where, size_t* line);
|
||||||
|
|
||||||
|
// Compares types of a value and function args.
|
||||||
|
bool checkFnTypes(GroundValue* left, GroundFunctionArgs* arg);
|
||||||
|
|
||||||
|
// Compares types of two values.
|
||||||
|
bool checkTypes(GroundValue* left, GroundValue* right);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
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