From 9e329968d1d20722f389a8591dd4a55653d30152 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Sat, 13 Sep 2025 15:47:24 +1000 Subject: [PATCH] Error types, print lists, better fn calling --- src/main.cpp | 292 ++++++++++++++++++++++++++++--------------- tests/error.grnd | 2 +- tests/functions.grnd | 2 +- tests/lists.grnd | 1 + tests/to1000.grnd | 5 +- 5 files changed, 198 insertions(+), 104 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 053af1a..c8cdb84 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,7 +13,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ /* @@ -78,8 +78,7 @@ enum class Instructions { Getstrcharat, Getstrsize, Stoi, Stod, Tostring, Fun, Return, Endfun, Pusharg, Call, Local, - Use, Extern, - Error + Use, Extern, Error, Catch, Try, Exception }; /* @@ -124,7 +123,7 @@ struct Literal; val = 13 }, } - } + } All elements in the list must be of the same type. See also Literal struct. */ struct List { @@ -281,7 +280,7 @@ struct Function { // C-compatible enum and types for developing libraries for Ground in C typedef enum { GROUND_INT, - GROUND_DOUBLE, + GROUND_DOUBLE, GROUND_BOOL, GROUND_STRING, GROUND_CHAR @@ -306,7 +305,7 @@ map functions; /* fnArgs vector - Containst the arguments to be passed to a function + Containst the arguments to be passed to a function */ vector fnArgs; @@ -368,10 +367,10 @@ Literal groundValueToLiteral(const GroundValue& gv) { /* error function Takes a string (which is a debug message) and prints it to the console, letting the - user know what went wrong with the program. + user know what went wrong with the program. */ -void error(string in, int exitc = 1) { - cout << "\033[31mError: \033[39m" << in << endl; +void error(string in, string errCode = "syntaxError", int exitc = 1) { + cout << "\033[31m" + errCode + ": \033[39m" << in << endl; exit(exitc); } @@ -442,7 +441,7 @@ bool isListRef(string in) { bool isType(string in) { if (in.size() >= 1 && in[0] == '-') { string type = in.substr(1); - if (type == "string" || type == "char" || type == "bool" || type == "double" || type == "int" || type == "list") return true; + if (type == "string" || type == "char" || type == "bool" || type == "double" || type == "int" || type == "list") return true; else return false; } else return false; } @@ -485,6 +484,7 @@ Types getLitType(Literal in) { if (holds_alternative(in.val)) return Types::Bool; if (holds_alternative(in.val)) return Types::String; if (holds_alternative(in.val)) return Types::Char; + if (holds_alternative(in.val)) return Types::List; error("Literal for some reason has a weird type. This is not an issue with your program, but an issue with the Ground interpreter."); return Types::Int; } @@ -595,7 +595,42 @@ Literal exec(vector in, bool executingFunction) { cout << get(get(l.args[0]).val); } else { - error("Couldn't print that"); + error("Couldn't print that", "printError"); + } + } else if (holds_alternative(l.args[0])) { + if (variables.find(get(l.args[0]).listName) != variables.end()) { + List list = get(variables[get(l.args[0]).listName].val); + cout << "["; + for (int l = 0; l < list.val.size(); l++) { + if (holds_alternative(list.val[l].val)) { + cout << '"' << get(list.val[l].val) << '"'; + } + else if (holds_alternative(list.val[l].val)) { + cout << get(list.val[l].val); + } + else if (holds_alternative(list.val[l].val)) { + cout << get(list.val[l].val); + } + else if (holds_alternative(list.val[l].val)) { + if (get(list.val[l].val) == true) { + cout << "true"; + } else { + cout << "false"; + } + } + else if (holds_alternative(list.val[l].val)) { + cout << '\'' << get(list.val[l].val) << '\''; + } + else { + error("Couldn't print that", "printError"); + } + if (l != list.val.size() - 1) { + cout << ", "; + } + } + cout << "]"; + } else { + 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)"); @@ -631,30 +666,78 @@ Literal exec(vector in, bool executingFunction) { cout << get(get(l.args[0]).val) << endl; } else { - error("Couldn't print that"); + error("Couldn't print that", "printError"); + } + } else if (holds_alternative(l.args[0])) { + if (variables.find(get(l.args[0]).listName) != variables.end()) { + List list = get(variables[get(l.args[0]).listName].val); + cout << "["; + for (int l = 0; l < list.val.size(); l++) { + if (holds_alternative(list.val[l].val)) { + cout << '"' << get(list.val[l].val) << '"'; + } + else if (holds_alternative(list.val[l].val)) { + cout << get(list.val[l].val); + } + else if (holds_alternative(list.val[l].val)) { + cout << get(list.val[l].val); + } + else if (holds_alternative(list.val[l].val)) { + if (get(list.val[l].val) == true) { + cout << "true"; + } else { + cout << "false"; + } + } + else if (holds_alternative(list.val[l].val)) { + cout << '\'' << get(list.val[l].val) << '\''; + } + else { + error("Couldn't print that", "printError"); + } + if (l != list.val.size() - 1) { + cout << ", "; + } + } + cout << "]" << endl; + } else { + 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)"); + error("Argument of stdlnout must be a value (literal or a value reference) or a list reference"); } break; /* error instruction This instruction outputs a custom error message. */ - case Instructions::Error: - if (l.args.size() < 1) { - error("Could not find argument for Error inbuilt"); + if (l.args.size() < 2) { + error("Could not find arguments for Error inbuilt"); } if (holds_alternative(l.args[0])) { - if (holds_alternative(get(l.args[0]).val)) { - error(get(get(l.args[0]).val)); + 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)); } else { error("Argument of error must be a string"); } } else { + error("Argument of error must be a string"); } break; + /* + catch instruction + This instruction ensures that errors in programs are caught and dealt with appropriately. + */ + case Instructions::Catch: + if (l.args.size() < 2) { + error("Could not find all arguments for Catch inbuilt"); + } + if (holds_alternative(l.args[0])) { + if (holds_alternative(get(l.args[0]).val)) { + + } + } /* set instruction This instruction sets a variable to a provided value. @@ -678,7 +761,7 @@ Literal exec(vector in, bool executingFunction) { } else { error("Second argument of set must be a value (literal or value reference)"); } - + bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = varContents; } @@ -737,7 +820,7 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[1])) { if (holds_alternative(get(l.args[1]).val)) { ref = get(get(l.args[1]).val); - } else { + } else { error("Second argument of getlistat must be an integer literal"); } } else { @@ -756,7 +839,7 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(var.varName) > 0; variables[var.varName] = get(variables[listref.listName].val).val[ref]; } else { - error("Index " + to_string(ref) + " out of range of list " + listref.listName); + error("Index " + to_string(ref) + " out of range of list " + listref.listName, "rangeError"); } } else { error("Found a normal variable in place of a list"); @@ -793,7 +876,7 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[1])) { if (holds_alternative(get(l.args[1]).val)) { ref = get(get(l.args[1]).val); - } else { + } else { error("Second argument of getstrcharat must be an integer literal"); } } else { @@ -812,7 +895,7 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(var.varName) > 0; variables[var.varName] = newLit; } else { - error("Index " + to_string(ref) + " out of range of string " + instr); + error("Index " + to_string(ref) + " out of range of string " + instr, "rangeError"); } } break; @@ -838,7 +921,7 @@ Literal exec(vector in, bool executingFunction) { if (holds_alternative(l.args[1])) { if (holds_alternative(get(l.args[1]).val)) { ref = get(get(l.args[1]).val); - } else { + } else { error("Second argument of setlistat must be an integer literal"); } } else { @@ -857,7 +940,7 @@ Literal exec(vector in, bool executingFunction) { tmpList.val[ref] = value; variables[listref.listName].val = tmpList; } else { - error("Index " + to_string(ref) + " out of range of list " + listref.listName); + error("Index " + to_string(ref) + " out of range of list " + listref.listName, "rangeError"); } } } else { @@ -912,7 +995,7 @@ Literal exec(vector in, bool executingFunction) { { ListRef ref; Direct var; - + if (holds_alternative(l.args[0])) { ref = get(l.args[0]); } else { @@ -933,7 +1016,7 @@ Literal exec(vector in, bool executingFunction) { } else { error("Couldn't find the list " + ref.listName); } - + break; } /* @@ -947,7 +1030,7 @@ Literal exec(vector in, bool executingFunction) { { string ref; Direct var; - + if (holds_alternative(l.args[0])) { if (holds_alternative(get(l.args[0]).val)) { ref = get(get(l.args[0]).val); @@ -968,7 +1051,7 @@ Literal exec(vector in, bool executingFunction) { newLit.val = int(ref.size()); bool existed = variables.count(var.varName) > 0; variables[var.varName] = newLit; - + break; } /* @@ -983,7 +1066,7 @@ Literal exec(vector in, bool executingFunction) { { string toConv; Direct ref; - + if (holds_alternative(l.args[0])) { if (holds_alternative(get(l.args[0]).val)) { toConv = get(get(l.args[0]).val); @@ -1006,7 +1089,7 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(ref.varName) > 0; variables[ref.varName] = newLit; } else { - error("Cannot convert the value " + toConv + " to an int"); + error("Cannot convert the value " + toConv + " to an int", "conversionError"); } } break; @@ -1022,7 +1105,7 @@ Literal exec(vector in, bool executingFunction) { { string toConv; Direct ref; - + if (holds_alternative(l.args[0])) { if (holds_alternative(get(l.args[0]).val)) { toConv = get(get(l.args[0]).val); @@ -1045,7 +1128,7 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(ref.varName) > 0; variables[ref.varName] = newLit; } else { - error("Cannot convert the value " + toConv + " to a decimal"); + error("Cannot convert the value " + toConv + " to a decimal", "conversionError"); } } break; @@ -1060,7 +1143,7 @@ Literal exec(vector in, bool executingFunction) { { Literal toConv; Direct ref; - + if (holds_alternative(l.args[0])) { toConv = get(l.args[0]); } else { @@ -1088,7 +1171,7 @@ Literal exec(vector in, bool executingFunction) { } else { newLit.val = "false"; } - } + } bool existed = variables.count(ref.varName) > 0; variables[ref.varName] = newLit; @@ -1167,9 +1250,9 @@ 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"); + error("Cannot add those two values", "mathError"); } - + bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = final; } @@ -1217,9 +1300,9 @@ 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"); + error("Cannot subtract those two values", "mathError"); } - + bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = final; } @@ -1267,9 +1350,9 @@ 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"); + error("Cannot multiply those two values", "mathError"); } - + bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = final; } @@ -1310,12 +1393,12 @@ Literal exec(vector in, bool executingFunction) { // Ensure we aren't dividing by zero if (holds_alternative(right.val)) { if (get(right.val) == 0) { - error("Division by zero is not allowed"); + 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"); + error("Division by zero is not allowed", "divisionByZeroError"); } } @@ -1329,9 +1412,9 @@ 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"); + error("Cannot divide those two values", "mathError"); } - + bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = final; } @@ -1385,9 +1468,9 @@ 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"); + error("Cannot equal those two values", "comparisonError"); } - + bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = final; } @@ -1441,9 +1524,9 @@ 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"); + error("Cannot inequal those two values", "comparisonError"); } - + bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = final; } @@ -1460,7 +1543,7 @@ Literal exec(vector in, bool executingFunction) { Literal boolean; Direct varRef; - + if (holds_alternative(l.args[0])) { if (holds_alternative(get(l.args[0]).val)) { boolean.val = !(get(get(l.args[0]).val)); @@ -1530,9 +1613,9 @@ 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"); + error("Cannot greater those two values", "comparisonError"); } - + bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = final; } @@ -1586,9 +1669,9 @@ 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"); + error("Cannot lesser those two values", "comparisonError"); } - + bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = final; } @@ -1693,10 +1776,10 @@ Literal exec(vector in, bool executingFunction) { variables[ref.varName].val = "char"; break; default: - error("Could not get type?? This should never be reached. Please report this issue"); + error("Could not get type?? This should never be reached. Please report this issue", "undefinedError"); break; } - + } break; @@ -1748,7 +1831,7 @@ Literal exec(vector in, bool executingFunction) { } { Function newFunction; - + if (holds_alternative(l.args[0])) { newFunction.returnType = get(l.args[0]).type; } else { @@ -1756,7 +1839,7 @@ Literal exec(vector in, bool executingFunction) { } string fnName; - + if (holds_alternative(l.args[1])) { fnName = get(l.args[1]).fnName; } else { @@ -1774,24 +1857,24 @@ Literal exec(vector in, bool executingFunction) { for (int m = 2; m < l.args.size(); m += 2) { FnArg newArg; - + // Get type if (holds_alternative(l.args[m])) { newArg.type = get(l.args[m]).type; } else { 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"); } - + newFunction.args.push_back(newArg); } - + functions[fnName] = newFunction; processingFunction = true; procFnName = fnName; @@ -1815,7 +1898,7 @@ Literal exec(vector in, bool executingFunction) { break; /* endfun instruction - This should not be reached during normal execution. + This should not be reached during normal execution. */ case Instructions::Endfun: error("No function is being defined. Cannot end function declaration here"); @@ -1845,12 +1928,12 @@ Literal exec(vector in, bool executingFunction) { if (l.args.size() < 2) { error("Could not find all arguments required for Call inbuilt"); } - + FunctionRef ref; string returnRef; bool expectList = true; - + if (holds_alternative(l.args[0])) { ref = get(l.args[0]); } else { @@ -1871,19 +1954,19 @@ Literal exec(vector in, bool executingFunction) { // Call external function typedef GroundValue (*ExtFunc)(GroundValue*, int); ExtFunc extFunc = (ExtFunc)externalFunctions[ref.fnName]; - + // Convert arguments vector gvArgs; for (const Literal& arg : fnArgs) { gvArgs.push_back(literalToGroundValue(arg)); } - + // Call function GroundValue result = extFunc(gvArgs.data(), gvArgs.size()); - + // Convert result back Literal resultLit = groundValueToLiteral(result); - + // Clear arguments and store result fnArgs.clear(); variables[returnRef] = resultLit; @@ -1898,8 +1981,8 @@ Literal exec(vector in, bool executingFunction) { // Check argument count if (fnArgs.size() != functions[ref.fnName].args.size()) { - error("Function " + ref.fnName + " expects " + - to_string(functions[ref.fnName].args.size()) + + error("Function " + ref.fnName + " expects " + + to_string(functions[ref.fnName].args.size()) + " arguments, got " + to_string(fnArgs.size())); } @@ -1909,17 +1992,17 @@ Literal exec(vector in, bool executingFunction) { // Create function arguments with type checking for (int m = 0; m < functions[ref.fnName].args.size(); m++) { FnArg arg = functions[ref.fnName].args[m]; - + // Type checking - now with error reporting if (arg.type != getLitType(fnArgs[m])) { - error("Function " + ref.fnName + " argument " + to_string(m + 1) + - " type mismatch. Expected type does not match provided argument type."); + error("Function " + ref.fnName + " argument " + to_string(m + 1) + + " type mismatch. Expected type does not match provided argument type.", "typeError"); } - + // Create the variable - variables[arg.ref.varName] = fnArgs[m]; + variables[arg.ref.varName] = fnArgs[m]; } - + // Clear function arguments for next call fnArgs.clear(); @@ -1951,7 +2034,7 @@ Literal exec(vector in, bool executingFunction) { } { string useName; - + if (holds_alternative(l.args[0])) { if (holds_alternative(get(l.args[0]).val)) { useName = get(get(l.args[0]).val) + ".grnd"; @@ -1976,11 +2059,11 @@ Literal exec(vector in, bool executingFunction) { string groundLibsDir = getenv("GROUND_LIBS"); if (filesystem::exists(useName)) { - - } else if (groundLibsDir != "" && filesystem::exists(groundLibsDir + useName)) { - useName = groundLibsDir + useName; + // no need to do anything here + } else if (groundLibsDir != "" && filesystem::exists(groundLibsDir + useName + ".grnd")) { + useName = groundLibsDir + useName + ".grnd"; } else { - error("Could not find external Ground library in $GROUND_LIBS or current directory."); + error("Could not find external Ground library in $GROUND_LIBS (currently set to " + groundLibsDir +") or current directory.", "libraryError"); } ifstream file(useName); @@ -2037,7 +2120,7 @@ Literal exec(vector in, bool executingFunction) { // Check multiple locations for the library string libPath; bool found = false; - + // Check GROUND_LIBS directory const char* groundLibsDir = getenv("GROUND_LIBS"); if (groundLibsDir) { @@ -2052,16 +2135,16 @@ Literal exec(vector in, bool executingFunction) { found = true; } } - + if (!found) { - error("Could not find external library: " + fullLibName + - " (searched current directory and GROUND_LIBS)"); + 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())); + error("Failed to load library " + libPath + ": " + string(DLERROR()), "libraryError"); } // Store handle for cleanup later @@ -2075,7 +2158,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)"); + error("Library " + libName + " is not Ground-compatible (missing required functions: ground_get_functions or ground_get_function)", "libraryError"); } // Optional initialization @@ -2090,7 +2173,7 @@ Literal exec(vector in, bool executingFunction) { if (!functionNames) { error("Library " + libName + " returned null function list"); } - + int functionCount = 0; for (int i = 0; functionNames[i] != nullptr; i++) { void* funcPtr = getFunction(functionNames[i]); @@ -2098,12 +2181,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])); + error("Failed to get function pointer for: " + string(functionNames[i]), "libraryError"); } } - + if (functionCount == 0) { - error("No functions were loaded from library: " + libName); + error("No functions were loaded from library: " + libName, "libraryError"); } } break; @@ -2161,7 +2244,7 @@ vector> lexer(string in) { bool procString = false; bool procChar = false; bool isComment = false; - + for (char i : in) { switch (i) { case '"': @@ -2231,7 +2314,7 @@ vector> lexer(string in) { vector parser(vector> in) { vector out; int lineNum = 0; - + for (vector lineTokens : in) { lineNum ++; Instruction newInst; @@ -2240,7 +2323,7 @@ vector parser(vector> in) { continue; }; bool firstInst = true; - + for (string i : lineTokens) { if (firstInst) { firstInst = false; @@ -2248,10 +2331,19 @@ vector parser(vector> in) { newInst.isLabel = true; newInst.label.id = i.substr(1); } + else if (isFunction(i)){ + newInst.inst = Instructions::Call; + FunctionRef newFnRef; + newFnRef.fnName = i.substr(1); + newInst.args.push_back(newFnRef); + } else if (i == "stdin") newInst.inst = Instructions::Stdin; else if (i == "stdout") newInst.inst = Instructions::Stdout; else if (i == "stdlnout") newInst.inst = Instructions::Stdlnout; else if (i == "error") newInst.inst = Instructions::Error; + else if (i == "try") newInst.inst = Instructions::Try; + else if (i == "catch") newInst.inst = Instructions::Catch; + else if (i == "exception") newInst.inst = Instructions::Exception; else if (i == "jump") newInst.inst = Instructions::Jump; else if (i == "if") newInst.inst = Instructions::If; else if (i == "add") newInst.inst = Instructions::Add; @@ -2315,7 +2407,7 @@ vector parser(vector> in) { else if (type == "int") newType.type = Types::Int; else if (type == "bool") newType.type = Types::Bool; else if (type == "list") newType.type = Types::List; - else error("Ground could not find type. This is an error with the interpreter, not your code. This line of code should never be reached."); + else error("Ground could not find type. This is an error with the interpreter, not your code. This line of code should never be reached.", "undefinedError"); newInst.args.push_back(newType); } break; @@ -2323,7 +2415,7 @@ vector parser(vector> in) { { FunctionRef newFunction; newFunction.fnName = i.substr(1); - newInst.args.push_back(newFunction); + newInst.args.push_back(newFunction); } break; case Types::Line: @@ -2386,10 +2478,10 @@ vector parser(vector> in) { } break; default: - error("This type should not be obtained in normal execution"); + error("This type should not be obtained in normal execution", "undefinedError"); break; } - } + } } out.push_back(newInst); } @@ -2416,7 +2508,7 @@ int main(int argc, char** argv) { argsList.val.push_back(lit); } variables["args"].val = argsList; - + ifstream file(argv[1]); string lns; string in; diff --git a/tests/error.grnd b/tests/error.grnd index bd32ab4..726464d 100644 --- a/tests/error.grnd +++ b/tests/error.grnd @@ -1 +1 @@ -error "Hello, world!" \ No newline at end of file +error "Hello, world!" "sillyError" diff --git a/tests/functions.grnd b/tests/functions.grnd index f5dd283..19c0f51 100644 --- a/tests/functions.grnd +++ b/tests/functions.grnd @@ -14,7 +14,7 @@ fun -bool !jumpy return true endfun -call !jumpy &tmp +!jumpy &tmp stdlnout "I called a function" diff --git a/tests/lists.grnd b/tests/lists.grnd index 8b56097..9f11630 100644 --- a/tests/lists.grnd +++ b/tests/lists.grnd @@ -1,5 +1,6 @@ # A cool list setlist *favWords "hello" "there" "general" "kenobi" +stdlnout *favWords set &count 0 set &passedThrough true diff --git a/tests/to1000.grnd b/tests/to1000.grnd index c31e64a..03aeb0b 100644 --- a/tests/to1000.grnd +++ b/tests/to1000.grnd @@ -1,5 +1,6 @@ set &var 0 +@jump add 1 $var &var stdlnout $var -greater 1000 $var &cond -if $cond %2 +greater 10000 $var &cond +if $cond %jump