From e4b5aafe353f36978526a37a570f9bf90af41936 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Wed, 15 Apr 2026 10:37:14 +1000 Subject: [PATCH] Add catch support --- src/interpreter.c | 28 +++++++++++++++------------- src/main.c | 2 ++ src/types.c | 6 ++++++ tests/catch.grnd | 13 +++++++++++++ 4 files changed, 36 insertions(+), 13 deletions(-) create mode 100644 tests/catch.grnd diff --git a/src/interpreter.c b/src/interpreter.c index 183719f..63e250c 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -758,7 +758,18 @@ GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope) { instructionsToPause --; int ci = currentInstruction; 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; } if (ci != currentInstruction) { @@ -1964,16 +1975,6 @@ 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); - } return returnValue; } if (returnValue.type != ANY && returnValue.type != function->returnType) { @@ -2451,8 +2452,8 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop return createErrorGroundValue( createGroundError( - in->args.args[0].value.value.data.stringVal, in->args.args[1].value.value.data.stringVal, + in->args.args[0].value.value.data.stringVal, in, (size_t*)¤tInstruction ) @@ -2478,8 +2479,9 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop } 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); break; diff --git a/src/main.c b/src/main.c index 1993d33..2d2a4b0 100644 --- a/src/main.c +++ b/src/main.c @@ -121,10 +121,12 @@ int main(int argc, char** argv) { } else { GroundVariable* variables = NULL; GroundLabel* labels = NULL; + GroundCatch* catches = NULL; GroundScope scope; scope.variables = &variables; scope.labels = &labels; + scope.catches = &catches; scope.isMainScope = true; addVariable(scope.variables, "CMDLINE_ARGS", createListGroundValue(groundArgs)); interpretGroundProgram(&program, &scope); diff --git a/src/types.c b/src/types.c index d87fb0d..c26c1e3 100644 --- a/src/types.c +++ b/src/types.c @@ -579,6 +579,12 @@ void printGroundInstruction(GroundInstruction* gi) { case LICENSE: printf("license"); break; + case THROW: + printf("throw"); + break; + case CATCH: + printf("catch"); + break; } if (gi->type != CREATELABEL) printf(" "); for (size_t i = 0; i < gi->args.length; i++) { diff --git a/tests/catch.grnd b/tests/catch.grnd new file mode 100644 index 0000000..34fe50f --- /dev/null +++ b/tests/catch.grnd @@ -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 \ No newline at end of file