forked from ground/ground
Start work on throw and catch
This commit is contained in:
@@ -16,7 +16,10 @@
|
||||
|
||||
|
||||
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;
|
||||
|
||||
typedef enum GroundValueType {
|
||||
|
||||
@@ -125,6 +125,12 @@ GroundLabel* findLabel(GroundLabel* head, const char *id) {
|
||||
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) {
|
||||
HASH_DEL(*head, item);
|
||||
free(item);
|
||||
@@ -165,6 +171,7 @@ void deleteVariable(GroundVariable** head, GroundVariable *item) {
|
||||
GroundScope scope = {
|
||||
.labels = NULL,
|
||||
.variables = malloc(sizeof(GroundVariable*)),
|
||||
.catches = malloc(sizeof(GroundCatch*)),
|
||||
.isMainScope = false
|
||||
};
|
||||
if (scope.variables == NULL) {
|
||||
@@ -517,6 +524,7 @@ GroundStruct parseStruct(GroundProgram* in, GroundScope* scope, size_t errorOffs
|
||||
GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
|
||||
GroundLabel* labels = NULL;
|
||||
GroundVariable* variables = NULL;
|
||||
GroundCatch* catches = NULL;
|
||||
int instructionsToPause = -1;
|
||||
|
||||
GroundScope scope;
|
||||
@@ -525,6 +533,7 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
|
||||
} else {
|
||||
scope.labels = &labels;
|
||||
scope.variables = &variables;
|
||||
scope.catches = &catches;
|
||||
}
|
||||
scope.isMainScope = isMainScopeGlobal;
|
||||
isMainScopeGlobal = false;
|
||||
@@ -1955,6 +1964,13 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
||||
returnValue.data.errorVal.line = currentInstruction;
|
||||
returnValue.data.errorVal.hasLine = true;
|
||||
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) {
|
||||
throwError(&returnValue.data.errorVal);
|
||||
}
|
||||
@@ -2418,6 +2434,57 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
||||
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
|
||||
*/
|
||||
@@ -2427,6 +2494,7 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default: {
|
||||
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, "drop") == 0) return DROP;
|
||||
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;
|
||||
|
||||
fprintf(stderr, "Error: Unknown instruction: %s\n", inst);
|
||||
|
||||
@@ -794,10 +794,12 @@ GroundScope copyGroundScope(GroundScope* scope) {
|
||||
GroundScope newScope = {
|
||||
.labels = malloc(sizeof(GroundLabel*)),
|
||||
.variables = malloc(sizeof(GroundVariable*)),
|
||||
.catches = malloc(sizeof(GroundCatch*)),
|
||||
.isMainScope = false
|
||||
};
|
||||
*newScope.variables = NULL;
|
||||
*newScope.labels = NULL;
|
||||
*newScope.catches = NULL;
|
||||
|
||||
if (scope == NULL) {
|
||||
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
|
||||
|
||||
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;
|
||||
|
||||
typedef enum GroundValueType {
|
||||
@@ -110,9 +113,16 @@ typedef struct GroundVariable {
|
||||
bool freed;
|
||||
} GroundVariable;
|
||||
|
||||
typedef struct GroundCatch {
|
||||
char id[MAX_ID_LEN];
|
||||
GroundLabel* label;
|
||||
UT_hash_handle hh;
|
||||
} GroundCatch;
|
||||
|
||||
typedef struct GroundScope {
|
||||
GroundLabel** labels;
|
||||
GroundVariable** variables;
|
||||
GroundCatch** catches;
|
||||
bool isMainScope;
|
||||
} GroundScope;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user