From d8cc3ff9e04979b87c5d81d545e82e87e7dcb7c0 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Sat, 30 Aug 2025 13:05:28 +1000 Subject: [PATCH] Functions can return lists --- src/main.cpp | 32 ++++++++++++++++++++++++-------- tests/functions.grnd | 22 ++++++++++++++++++++++ 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index dfe5f29..44adebb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -434,7 +434,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") return true; + if (type == "string" || type == "char" || type == "bool" || type == "double" || type == "int" || type == "list") return true; else return false; } else return false; } @@ -1771,6 +1771,8 @@ Literal exec(vector in, bool executingFunction) { } 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"); } @@ -1792,8 +1794,10 @@ Literal exec(vector in, bool executingFunction) { } if (holds_alternative(l.args[0])) { fnArgs.push_back(get(l.args[0])); + } else if (holds_alternative(l.args[0])) { + fnArgs.push_back(variables[get(l.args[0]).listName]); } else { - error("First argument of pusharg must be a literal"); + error("First argument of pusharg must be a literal or list reference"); } break; /* @@ -1807,7 +1811,9 @@ Literal exec(vector in, bool executingFunction) { } FunctionRef ref; - Direct returnRef; + string returnRef; + + bool expectList = true; if (holds_alternative(l.args[0])) { ref = get(l.args[0]); @@ -1816,9 +1822,12 @@ Literal exec(vector in, bool executingFunction) { } if (holds_alternative(l.args[1])) { - returnRef = get(l.args[1]); + returnRef = get(l.args[1]).varName; + } else if (holds_alternative(l.args[1])) { + returnRef = get(l.args[1]).listName; + expectList = true; } else { - error("Second argument of call must be a direct reference"); + error("Second argument of call must be a direct reference or list reference"); } // Check for external function @@ -1841,7 +1850,7 @@ Literal exec(vector in, bool executingFunction) { // Clear arguments and store result fnArgs.clear(); - variables[returnRef.varName] = resultLit; + variables[returnRef] = resultLit; break; } @@ -1885,8 +1894,15 @@ Literal exec(vector in, bool executingFunction) { fnArgs.clear(); // Now, assign the return value in the current scope. - bool existed = variables.count(returnRef.varName) > 0; - variables[returnRef.varName] = retVal; + if (expectList) { + variables[returnRef] = retVal; + } else { + if (holds_alternative(retVal.val)) { + error("Expecting to output a normal literal to a normal literal"); + } else { + variables[returnRef] = retVal; + } + } } break; case Instructions::Use: diff --git a/tests/functions.grnd b/tests/functions.grnd index f97c379..f5dd283 100644 --- a/tests/functions.grnd +++ b/tests/functions.grnd @@ -17,3 +17,25 @@ endfun call !jumpy &tmp stdlnout "I called a function" + +# This function returns a list + +fun -list !dingus + stdlnout "Testing lists in functions" + setlist *dingle "heheheha" "hahahahe" "hmmm" + return *dingle +endfun + +call !dingus *outlist + +getlistsize *outlist &size +set &counter 0 +@loopstart +equal $size $counter &cond +if $cond %loopend +getlistat *outlist $counter &tmp +stdlnout $tmp +add 1 $counter &counter +jump %loopstart +@loopend +end 0