From 28a9e389faf4be2f106bf64a94ae80ec3f2caef6 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Mon, 18 Aug 2025 09:36:35 +1000 Subject: [PATCH] Basic function calling support --- src/main.cpp | 46 ++++++++++++++++++++++++++++++++++++-------- tests/functions.grnd | 6 +++++- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index d198867..7adeda2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -376,18 +376,20 @@ Types getType(string in) { return Types::Int; } +bool processingFunction = false; +string procFnName = ""; + +bool inFunction = false; + +// Forward declaration for the call instruction +Literal exec(vector in); + /* exec function This function takes a list of instructions (see Instruction struct above and parser function below) and acts upon their properties. This is the main interpreter function for the program. */ - -bool processingFunction = false; -string procFnName = ""; - -bool inFunction = false; - Literal exec(vector in) { for (int i = 0; i < in.size(); i++) { Instruction l = in[i]; @@ -1508,6 +1510,10 @@ Literal exec(vector in) { case Instructions::Endfun: error("No function is being defined. Cannot end function declaration here"); break; + /* + pusharg instruction + This instruction makes new arguments avaliable for functions. + */ case Instructions::Pusharg: if (l.args.size() < 1) { error("Could not find all arguments required for Endfun inbuilt"); @@ -1518,9 +1524,33 @@ Literal exec(vector in) { error("First argument of pusharg must be a literal"); } break; - case Instructions::Local: - break; + /* + call instruction + This instruction calls a function, and makes the arguments avaliable for it. + */ case Instructions::Call: + { + if (l.args.size() < 2) { + error("Could not find all arguments required for Call inbuilt"); + } + + FunctionRef ref; + Direct returnRef; + + if (holds_alternative(l.args[0])) { + ref = get(l.args[0]); + } else { + error("First argument of call must be a function reference"); + } + + if (holds_alternative(l.args[1])) { + returnRef = get(l.args[1]); + } else { + error("Second argument of call must be a direct reference"); + } + + variables[returnRef.varName] = exec(functions[ref.fnName].instructions); + } break; case Instructions::Use: break; diff --git a/tests/functions.grnd b/tests/functions.grnd index 906f18d..f99555c 100644 --- a/tests/functions.grnd +++ b/tests/functions.grnd @@ -1,6 +1,10 @@ fun -int !dingle -string &silly -stdlnout &silly +stdlnout "This is inside the function" return 10 endfun stdlnout "This is outside the function" + +call !dingle &var + +stdlnout $var