forked from ground/ground
Start work on throw and catch
This commit is contained in:
@@ -16,7 +16,10 @@
|
|||||||
|
|
||||||
|
|
||||||
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, AND, OR, XOR, NEG, SHIFT, STOI, STOD, ITOC, CTOI, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, CALLMETHOD, STRUCT, ENDSTRUCT, INIT, GETFIELD, SETFIELD, USE, EXTERN, CREATELABEL, PAUSE, DROP, LICENSE, ERRORCMD
|
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, AND, OR, XOR, NEG,
|
||||||
|
SHIFT, STOI, STOD, ITOC, CTOI, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, CALLMETHOD, STRUCT, ENDSTRUCT, INIT,
|
||||||
|
GETFIELD, SETFIELD, USE, EXTERN, CREATELABEL, PAUSE, DROP, LICENSE, ERRORCMD, THROW, CATCH
|
||||||
} GroundInstType;
|
} GroundInstType;
|
||||||
|
|
||||||
typedef enum GroundValueType {
|
typedef enum GroundValueType {
|
||||||
|
|||||||
@@ -125,6 +125,12 @@ GroundLabel* findLabel(GroundLabel* head, const char *id) {
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GroundCatch* findCatch(GroundCatch* head, const char *id) {
|
||||||
|
GroundCatch *item;
|
||||||
|
HASH_FIND_STR(head, id, item);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
void deleteLabel(GroundLabel** head, GroundLabel *item) {
|
void deleteLabel(GroundLabel** head, GroundLabel *item) {
|
||||||
HASH_DEL(*head, item);
|
HASH_DEL(*head, item);
|
||||||
free(item);
|
free(item);
|
||||||
@@ -165,6 +171,7 @@ void deleteVariable(GroundVariable** head, GroundVariable *item) {
|
|||||||
GroundScope scope = {
|
GroundScope scope = {
|
||||||
.labels = NULL,
|
.labels = NULL,
|
||||||
.variables = malloc(sizeof(GroundVariable*)),
|
.variables = malloc(sizeof(GroundVariable*)),
|
||||||
|
.catches = malloc(sizeof(GroundCatch*)),
|
||||||
.isMainScope = false
|
.isMainScope = false
|
||||||
};
|
};
|
||||||
if (scope.variables == NULL) {
|
if (scope.variables == NULL) {
|
||||||
@@ -517,6 +524,7 @@ GroundStruct parseStruct(GroundProgram* in, GroundScope* scope, size_t errorOffs
|
|||||||
GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
|
GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
|
||||||
GroundLabel* labels = NULL;
|
GroundLabel* labels = NULL;
|
||||||
GroundVariable* variables = NULL;
|
GroundVariable* variables = NULL;
|
||||||
|
GroundCatch* catches = NULL;
|
||||||
int instructionsToPause = -1;
|
int instructionsToPause = -1;
|
||||||
|
|
||||||
GroundScope scope;
|
GroundScope scope;
|
||||||
@@ -525,6 +533,7 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
|
|||||||
} else {
|
} else {
|
||||||
scope.labels = &labels;
|
scope.labels = &labels;
|
||||||
scope.variables = &variables;
|
scope.variables = &variables;
|
||||||
|
scope.catches = &catches;
|
||||||
}
|
}
|
||||||
scope.isMainScope = isMainScopeGlobal;
|
scope.isMainScope = isMainScopeGlobal;
|
||||||
isMainScopeGlobal = false;
|
isMainScopeGlobal = false;
|
||||||
@@ -1955,6 +1964,13 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
|||||||
returnValue.data.errorVal.line = currentInstruction;
|
returnValue.data.errorVal.line = currentInstruction;
|
||||||
returnValue.data.errorVal.hasLine = true;
|
returnValue.data.errorVal.hasLine = true;
|
||||||
returnValue.data.errorVal.where = in;
|
returnValue.data.errorVal.where = in;
|
||||||
|
|
||||||
|
GroundCatch* catch = findCatch(*scope->catches, returnValue.data.errorVal.type);
|
||||||
|
if (catch != NULL) {
|
||||||
|
// Jump to label where catch points to
|
||||||
|
currentInstruction = catch->label->lineNum;
|
||||||
|
}
|
||||||
|
|
||||||
if (scope->isMainScope) {
|
if (scope->isMainScope) {
|
||||||
throwError(&returnValue.data.errorVal);
|
throwError(&returnValue.data.errorVal);
|
||||||
}
|
}
|
||||||
@@ -2418,6 +2434,57 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case THROW: {
|
||||||
|
if (in->args.length < 2) {
|
||||||
|
runtimeError(TOO_FEW_ARGS, "Expecting 2 args", in, currentInstruction);
|
||||||
|
}
|
||||||
|
if (in->args.length > 2) {
|
||||||
|
runtimeError(TOO_MANY_ARGS, "Expecting 2 args", in, currentInstruction);
|
||||||
|
}
|
||||||
|
if (in->args.args[0].type != VALUE || in->args.args[0].value.value.type != STRING) {
|
||||||
|
runtimeError(ARG_TYPE_MISMATCH, "Expecting a String value for arg 1", in, currentInstruction);
|
||||||
|
}
|
||||||
|
if (in->args.args[1].type != VALUE || in->args.args[1].value.value.type != STRING) {
|
||||||
|
runtimeError(ARG_TYPE_MISMATCH, "Expecting a String value for arg 2", in, currentInstruction);
|
||||||
|
}
|
||||||
|
|
||||||
|
return createErrorGroundValue(
|
||||||
|
createGroundError(
|
||||||
|
in->args.args[0].value.value.data.stringVal,
|
||||||
|
in->args.args[1].value.value.data.stringVal,
|
||||||
|
in,
|
||||||
|
(size_t*)¤tInstruction
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
case CATCH: {
|
||||||
|
if (in->args.length < 2) {
|
||||||
|
runtimeError(TOO_FEW_ARGS, "Expecting 2 args", in, currentInstruction);
|
||||||
|
}
|
||||||
|
if (in->args.length > 2) {
|
||||||
|
runtimeError(TOO_MANY_ARGS, "Expecting 2 args", in, currentInstruction);
|
||||||
|
}
|
||||||
|
if (in->args.args[0].type != VALUE || in->args.args[0].value.value.type != STRING) {
|
||||||
|
runtimeError(ARG_TYPE_MISMATCH, "Expecting a String value for arg 1", in, currentInstruction);
|
||||||
|
}
|
||||||
|
if (in->args.args[1].type != LINEREF) {
|
||||||
|
runtimeError(ARG_TYPE_MISMATCH, "Expecting a LineRef for arg 2", in, currentInstruction);
|
||||||
|
}
|
||||||
|
|
||||||
|
GroundLabel* label = findLabel(*scope->labels, in->args.args[1].value.refName);
|
||||||
|
if (label == NULL) {
|
||||||
|
runtimeError(UNKNOWN_LABEL, NULL, in, currentInstruction);
|
||||||
|
}
|
||||||
|
|
||||||
|
GroundCatch catch = {
|
||||||
|
.label = label
|
||||||
|
};
|
||||||
|
|
||||||
|
HASH_ADD_STR(*scope->catches, id, &catch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* License for REPL
|
* License for REPL
|
||||||
*/
|
*/
|
||||||
@@ -2427,6 +2494,7 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
runtimeError(FIXME, "Currently unimplemented instruction", in, currentInstruction);
|
runtimeError(FIXME, "Currently unimplemented instruction", in, currentInstruction);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -204,6 +204,8 @@ static GroundInstType getInstructionType(const char* inst) {
|
|||||||
if (strcmp(inst, "extern") == 0) return EXTERN;
|
if (strcmp(inst, "extern") == 0) return EXTERN;
|
||||||
if (strcmp(inst, "drop") == 0) return DROP;
|
if (strcmp(inst, "drop") == 0) return DROP;
|
||||||
if (strcmp(inst, "license") == 0) return LICENSE;
|
if (strcmp(inst, "license") == 0) return LICENSE;
|
||||||
|
if (strcmp(inst, "throw") == 0) return THROW;
|
||||||
|
if (strcmp(inst, "catch") == 0) return CATCH;
|
||||||
if (strcmp(inst, "PAUSE") == 0) return PAUSE;
|
if (strcmp(inst, "PAUSE") == 0) return PAUSE;
|
||||||
|
|
||||||
fprintf(stderr, "Error: Unknown instruction: %s\n", inst);
|
fprintf(stderr, "Error: Unknown instruction: %s\n", inst);
|
||||||
|
|||||||
@@ -794,10 +794,12 @@ GroundScope copyGroundScope(GroundScope* scope) {
|
|||||||
GroundScope newScope = {
|
GroundScope newScope = {
|
||||||
.labels = malloc(sizeof(GroundLabel*)),
|
.labels = malloc(sizeof(GroundLabel*)),
|
||||||
.variables = malloc(sizeof(GroundVariable*)),
|
.variables = malloc(sizeof(GroundVariable*)),
|
||||||
|
.catches = malloc(sizeof(GroundCatch*)),
|
||||||
.isMainScope = false
|
.isMainScope = false
|
||||||
};
|
};
|
||||||
*newScope.variables = NULL;
|
*newScope.variables = NULL;
|
||||||
*newScope.labels = NULL;
|
*newScope.labels = NULL;
|
||||||
|
*newScope.catches = NULL;
|
||||||
|
|
||||||
if (scope == NULL) {
|
if (scope == NULL) {
|
||||||
printf("oh no scope is null\n");
|
printf("oh no scope is null\n");
|
||||||
|
|||||||
12
src/types.h
12
src/types.h
@@ -29,7 +29,10 @@ void wasm_print(const char* str);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
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, AND, OR, XOR, NEG, SHIFT, STOI, STOD, ITOC, CTOI, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, CALLMETHOD, STRUCT, ENDSTRUCT, INIT, GETFIELD, SETFIELD, USE, EXTERN, CREATELABEL, PAUSE, DROP, LICENSE, ERRORCMD
|
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, AND, OR, XOR, NEG,
|
||||||
|
SHIFT, STOI, STOD, ITOC, CTOI, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, CALLMETHOD, STRUCT, ENDSTRUCT, INIT,
|
||||||
|
GETFIELD, SETFIELD, USE, EXTERN, CREATELABEL, PAUSE, DROP, LICENSE, ERRORCMD, THROW, CATCH
|
||||||
} GroundInstType;
|
} GroundInstType;
|
||||||
|
|
||||||
typedef enum GroundValueType {
|
typedef enum GroundValueType {
|
||||||
@@ -110,9 +113,16 @@ typedef struct GroundVariable {
|
|||||||
bool freed;
|
bool freed;
|
||||||
} GroundVariable;
|
} GroundVariable;
|
||||||
|
|
||||||
|
typedef struct GroundCatch {
|
||||||
|
char id[MAX_ID_LEN];
|
||||||
|
GroundLabel* label;
|
||||||
|
UT_hash_handle hh;
|
||||||
|
} GroundCatch;
|
||||||
|
|
||||||
typedef struct GroundScope {
|
typedef struct GroundScope {
|
||||||
GroundLabel** labels;
|
GroundLabel** labels;
|
||||||
GroundVariable** variables;
|
GroundVariable** variables;
|
||||||
|
GroundCatch** catches;
|
||||||
bool isMainScope;
|
bool isMainScope;
|
||||||
} GroundScope;
|
} GroundScope;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user