From c4ebca9ed9c2f76d9fd65132ce2c0501282344de Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Sun, 21 Sep 2025 14:10:09 +1000 Subject: [PATCH] Catching errors across scopes --- src/main.cpp | 22 ++++++++++++++++++++++ tests/error.grnd | 24 +++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 391c8f5..0cd6c0c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -279,6 +279,7 @@ struct Struct { struct Error { string code; int pops; + string reporter; }; /* @@ -413,6 +414,7 @@ Literal error(string in, string errCode = "syntaxError", int exitc = 1) { Literal tmpLit; tmpLit.val = false; setVal(catches.top()[errCode].varName, tmpLit); + retError.reporter = catches.top()[errCode].varName; Literal tmpLit2; tmpLit2.val = retError; return tmpLit2; @@ -2383,6 +2385,19 @@ Literal exec(vector in, bool executingFunction) { // Call the function Literal retVal = exec(fnToExec.instructions, true); + string errPreserveValue; + + if (holds_alternative(retVal.val)) { + Error err = get(retVal.val); + if (err.pops > 1) { + err.pops --; + Literal tmpLit; + tmpLit.val = err; + return tmpLit; + } + errPreserveValue = err.reporter; + } + // If we were executing a function in a struct, add back values if (inStruct) { for (auto &[key, value] : structVal.values) { @@ -2394,6 +2409,13 @@ Literal exec(vector in, bool executingFunction) { variables = scopeBackup; labelStack.pop(); + // Add back the false for any errors + if (!errPreserveValue.empty()) { + Literal errLit; + errLit.val = false; + setVal(errPreserveValue, errLit); + } + // Add back the struct values variables[structName].val = structVal; diff --git a/tests/error.grnd b/tests/error.grnd index 726464d..1534b4c 100644 --- a/tests/error.grnd +++ b/tests/error.grnd @@ -1 +1,23 @@ -error "Hello, world!" "sillyError" +fun -int !divten -int &divisor + divide 10 $divisor &out + # Skip the rest of the function because we have an error + println "aw yeag we devided by zero" + return $out +endfun + +fun -string !wrapperFn -int &dingle + pusharg $dingle + !divten &result + # Skip the rest of the function because we have an error + println "big error incoming" + tostring $result &out + return $out +endfun + +catch "divisionByZeroError" &success +pusharg 0 +!wrapperFn &result + +# There's a catch in this scope, stop here and continue execution + +println $success