forked from ground/ground
Add catch support
This commit is contained in:
@@ -758,7 +758,18 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) {
|
|||||||
instructionsToPause --;
|
instructionsToPause --;
|
||||||
int ci = currentInstruction;
|
int ci = currentInstruction;
|
||||||
GroundValue gv = interpretGroundInstruction(in->instructions[i], &scope);
|
GroundValue gv = interpretGroundInstruction(in->instructions[i], &scope);
|
||||||
if (gv.type != NONE) {
|
if (gv.type == ERROR) {
|
||||||
|
GroundCatch* catch = findCatch(*scope.catches, gv.data.errorVal.type);
|
||||||
|
if (catch != NULL) {
|
||||||
|
currentInstruction = catch->label->lineNum;
|
||||||
|
} else {
|
||||||
|
if (scope.isMainScope) {
|
||||||
|
throwError(&gv.data.errorVal);
|
||||||
|
} else {
|
||||||
|
return gv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (gv.type != NONE) {
|
||||||
return gv;
|
return gv;
|
||||||
}
|
}
|
||||||
if (ci != currentInstruction) {
|
if (ci != currentInstruction) {
|
||||||
@@ -1964,16 +1975,6 @@ 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) {
|
|
||||||
throwError(&returnValue.data.errorVal);
|
|
||||||
}
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
if (returnValue.type != ANY && returnValue.type != function->returnType) {
|
if (returnValue.type != ANY && returnValue.type != function->returnType) {
|
||||||
@@ -2451,8 +2452,8 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
|||||||
|
|
||||||
return createErrorGroundValue(
|
return createErrorGroundValue(
|
||||||
createGroundError(
|
createGroundError(
|
||||||
in->args.args[0].value.value.data.stringVal,
|
|
||||||
in->args.args[1].value.value.data.stringVal,
|
in->args.args[1].value.value.data.stringVal,
|
||||||
|
in->args.args[0].value.value.data.stringVal,
|
||||||
in,
|
in,
|
||||||
(size_t*)¤tInstruction
|
(size_t*)¤tInstruction
|
||||||
)
|
)
|
||||||
@@ -2478,8 +2479,9 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
|
|||||||
}
|
}
|
||||||
|
|
||||||
GroundCatch catch = {
|
GroundCatch catch = {
|
||||||
.label = label
|
.label = label,
|
||||||
};
|
};
|
||||||
|
snprintf(catch.id, sizeof(catch.id), "%s", in->args.args[0].value.value.data.stringVal);
|
||||||
|
|
||||||
HASH_ADD_STR(*scope->catches, id, &catch);
|
HASH_ADD_STR(*scope->catches, id, &catch);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -121,10 +121,12 @@ int main(int argc, char** argv) {
|
|||||||
} else {
|
} else {
|
||||||
GroundVariable* variables = NULL;
|
GroundVariable* variables = NULL;
|
||||||
GroundLabel* labels = NULL;
|
GroundLabel* labels = NULL;
|
||||||
|
GroundCatch* catches = NULL;
|
||||||
|
|
||||||
GroundScope scope;
|
GroundScope scope;
|
||||||
scope.variables = &variables;
|
scope.variables = &variables;
|
||||||
scope.labels = &labels;
|
scope.labels = &labels;
|
||||||
|
scope.catches = &catches;
|
||||||
scope.isMainScope = true;
|
scope.isMainScope = true;
|
||||||
addVariable(scope.variables, "CMDLINE_ARGS", createListGroundValue(groundArgs));
|
addVariable(scope.variables, "CMDLINE_ARGS", createListGroundValue(groundArgs));
|
||||||
interpretGroundProgram(&program, &scope);
|
interpretGroundProgram(&program, &scope);
|
||||||
|
|||||||
@@ -579,6 +579,12 @@ void printGroundInstruction(GroundInstruction* gi) {
|
|||||||
case LICENSE:
|
case LICENSE:
|
||||||
printf("license");
|
printf("license");
|
||||||
break;
|
break;
|
||||||
|
case THROW:
|
||||||
|
printf("throw");
|
||||||
|
break;
|
||||||
|
case CATCH:
|
||||||
|
printf("catch");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (gi->type != CREATELABEL) printf(" ");
|
if (gi->type != CREATELABEL) printf(" ");
|
||||||
for (size_t i = 0; i < gi->args.length; i++) {
|
for (size_t i = 0; i < gi->args.length; i++) {
|
||||||
|
|||||||
13
tests/catch.grnd
Normal file
13
tests/catch.grnd
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
fun !throws -int
|
||||||
|
throw "MyError" "longer error message"
|
||||||
|
endfun
|
||||||
|
|
||||||
|
catch "MyError" %catcher
|
||||||
|
|
||||||
|
call !throws &res
|
||||||
|
|
||||||
|
end 0
|
||||||
|
|
||||||
|
@catcher
|
||||||
|
println "ruh roh"
|
||||||
|
end 1
|
||||||
Reference in New Issue
Block a user