Add catch support

This commit is contained in:
2026-04-15 10:37:14 +10:00
parent ca85550c92
commit e4b5aafe35
4 changed files with 36 additions and 13 deletions

View File

@@ -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*)&currentInstruction (size_t*)&currentInstruction
) )
@@ -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;

View File

@@ -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);

View File

@@ -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
View 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