From bfbcd376dffb2ec1228a87546c116498015b03e1 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Sun, 21 Sep 2025 13:47:43 +1000 Subject: [PATCH] Returning errors --- src/main.cpp | 410 ++++++++++++++++++++++++++------------------------- 1 file changed, 209 insertions(+), 201 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 9d77ed3..391c8f5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -276,6 +276,11 @@ struct Struct { map functions; }; +struct Error { + string code; + int pops; +}; + /* Literal struct Contains literal values. For example, if the following line was written: @@ -289,7 +294,7 @@ struct Struct { point to. See also variables map, parser function, interpreter function */ struct Literal { - variant val; + variant val; }; // C-compatible enum and types for developing libraries for Ground in C @@ -399,22 +404,25 @@ void setVal(string varName, Literal value); Takes a string (which is a debug message) and prints it to the console, letting the user know what went wrong with the program. */ -int error(string in, string errCode = "syntaxError", int exitc = 1) { - int pops = 0; +Literal error(string in, string errCode = "syntaxError", int exitc = 1) { + Error retError; + retError.code = errCode; + retError.pops = 0; while (catches.size() > 0) { if (catches.top().find(errCode) != catches.top().end()) { Literal tmpLit; tmpLit.val = false; setVal(catches.top()[errCode].varName, tmpLit); - return pops; + Literal tmpLit2; + tmpLit2.val = retError; + return tmpLit2; } else { catches.pop(); - pops ++; + retError.pops ++; } } cout << "\033[31m" + errCode + ": \033[39m" << in << endl; exit(exitc); - return pops; } /* @@ -637,14 +645,14 @@ Literal exec(vector in, bool executingFunction) { continue; } else if (l.inst == Instructions::Fun) { if (l.args.size() < 2) { - error("Could not find all arguments required for Fun inbuilt"); + return error("Could not find all arguments required for Fun inbuilt"); } Function newFunction; if (holds_alternative(l.args[0])) { newFunction.returnType = get(l.args[0]).type; } else { - error("First argument of function must be a type reference"); + return error("First argument of function must be a type reference"); } string fnName; @@ -652,7 +660,7 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[1])) { fnName = get(l.args[1]).fnName; } else { - error("Second argument of function must be a function reference"); + return error("Second argument of function must be a function reference"); } if (importing.size() > 0) { @@ -661,7 +669,7 @@ Literal exec(vector in, bool executingFunction) { // Parse function arguments (type-direct pairs) if ((l.args.size() - 2) % 2 != 0) { - error("Function arguments must be in type-direct pairs"); + return error("Function arguments must be in type-direct pairs"); } for (int m = 2; m < l.args.size(); m += 2) { @@ -671,14 +679,14 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[m])) { newArg.type = get(l.args[m]).type; } else { - error("Expected type reference in function argument definition"); + return error("Expected type reference in function argument definition"); } // Get direct reference if (m + 1 < l.args.size() && holds_alternative(l.args[m + 1])) { newArg.ref = get(l.args[m + 1]); } else { - error("Expected direct reference after type reference in function argument definition"); + return error("Expected direct reference after type reference in function argument definition"); } newFunction.args.push_back(newArg); @@ -689,7 +697,7 @@ Literal exec(vector in, bool executingFunction) { procFnName = fnName; } else if (l.inst == Instructions::Init) { if (l.args.size() < 2) { - error("Could not find all arguments required for Init inbuilt"); + return error("Could not find all arguments required for Init inbuilt"); } Direct varRef; @@ -697,12 +705,12 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { varRef = get(l.args[0]); } else { - error("First argument of init must be a direct reference"); + return error("First argument of init must be a direct reference"); } if (holds_alternative(l.args[1])) { type = get(l.args[1]); } else { - error("Second argument of init must be a type reference"); + return error("Second argument of init must be a type reference"); } Literal newVal; @@ -726,7 +734,7 @@ Literal exec(vector in, bool executingFunction) { newVal.val = false; break; default: - error("You dingus you werent supposed to get here"); + return error("You dingus you werent supposed to get here"); } } structs[procStructName].values[varRef.varName] = newVal; @@ -756,19 +764,19 @@ Literal exec(vector in, bool executingFunction) { if (structVal.values.find(varInStruct) != structVal.values.end()) { l.args[j] = structVal.values[varInStruct]; } else { - error("Could not find property '" + varInStruct + "' in struct '" + structName + "'"); + return error("Could not find property '" + varInStruct + "' in struct '" + structName + "'"); } } else { - error("Variable '" + structName + "' is not a struct"); + return error("Variable '" + structName + "' is not a struct"); } } else { - error("Could not find struct '" + structName + "'"); + return error("Could not find struct '" + structName + "'"); } } else { - error("Invalid struct member access syntax"); + return error("Invalid struct member access syntax"); } } else { - error("Could not find variable " + varName); + return error("Could not find variable " + varName); } } } else if (holds_alternative(l.args[j])) { @@ -779,7 +787,7 @@ Literal exec(vector in, bool executingFunction) { newLine.lineNum = labelStack.top()[ln.label]; l.args[j] = newLine; } else { - if (l.inst != Instructions::Exists) error("Could not find label " + ln.label); + if (l.inst != Instructions::Exists) return error("Could not find label " + ln.label); } } } @@ -795,7 +803,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Stdout: if (l.args.size() < 1) { - error("Could not find argument for Stdout inbuilt"); + return error("Could not find argument for Stdout inbuilt"); } if (holds_alternative(l.args[0])) { if (holds_alternative(get(l.args[0]).val)) { @@ -818,7 +826,7 @@ Literal exec(vector in, bool executingFunction) { cout << get(get(l.args[0]).val); } else { - error("Couldn't print that", "printError"); + return error("Couldn't print that", "printError"); } } else if (holds_alternative(l.args[0])) { if (variables.find(get(l.args[0]).listName) != variables.end()) { @@ -845,7 +853,7 @@ Literal exec(vector in, bool executingFunction) { cout << '\'' << get(list.val[l].val) << '\''; } else { - error("Couldn't print that", "printError"); + return error("Couldn't print that", "printError"); } if (l != list.val.size() - 1) { cout << ", "; @@ -853,10 +861,10 @@ Literal exec(vector in, bool executingFunction) { } cout << "]"; } else { - error("Couldn't find list named " + get(l.args[0]).listName); + return error("Couldn't find list named " + get(l.args[0]).listName); } } else { - error("Argument of stdlnout must be a value (literal or a value reference)"); + return error("Argument of stdlnout must be a value (literal or a value reference)"); } break; /* @@ -866,7 +874,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Stdlnout: if (l.args.size() < 1) { - error("Could not find argument for Stdout inbuilt"); + return error("Could not find argument for Stdout inbuilt"); } if (holds_alternative(l.args[0])) { if (holds_alternative(get(l.args[0]).val)) { @@ -889,7 +897,7 @@ Literal exec(vector in, bool executingFunction) { cout << get(get(l.args[0]).val) << endl; } else { - error("Couldn't print that", "printError"); + return error("Couldn't print that", "printError"); } } else if (holds_alternative(l.args[0])) { if (variables.find(get(l.args[0]).listName) != variables.end()) { @@ -916,7 +924,7 @@ Literal exec(vector in, bool executingFunction) { cout << '\'' << get(list.val[l].val) << '\''; } else { - error("Couldn't print that", "printError"); + return error("Couldn't print that", "printError"); } if (l != list.val.size() - 1) { cout << ", "; @@ -924,10 +932,10 @@ Literal exec(vector in, bool executingFunction) { } cout << "]" << endl; } else { - error("Couldn't find list named " + get(l.args[0]).listName); + return error("Couldn't find list named " + get(l.args[0]).listName); } } else { - error("Argument of stdlnout must be a value (literal or a value reference) or a list reference"); + return error("Argument of stdlnout must be a value (literal or a value reference) or a list reference"); } break; /* @@ -936,16 +944,16 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Error: if (l.args.size() < 2) { - error("Could not find arguments for Error inbuilt"); + return error("Could not find arguments for Error inbuilt"); } if (holds_alternative(l.args[0])) { if (holds_alternative(get(l.args[0]).val) && holds_alternative(get(l.args[1]).val)) { - error(get(get(l.args[0]).val), get(get(l.args[1]).val)); + return error(get(get(l.args[0]).val), get(get(l.args[1]).val)); } else { - error("Argument of error must be a string"); + return error("Argument of error must be a string"); } } else { - error("Argument of error must be a string"); + return error("Argument of error must be a string"); } break; /* @@ -954,7 +962,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Catch: if (l.args.size() < 2) { - error("Could not find all arguments for Catch inbuilt"); + return error("Could not find all arguments for Catch inbuilt"); } { @@ -965,16 +973,16 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(get(l.args[0]).val)) { errCode = get(get(l.args[0]).val); } else { - error("First argument of catch must be a string literal"); + return error("First argument of catch must be a string literal"); } } else { - error("First argument of catch must be a string literal"); + return error("First argument of catch must be a string literal"); } if (holds_alternative(l.args[1])) { varRef = get(l.args[1]); } else { - error("Second argument of catch must be a direct reference"); + return error("Second argument of catch must be a direct reference"); } catches.top()[errCode] = varRef; @@ -989,7 +997,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Set: if (l.args.size() < 2) { - error("Could not find all arguments required for Set inbuilt"); + return error("Could not find all arguments required for Set inbuilt"); } { Direct varRef; @@ -998,13 +1006,13 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { varRef = get(l.args[0]); } else { - error("First argument of set must be a direct reference"); + return error("First argument of set must be a direct reference"); } if (holds_alternative(l.args[1])) { varContents = get(l.args[1]); } else { - error("Second argument of set must be a value (literal or value reference)"); + return error("Second argument of set must be a value (literal or value reference)"); } bool existed = variables.count(varRef.varName) > 0; @@ -1013,7 +1021,7 @@ Literal exec(vector in, bool executingFunction) { break; case Instructions::Init: if (l.args.size() < 2) { - error("Could not find all arguments required for Init inbuilt"); + return error("Could not find all arguments required for Init inbuilt"); } { Direct varRef; @@ -1021,18 +1029,18 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { varRef = get(l.args[0]); } else { - error("First argument of init must be a direct reference"); + return error("First argument of init must be a direct reference"); } if (holds_alternative(l.args[1])) { type = get(l.args[1]); } else { - error("Second argument of init must be a type reference"); + return error("Second argument of init must be a type reference"); } Literal newVal; if (type.isCustomType) { if (structs.find(type.customType) == structs.end()) { - error("Unknown struct type: " + type.customType); + return error("Unknown struct type: " + type.customType); } Struct newStructInstance = structs[type.customType]; @@ -1055,7 +1063,7 @@ Literal exec(vector in, bool executingFunction) { newVal.val = false; break; default: - error("You dingus you werent supposed to get here"); + return error("You dingus you werent supposed to get here"); } } variables[varRef.varName] = newVal; @@ -1068,7 +1076,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Setlist: if (l.args.size() < 1) { - error("Could not find all arguments required for Setlist inbuilt"); + return error("Could not find all arguments required for Setlist inbuilt"); } { string listName; @@ -1077,7 +1085,7 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { listName = get(l.args[0]).listName; } else { - error("First argument of setlist must be a list reference"); + return error("First argument of setlist must be a list reference"); } bool first = true; @@ -1085,7 +1093,7 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(k)) { listContents.val.push_back(get(k)); } else { - if (!first) error("All arguments after first in setlist must be values"); + if (!first) return error("All arguments after first in setlist must be values"); first = false; } } @@ -1101,7 +1109,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Getlistat: if (l.args.size() < 3) { - error("Could not find all arguments required for Getlistat inbuilt"); + return error("Could not find all arguments required for Getlistat inbuilt"); } { ListRef listref; @@ -1111,23 +1119,23 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { listref = get(l.args[0]); } else { - error("First argument of getlistat must be a list reference"); + return error("First argument of getlistat must be a list reference"); } if (holds_alternative(l.args[1])) { if (holds_alternative(get(l.args[1]).val)) { ref = get(get(l.args[1]).val); } else { - error("Second argument of getlistat must be an integer literal"); + return error("Second argument of getlistat must be an integer literal"); } } else { - error("Second argument of getlistat must be an integer literal"); + return error("Second argument of getlistat must be an integer literal"); } if (holds_alternative(l.args[2])) { var = get(l.args[2]); } else { - error("Third argument of getlistat must be a direct reference"); + return error("Third argument of getlistat must be a direct reference"); } if (variables.find(listref.listName) != variables.end()) { @@ -1136,13 +1144,13 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(var.varName) > 0; setVal(var.varName, get(variables[listref.listName].val).val[ref]); } else { - error("Index " + to_string(ref) + " out of range of list " + listref.listName, "rangeError"); + return error("Index " + to_string(ref) + " out of range of list " + listref.listName, "rangeError"); } } else { - error("Found a normal variable in place of a list"); + return error("Found a normal variable in place of a list"); } } else { - error("Unknown list: " + listref.listName); + return error("Unknown list: " + listref.listName); } } break; @@ -1153,7 +1161,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Getstrcharat: if (l.args.size() < 3) { - error("Could not find all arguments required for Getstrcharat inbuilt"); + return error("Could not find all arguments required for Getstrcharat inbuilt"); } { string instr; @@ -1164,26 +1172,26 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(get(l.args[0]).val)) { instr = get(get(l.args[0]).val); } else { - error("First argument of getstrcharat must be a string literal"); + return error("First argument of getstrcharat must be a string literal"); } } else { - error("First argument of getstrcharat must be a string literal"); + return error("First argument of getstrcharat must be a string literal"); } if (holds_alternative(l.args[1])) { if (holds_alternative(get(l.args[1]).val)) { ref = get(get(l.args[1]).val); } else { - error("Second argument of getstrcharat must be an integer literal"); + return error("Second argument of getstrcharat must be an integer literal"); } } else { - error("Second argument of getstrcharat must be an integer literal"); + return error("Second argument of getstrcharat must be an integer literal"); } if (holds_alternative(l.args[2])) { var = get(l.args[2]); } else { - error("Third argument of getstrcharat must be a direct reference"); + return error("Third argument of getstrcharat must be a direct reference"); } if (instr.size() > ref) { @@ -1192,7 +1200,7 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(var.varName) > 0; setVal(var.varName, newLit); } else { - error("Index " + to_string(ref) + " out of range of string " + instr, "rangeError"); + return error("Index " + to_string(ref) + " out of range of string " + instr, "rangeError"); } } break; @@ -1202,7 +1210,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Setlistat: if (l.args.size() < 3) { - error("Could not find all arguments required for Setlistat inbuilt"); + return error("Could not find all arguments required for Setlistat inbuilt"); } { ListRef listref; @@ -1212,23 +1220,23 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { listref = get(l.args[0]); } else { - error("First argument of setlistat must be a list reference"); + return error("First argument of setlistat must be a list reference"); } if (holds_alternative(l.args[1])) { if (holds_alternative(get(l.args[1]).val)) { ref = get(get(l.args[1]).val); } else { - error("Second argument of setlistat must be an integer literal"); + return error("Second argument of setlistat must be an integer literal"); } } else { - error("Second argument of setlistat must be an integer literal"); + return error("Second argument of setlistat must be an integer literal"); } if (holds_alternative(l.args[2])) { value = get(l.args[2]); } else { - error("Third argument of setlistat must be a direct reference"); + return error("Third argument of setlistat must be a direct reference"); } if (variables.find(listref.listName) != variables.end()) { if (holds_alternative(variables[listref.listName].val)) { @@ -1239,11 +1247,11 @@ Literal exec(vector in, bool executingFunction) { tmpLit.val = tmpList; setVal(listref.listName, tmpLit); } else { - error("Index " + to_string(ref) + " out of range of list " + listref.listName, "rangeError"); + return error("Index " + to_string(ref) + " out of range of list " + listref.listName, "rangeError"); } } } else { - error("Unknown list: " + listref.listName); + return error("Unknown list: " + listref.listName); } } break; @@ -1253,7 +1261,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Listappend: if (l.args.size() < 2) { - error("Could not find all arguments required for Listappend inbuilt"); + return error("Could not find all arguments required for Listappend inbuilt"); } { ListRef listref; @@ -1262,18 +1270,18 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { listref = get(l.args[0]); } else { - error("First argument of listappend must be a list reference"); + return error("First argument of listappend must be a list reference"); } if (holds_alternative(l.args[1])) { value = get(l.args[1]); } else { - error("Second argument of listappend must be a direct reference"); + return error("Second argument of listappend must be a direct reference"); } if (variables.find(listref.listName) != variables.end()) { if (!holds_alternative(variables[listref.listName].val)) { - error("Variable " + listref.listName + "is not a list"); + return error("Variable " + listref.listName + "is not a list"); } List tmpList = get(variables[listref.listName].val); tmpList.val.push_back(value); @@ -1281,7 +1289,7 @@ Literal exec(vector in, bool executingFunction) { tmpLit.val = tmpList; setVal(listref.listName, tmpLit); } else { - error("Unknown list: " + listref.listName); + return error("Unknown list: " + listref.listName); } } break; @@ -1291,7 +1299,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Getlistsize: if (l.args.size() < 2) { - error("Could not find all arguments required for Getlistsize inbuilt"); + return error("Could not find all arguments required for Getlistsize inbuilt"); } { ListRef ref; @@ -1300,13 +1308,13 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { ref = get(l.args[0]); } else { - error("First argument of getlistsize must be a list reference"); + return error("First argument of getlistsize must be a list reference"); } if (holds_alternative(l.args[1])) { var = get(l.args[1]); } else { - error("Second argument of getlistsize must be a direct reference"); + return error("Second argument of getlistsize must be a direct reference"); } Literal newLit; @@ -1315,7 +1323,7 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(var.varName) > 0; setVal(var.varName, newLit); } else { - error("Couldn't find the list " + ref.listName); + return error("Couldn't find the list " + ref.listName); } break; @@ -1326,7 +1334,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Getstrsize: if (l.args.size() < 2) { - error("Could not find all arguments required for Getstrsize inbuilt"); + return error("Could not find all arguments required for Getstrsize inbuilt"); } { string ref; @@ -1336,16 +1344,16 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(get(l.args[0]).val)) { ref = get(get(l.args[0]).val); } else { - error("First argument of getlistsize must be a string value"); + return error("First argument of getlistsize must be a string value"); } } else { - error("First argument of getlistsize must be a string value"); + return error("First argument of getlistsize must be a string value"); } if (holds_alternative(l.args[1])) { var = get(l.args[1]); } else { - error("Second argument of getlistsize must be a direct reference"); + return error("Second argument of getlistsize must be a direct reference"); } Literal newLit; @@ -1361,7 +1369,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Stoi: if (l.args.size() < 2) { - error("Could not find all arguments required for Stoi inbuilt"); + return error("Could not find all arguments required for Stoi inbuilt"); } { string toConv; @@ -1371,16 +1379,16 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(get(l.args[0]).val)) { toConv = get(get(l.args[0]).val); } else { - error("First argument of stoi must be a string literal"); + return error("First argument of stoi must be a string literal"); } } else { - error("First argument of stoi must be a string literal"); + return error("First argument of stoi must be a string literal"); } if (holds_alternative(l.args[1])) { ref = get(l.args[1]); } else { - error("Second argument of stoi must be a direct reference"); + return error("Second argument of stoi must be a direct reference"); } if (isInt(toConv)) { @@ -1389,7 +1397,7 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(ref.varName) > 0; setVal(ref.varName, newLit); } else { - error("Cannot convert the value " + toConv + " to an int", "conversionError"); + return error("Cannot convert the value " + toConv + " to an int", "conversionError"); } } break; @@ -1400,7 +1408,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Stod: if (l.args.size() < 2) { - error("Could not find all arguments required for Stod inbuilt"); + return error("Could not find all arguments required for Stod inbuilt"); } { string toConv; @@ -1410,16 +1418,16 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(get(l.args[0]).val)) { toConv = get(get(l.args[0]).val); } else { - error("First argument of stod must be a string literal"); + return error("First argument of stod must be a string literal"); } } else { - error("First argument of stod must be a string literal"); + return error("First argument of stod must be a string literal"); } if (holds_alternative(l.args[1])) { ref = get(l.args[1]); } else { - error("Second argument of stod must be a direct reference"); + return error("Second argument of stod must be a direct reference"); } if (isDouble(toConv) || isInt(toConv)) { @@ -1428,7 +1436,7 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(ref.varName) > 0; setVal(ref.varName, newLit); } else { - error("Cannot convert the value " + toConv + " to a decimal", "conversionError"); + return error("Cannot convert the value " + toConv + " to a decimal", "conversionError"); } } break; @@ -1438,7 +1446,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Tostring: if (l.args.size() < 2) { - error("Could not find all arguments required for Tostring inbuilt"); + return error("Could not find all arguments required for Tostring inbuilt"); } { Literal toConv; @@ -1447,13 +1455,13 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { toConv = get(l.args[0]); } else { - error("First argument of tostring must be a literal"); + return error("First argument of tostring must be a literal"); } if (holds_alternative(l.args[1])) { ref = get(l.args[1]); } else { - error("Second argument of tostring must be a direct reference"); + return error("Second argument of tostring must be a direct reference"); } Literal newLit; @@ -1485,7 +1493,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Stdin: if (l.args.size() < 1) { - error("Could not find all arguments required for Stdin inbuilt"); + return error("Could not find all arguments required for Stdin inbuilt"); } if (holds_alternative(l.args[0])) { Direct varRef = get(l.args[0]); @@ -1496,7 +1504,7 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(varRef.varName) > 0; setVal(varRef.varName, userLit); } else { - error("First argument of stdin must be a direct reference"); + return error("First argument of stdin must be a direct reference"); } break; /* @@ -1506,7 +1514,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Add: if (l.args.size() < 3) { - error("Could not find all arguments required for Add inbuilt"); + return error("Could not find all arguments required for Add inbuilt"); } { Direct varRef; @@ -1517,19 +1525,19 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { left = get(l.args[0]); } else { - error("First argument of add must be a value (literal or value reference)"); + return error("First argument of add must be a value (literal or value reference)"); } if (holds_alternative(l.args[1])) { right = get(l.args[1]); } else { - error("Second argument of add must be a value (literal or value reference)"); + return error("Second argument of add must be a value (literal or value reference)"); } if (holds_alternative(l.args[2])) { varRef = get(l.args[2]); } else { - error("Third argument of add must be a direct reference"); + return error("Third argument of add must be a direct reference"); } // Figure out types and compute values @@ -1550,7 +1558,7 @@ Literal exec(vector in, bool executingFunction) { } else if (holds_alternative(left.val) && holds_alternative(right.val)) { final.val = string().append(&get(left.val)).append(&get(right.val)); } else { - error("Cannot add those two values", "mathError"); + return error("Cannot add those two values", "mathError"); } bool existed = variables.count(varRef.varName) > 0; @@ -1564,7 +1572,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Subtract: if (l.args.size() < 3) { - error("Could not find all arguments required for Subtract inbuilt"); + return error("Could not find all arguments required for Subtract inbuilt"); } { Direct varRef; @@ -1575,19 +1583,19 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { left = get(l.args[0]); } else { - error("First argument of subtract must be a value (literal or value reference)"); + return error("First argument of subtract must be a value (literal or value reference)"); } if (holds_alternative(l.args[1])) { right = get(l.args[1]); } else { - error("Second argument of subtract must be a value (literal or value reference)"); + return error("Second argument of subtract must be a value (literal or value reference)"); } if (holds_alternative(l.args[2])) { varRef = get(l.args[2]); } else { - error("Third argument of subtract must be a direct reference"); + return error("Third argument of subtract must be a direct reference"); } // Figure out types and compute values @@ -1600,7 +1608,7 @@ Literal exec(vector in, bool executingFunction) { } else if (holds_alternative(left.val) && holds_alternative(right.val)) { final.val = get(left.val) - double(get(right.val)); } else { - error("Cannot subtract those two values", "mathError"); + return error("Cannot subtract those two values", "mathError"); } bool existed = variables.count(varRef.varName) > 0; @@ -1614,7 +1622,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Multiply: if (l.args.size() < 3) { - error("Could not find all arguments required for Multiply inbuilt"); + return error("Could not find all arguments required for Multiply inbuilt"); } { Direct varRef; @@ -1625,19 +1633,19 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { left = get(l.args[0]); } else { - error("First argument of multiply must be a value (literal or value reference)"); + return error("First argument of multiply must be a value (literal or value reference)"); } if (holds_alternative(l.args[1])) { right = get(l.args[1]); } else { - error("Second argument of multiply must be a value (literal or value reference)"); + return error("Second argument of multiply must be a value (literal or value reference)"); } if (holds_alternative(l.args[2])) { varRef = get(l.args[2]); } else { - error("Third argument of multiply must be a direct reference"); + return error("Third argument of multiply must be a direct reference"); } // Figure out types and compute values @@ -1650,7 +1658,7 @@ Literal exec(vector in, bool executingFunction) { } else if (holds_alternative(left.val) && holds_alternative(right.val)) { final.val = get(left.val) * double(get(right.val)); } else { - error("Cannot multiply those two values", "mathError"); + return error("Cannot multiply those two values", "mathError"); } bool existed = variables.count(varRef.varName) > 0; @@ -1664,7 +1672,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Divide: if (l.args.size() < 3) { - error("Could not find all arguments required for Divide inbuilt"); + return error("Could not find all arguments required for Divide inbuilt"); } { Direct varRef; @@ -1675,30 +1683,30 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { left = get(l.args[0]); } else { - error("First argument of divide must be a value (literal or value reference)"); + return error("First argument of divide must be a value (literal or value reference)"); } if (holds_alternative(l.args[1])) { right = get(l.args[1]); } else { - error("Second argument of divide must be a value (literal or value reference)"); + return error("Second argument of divide must be a value (literal or value reference)"); } if (holds_alternative(l.args[2])) { varRef = get(l.args[2]); } else { - error("Third argument of divide must be a direct reference"); + return error("Third argument of divide must be a direct reference"); } // Ensure we aren't dividing by zero if (holds_alternative(right.val)) { if (get(right.val) == 0) { - error("Division by zero is not allowed", "divisionByZeroError"); + return error("Division by zero is not allowed", "divisionByZeroError"); } } if (holds_alternative(right.val)) { if (get(right.val) == 0) { - error("Division by zero is not allowed", "divisionByZeroError"); + return error("Division by zero is not allowed", "divisionByZeroError"); } } @@ -1712,7 +1720,7 @@ Literal exec(vector in, bool executingFunction) { } else if (holds_alternative(left.val) && holds_alternative(right.val)) { final.val = get(left.val) / double(get(right.val)); } else { - error("Cannot divide those two values", "mathError"); + return error("Cannot divide those two values", "mathError"); } bool existed = variables.count(varRef.varName) > 0; @@ -1726,7 +1734,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Equal: if (l.args.size() < 3) { - error("Could not find all arguments required for Equal inbuilt"); + return error("Could not find all arguments required for Equal inbuilt"); } { Direct varRef; @@ -1737,19 +1745,19 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { left = get(l.args[0]); } else { - error("First argument of equal must be a value (literal or value reference)"); + return error("First argument of equal must be a value (literal or value reference)"); } if (holds_alternative(l.args[1])) { right = get(l.args[1]); } else { - error("Second argument of equal must be a value (literal or value reference)"); + return error("Second argument of equal must be a value (literal or value reference)"); } if (holds_alternative(l.args[2])) { varRef = get(l.args[2]); } else { - error("Third argument of equal must be a direct reference"); + return error("Third argument of equal must be a direct reference"); } // Figure out types and compute values @@ -1768,7 +1776,7 @@ Literal exec(vector in, bool executingFunction) { } else if (holds_alternative(left.val) && holds_alternative(right.val)) { final.val = get(left.val) == get(right.val); } else { - error("Cannot equal those two values", "comparisonError"); + return error("Cannot equal those two values", "comparisonError"); } bool existed = variables.count(varRef.varName) > 0; @@ -1782,7 +1790,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Inequal: if (l.args.size() < 3) { - error("Could not find all arguments required for Inequal inbuilt"); + return error("Could not find all arguments required for Inequal inbuilt"); } { Direct varRef; @@ -1793,19 +1801,19 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { left = get(l.args[0]); } else { - error("First argument of inequal must be a value (literal or value reference)"); + return error("First argument of inequal must be a value (literal or value reference)"); } if (holds_alternative(l.args[1])) { right = get(l.args[1]); } else { - error("Second argument of inequal must be a value (literal or value reference)"); + return error("Second argument of inequal must be a value (literal or value reference)"); } if (holds_alternative(l.args[2])) { varRef = get(l.args[2]); } else { - error("Third argument of inequal must be a direct reference"); + return error("Third argument of inequal must be a direct reference"); } // Figure out types and compute values @@ -1824,7 +1832,7 @@ Literal exec(vector in, bool executingFunction) { } else if (holds_alternative(left.val) && holds_alternative(right.val)) { final.val = get(left.val) != get(right.val); } else { - error("Cannot inequal those two values", "comparisonError"); + return error("Cannot inequal those two values", "comparisonError"); } bool existed = variables.count(varRef.varName) > 0; @@ -1838,7 +1846,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Greater: if (l.args.size() < 3) { - error("Could not find all arguments required for Greater inbuilt"); + return error("Could not find all arguments required for Greater inbuilt"); } { Direct varRef; @@ -1849,19 +1857,19 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { left = get(l.args[0]); } else { - error("First argument of greater must be a value (literal or value reference)"); + return error("First argument of greater must be a value (literal or value reference)"); } if (holds_alternative(l.args[1])) { right = get(l.args[1]); } else { - error("Second argument of greater must be a value (literal or value reference)"); + return error("Second argument of greater must be a value (literal or value reference)"); } if (holds_alternative(l.args[2])) { varRef = get(l.args[2]); } else { - error("Third argument of greater must be a direct reference"); + return error("Third argument of greater must be a direct reference"); } // Figure out types and compute values @@ -1880,7 +1888,7 @@ Literal exec(vector in, bool executingFunction) { } else if (holds_alternative(left.val) && holds_alternative(right.val)) { final.val = get(left.val) > get(right.val); } else { - error("Cannot greater those two values", "comparisonError"); + return error("Cannot greater those two values", "comparisonError"); } bool existed = variables.count(varRef.varName) > 0; @@ -1894,7 +1902,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Lesser: if (l.args.size() < 3) { - error("Could not find all arguments required for Lesser inbuilt"); + return error("Could not find all arguments required for Lesser inbuilt"); } { Direct varRef; @@ -1905,19 +1913,19 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { left = get(l.args[0]); } else { - error("First argument of lesser must be a value (literal or value reference)"); + return error("First argument of lesser must be a value (literal or value reference)"); } if (holds_alternative(l.args[1])) { right = get(l.args[1]); } else { - error("Second argument of lesser must be a value (literal or value reference)"); + return error("Second argument of lesser must be a value (literal or value reference)"); } if (holds_alternative(l.args[2])) { varRef = get(l.args[2]); } else { - error("Third argument of lesser must be a direct reference"); + return error("Third argument of lesser must be a direct reference"); } // Figure out types and compute values @@ -1936,7 +1944,7 @@ Literal exec(vector in, bool executingFunction) { } else if (holds_alternative(left.val) && holds_alternative(right.val)) { final.val = get(left.val) < get(right.val); } else { - error("Cannot lesser those two values", "comparisonError"); + return error("Cannot lesser those two values", "comparisonError"); } bool existed = variables.count(varRef.varName) > 0; @@ -1950,7 +1958,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Not: if (l.args.size() < 2) { - error("Could not find all arguments required for Not inbuilt"); + return error("Could not find all arguments required for Not inbuilt"); } { Literal boolean; @@ -1960,16 +1968,16 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(get(l.args[0]).val)) { boolean.val = !get(get(l.args[0]).val); } else { - error("First argument of not must be a boolean literal"); + return error("First argument of not must be a boolean literal"); } } else { - error("First argument of not must be a boolean literal"); + return error("First argument of not must be a boolean literal"); } if (holds_alternative(l.args[1])) { varRef = get(l.args[1]); } else { - error("Second argument of not must be a direct reference"); + return error("Second argument of not must be a direct reference"); } setVal(varRef.varName, boolean); @@ -1981,12 +1989,12 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Jump: if (l.args.size() < 1) { - error("Could not find all arguments required for Jump inbuilt"); + return error("Could not find all arguments required for Jump inbuilt"); } if (holds_alternative(l.args[0])) { i = get(l.args[0]).lineNum - 1; } else { - error("First argument of jump must be a line reference"); + return error("First argument of jump must be a line reference"); } break; /* @@ -1996,23 +2004,23 @@ Literal exec(vector in, bool executingFunction) { case Instructions::If: { if (l.args.size() < 2) { - error("Could not find all arguments required for If inbuilt"); + return error("Could not find all arguments required for If inbuilt"); } bool isTrue = false; if (holds_alternative(l.args[0])) { if (holds_alternative(get(l.args[0]).val)) { if (get(get(l.args[0]).val)) isTrue = true; } else { - error("First argument of if must be a bool value"); + return error("First argument of if must be a bool value"); } } else { - error("First argument of if must be a bool value"); + return error("First argument of if must be a bool value"); } if (isTrue) { if (holds_alternative(l.args[1])) { i = get(l.args[1]).lineNum - 1; } else { - error("Second argument of if must be a line reference"); + return error("Second argument of if must be a line reference"); } } } @@ -2023,21 +2031,21 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::End: if (l.args.size() < 1) { - error("Could not find all arguments required for End inbuilt"); + return error("Could not find all arguments required for End inbuilt"); } if (holds_alternative(l.args[0])) { if (holds_alternative(get(l.args[0]).val)) { exit(get(get(l.args[0]).val)); } else { - error("First argument of end must be an int value"); + return error("First argument of end must be an int value"); } } else { - error("First argument of end must be an int value"); + return error("First argument of end must be an int value"); } break; case Instructions::Gettype: if (l.args.size() < 2) { - error("Could not find all arguments required for Gettype inbuilt"); + return error("Could not find all arguments required for Gettype inbuilt"); } { Literal val; @@ -2045,7 +2053,7 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { val = get(l.args[0]); } else { - error("First argument of gettype must be a literal"); + return error("First argument of gettype must be a literal"); } Types type = getLitType(val); @@ -2055,7 +2063,7 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[1])) { ref = get(l.args[1]); } else { - error("Second argument of gettype must be a direct reference"); + return error("Second argument of gettype must be a direct reference"); } Literal tmpLit; @@ -2077,7 +2085,7 @@ Literal exec(vector in, bool executingFunction) { tmpLit.val = "char"; break; default: - error("Could not get type?? This should never be reached. Please report this issue", "undefinedError"); + return error("Could not get type?? This should never be reached. Please report this issue", "undefinedError"); break; } @@ -2088,14 +2096,14 @@ Literal exec(vector in, bool executingFunction) { break; case Instructions::Exists: if (l.args.size() < 2) { - error("Could not find all arguments required for Exists inbuilt"); + return error("Could not find all arguments required for Exists inbuilt"); } { Direct ref2; if (holds_alternative(l.args[1])) { ref2 = get(l.args[1]); } else { - error("Second argument of exists must be a direct reference"); + return error("Second argument of exists must be a direct reference"); } bool exists = false; @@ -2119,7 +2127,7 @@ Literal exec(vector in, bool executingFunction) { } } } else { - error("First argument of exists must be a direct, list, or line reference"); + return error("First argument of exists must be a direct, list, or line reference"); } Literal tmpLit; tmpLit.val = exists; @@ -2132,7 +2140,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Fun: if (l.args.size() < 2) { - error("Could not find all arguments required for Fun inbuilt"); + return error("Could not find all arguments required for Fun inbuilt"); } { Function newFunction; @@ -2140,7 +2148,7 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { newFunction.returnType = get(l.args[0]).type; } else { - error("First argument of function must be a type reference"); + return error("First argument of function must be a type reference"); } string fnName; @@ -2148,7 +2156,7 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[1])) { fnName = get(l.args[1]).fnName; } else { - error("Second argument of function must be a function reference"); + return error("Second argument of function must be a function reference"); } if (importing.size() > 0) { @@ -2157,7 +2165,7 @@ Literal exec(vector in, bool executingFunction) { // Parse function arguments (type-direct pairs) if ((l.args.size() - 2) % 2 != 0) { - error("Function arguments must be in type-direct pairs"); + return error("Function arguments must be in type-direct pairs"); } for (int m = 2; m < l.args.size(); m += 2) { @@ -2167,14 +2175,14 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[m])) { newArg.type = get(l.args[m]).type; } else { - error("Expected type reference in function argument definition"); + return error("Expected type reference in function argument definition"); } // Get direct reference if (m + 1 < l.args.size() && holds_alternative(l.args[m + 1])) { newArg.ref = get(l.args[m + 1]); } else { - error("Expected direct reference after type reference in function argument definition"); + return error("Expected direct reference after type reference in function argument definition"); } newFunction.args.push_back(newArg); @@ -2187,7 +2195,7 @@ Literal exec(vector in, bool executingFunction) { break; case Instructions::Struct: if (l.args.size() < 1) { - error("Could not find all arguments required for Struct inbuilt"); + return error("Could not find all arguments required for Struct inbuilt"); } { string structName; @@ -2195,7 +2203,7 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { structName = get(l.args[0]).customType; } else { - error("First argument of struct must be a type reference"); + return error("First argument of struct must be a type reference"); } Struct newStruct; @@ -2210,14 +2218,14 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Return: if (l.args.size() < 1) { - error("Could not find all arguments required for Return inbuilt"); + return error("Could not find all arguments required for Return inbuilt"); } if (holds_alternative(l.args[0])) { return get(l.args[0]); } else if (holds_alternative(l.args[0])) { return variables[get(l.args[0]).listName]; } else { - error("First argument of return must be a literal value/value reference"); + return error("First argument of return must be a literal value/value reference"); } break; /* @@ -2225,7 +2233,7 @@ Literal exec(vector in, bool executingFunction) { This should not be reached during normal execution. */ case Instructions::Endfun: - error("No function is being defined. Cannot end function declaration here"); + return error("No function is being defined. Cannot end function declaration here"); break; /* pusharg instruction @@ -2233,7 +2241,7 @@ Literal exec(vector in, bool executingFunction) { */ case Instructions::Pusharg: if (l.args.size() < 1) { - error("Could not find all arguments required for Endfun inbuilt"); + return error("Could not find all arguments required for Endfun inbuilt"); } for (int k = 0; k < l.args.size(); k++) { if (holds_alternative(l.args[k])) { @@ -2241,7 +2249,7 @@ Literal exec(vector in, bool executingFunction) { } else if (holds_alternative(l.args[k])) { fnArgs.push_back(variables[get(l.args[k]).listName]); } else { - error("First argument of pusharg must be a literal or list reference"); + return error("First argument of pusharg must be a literal or list reference"); } } break; @@ -2252,7 +2260,7 @@ Literal exec(vector in, bool executingFunction) { case Instructions::Call: { if (l.args.size() < 2) { - error("Could not find all arguments required for Call inbuilt"); + return error("Could not find all arguments required for Call inbuilt"); } FunctionRef ref; @@ -2263,7 +2271,7 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[0])) { ref = get(l.args[0]); } else { - error("First argument of call must be a function reference"); + return error("First argument of call must be a function reference"); } if (holds_alternative(l.args[1])) { @@ -2272,7 +2280,7 @@ Literal exec(vector in, bool executingFunction) { returnRef = get(l.args[1]).listName; expectList = true; } else { - error("Second argument of call must be a direct reference or list reference"); + return error("Second argument of call must be a direct reference or list reference"); } // Check for external function @@ -2324,22 +2332,22 @@ Literal exec(vector in, bool executingFunction) { fnToExec = structVal.functions[fnInStruct]; inStruct = true; } else { - error("Could not find function '" + fnInStruct + "' in struct '" + structName + "'"); + return error("Could not find function '" + fnInStruct + "' in struct '" + structName + "'"); } for (auto &[key, value] : structVal.values) { variables[key] = value; } } else { - error("Variable '" + structName + "' is not a struct"); + return error("Variable '" + structName + "' is not a struct"); } } else { - error("Could not find struct '" + structName + "'"); + return error("Could not find struct '" + structName + "'"); } } else { - error("Invalid struct member access syntax"); + return error("Invalid struct member access syntax"); } } else { - error("Function " + ref.fnName + " not found"); + return error("Function " + ref.fnName + " not found"); } } else { fnToExec = functions[ref.fnName]; @@ -2347,7 +2355,7 @@ Literal exec(vector in, bool executingFunction) { // Check argument count if (fnArgs.size() != fnToExec.args.size()) { - error("Function " + ref.fnName + " expects " + + return error("Function " + ref.fnName + " expects " + to_string(fnToExec.args.size()) + " arguments, got " + to_string(fnArgs.size())); } @@ -2358,7 +2366,7 @@ Literal exec(vector in, bool executingFunction) { // Type checking - now with error reporting if (arg.type != getLitType(fnArgs[m])) { - error("Function " + ref.fnName + " argument " + to_string(m + 1) + + return error("Function " + ref.fnName + " argument " + to_string(m + 1) + " type mismatch. Expected type does not match provided argument type.", "typeError"); } @@ -2394,7 +2402,7 @@ Literal exec(vector in, bool executingFunction) { setVal(returnRef, retVal); } else { if (holds_alternative(retVal.val)) { - error("Expecting to output a normal literal to a normal literal"); + return error("Expecting to output a normal literal to a normal literal"); } else { setVal(returnRef, retVal); } @@ -2403,7 +2411,7 @@ Literal exec(vector in, bool executingFunction) { break; case Instructions::Use: if (l.args.size() < 1) { - error("Could not find all arguments for Use inbuilt"); + return error("Could not find all arguments for Use inbuilt"); } { string useName; @@ -2412,10 +2420,10 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(get(l.args[0]).val)) { useName = get(get(l.args[0]).val) + ".grnd"; } else { - error("First argument for use requires a string literal"); + return error("First argument for use requires a string literal"); } } else { - error("First argument for use requires a string literal"); + return error("First argument for use requires a string literal"); } string libName = get(get(l.args[0]).val); @@ -2436,7 +2444,7 @@ Literal exec(vector in, bool executingFunction) { } else if (groundLibsDir != "" && filesystem::exists(groundLibsDir + useName)) { useName = groundLibsDir + useName; } else { - error("Could not find external Ground library in $GROUND_LIBS (currently set to " + groundLibsDir +") or current directory.", "libraryError"); + return error("Could not find external Ground library in $GROUND_LIBS (currently set to " + groundLibsDir +") or current directory.", "libraryError"); } ifstream file(useName); @@ -2455,7 +2463,7 @@ Literal exec(vector in, bool executingFunction) { break; case Instructions::Extern: if (l.args.size() < 1) { - error("Could not find all arguments for Extern inbuilt"); + return error("Could not find all arguments for Extern inbuilt"); } { string libName; @@ -2464,10 +2472,10 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(get(l.args[0]).val)) { libName = get(get(l.args[0]).val); } else { - error("First argument for extern requires a string literal"); + return error("First argument for extern requires a string literal"); } } else { - error("First argument for extern requires a string literal"); + return error("First argument for extern requires a string literal"); } bool imported = false; @@ -2510,14 +2518,14 @@ Literal exec(vector in, bool executingFunction) { } if (!found) { - error("Could not find external library: " + fullLibName + + return error("Could not find external library: " + fullLibName + " (searched current directory and GROUND_LIBS)", "libraryError"); } // Try to open the library void* handle = DLOPEN(libPath.c_str()); if (!handle) { - error("Failed to load library " + libPath + ": " + string(DLERROR()), "libraryError"); + return error("Failed to load library " + libPath + ": " + string(DLERROR()), "libraryError"); } // Store handle for cleanup later @@ -2531,7 +2539,7 @@ Literal exec(vector in, bool executingFunction) { GetFunctionFunc getFunction = (GetFunctionFunc)DLSYM(handle, "ground_get_function"); if (!getFunctions || !getFunction) { - error("Library " + libName + " is not Ground-compatible (missing required functions: ground_get_functions or ground_get_function)", "libraryError"); + return error("Library " + libName + " is not Ground-compatible (missing required functions: ground_get_functions or ground_get_function)", "libraryError"); } // Optional initialization @@ -2544,7 +2552,7 @@ Literal exec(vector in, bool executingFunction) { // Register all functions const char** functionNames = getFunctions(); if (!functionNames) { - error("Library " + libName + " returned null function list"); + return error("Library " + libName + " returned null function list"); } int functionCount = 0; @@ -2554,12 +2562,12 @@ Literal exec(vector in, bool executingFunction) { externalFunctions[libName + ":" + string(functionNames[i])] = funcPtr; functionCount++; } else { - error("Failed to get function pointer for: " + string(functionNames[i]), "libraryError"); + return error("Failed to get function pointer for: " + string(functionNames[i]), "libraryError"); } } if (functionCount == 0) { - error("No functions were loaded from library: " + libName, "libraryError"); + return error("No functions were loaded from library: " + libName, "libraryError"); } } break; @@ -2568,7 +2576,7 @@ Literal exec(vector in, bool executingFunction) { break; } } - if (executingFunction) error("Reached end of function and no value returned"); + if (executingFunction) return error("Reached end of function and no value returned"); Literal retLiteral; return retLiteral; }