Function declarations

This commit is contained in:
2025-08-13 09:40:03 +10:00
parent 52eadaa9c3
commit 4cd4d9080d
2 changed files with 104 additions and 16 deletions

View File

@@ -144,15 +144,6 @@ struct TypeRef {
struct FunctionRef { struct FunctionRef {
string fnName; string fnName;
}; };
/*
Function struct
Contains information needed to run a Ground function.
*/
struct Function {
int startPos;
Types returnType;
vector<pair<Direct, Types>> args;
};
/* /*
ListRef struct ListRef struct
@@ -187,12 +178,6 @@ map<string, List> lists;
*/ */
map<string, int> labels; map<string, int> labels;
/*
functions map
Contains the positions of functions and types of their values
*/
map<string, Function> functions;
/* /*
ValueRef struct ValueRef struct
If the program being executed makes a value reference, it is stored in a ValueRef If the program being executed makes a value reference, it is stored in a ValueRef
@@ -253,6 +238,22 @@ struct Instruction {
vector<variant<Literal, ValueRef, ListRef, FunctionRef, TypeRef, Direct, Line>> args; vector<variant<Literal, ValueRef, ListRef, FunctionRef, TypeRef, Direct, Line>> args;
}; };
/*
Function struct
Contains information needed to run a Ground function.
*/
struct Function {
Types returnType;
vector<pair<Direct, Types>> args;
vector<Instruction> instructions;
};
/*
functions map
Contains the code of functions and types of their values
*/
map<string, Function> functions;
/* /*
error function error function
Takes a string (which is a debug message) and prints it to the console, letting the Takes a string (which is a debug message) and prints it to the console, letting the
@@ -368,9 +369,23 @@ Types getType(string in) {
function below) and acts upon their properties. This is the main interpreter function below) and acts upon their properties. This is the main interpreter
function for the program. function for the program.
*/ */
bool processingFunction = false;
string procFnName = "";
void exec(vector<Instruction> in) { void exec(vector<Instruction> in) {
for (int i = 0; i < in.size(); i++) { for (int i = 0; i < in.size(); i++) {
Instruction l = in[i]; Instruction l = in[i];
if (processingFunction) {
if (l.inst == Instructions::Endfun) {
processingFunction = false;
procFnName = "";
continue;
} else {
functions[procFnName].instructions.push_back(l);
continue;
}
}
// Pre process value references and labels // Pre process value references and labels
for (int j = 0; j < l.args.size(); j++) { for (int j = 0; j < l.args.size(); j++) {
if (holds_alternative<ValueRef>(l.args[j])) { if (holds_alternative<ValueRef>(l.args[j])) {
@@ -1386,7 +1401,7 @@ void exec(vector<Instruction> in) {
} }
break; break;
/* /*
end instructoin end instruction
Ends execution of the code, eith the status code provided. Ends execution of the code, eith the status code provided.
*/ */
case Instructions::End: case Instructions::End:
@@ -1403,14 +1418,78 @@ void exec(vector<Instruction> in) {
error("First argument of end must be an int value"); error("First argument of end must be an int value");
} }
break; break;
/*
fun instruction
Allows functions to be defined.
*/
case Instructions::Fun: case Instructions::Fun:
if (l.args.size() < 3) {
error("Could not find all arguments required for Fun inbuilt");
}
{
Function newFunction;
if (holds_alternative<TypeRef>(l.args[0])) {
newFunction.returnType = get<TypeRef>(l.args[0]).type;
} else {
error("First argument of function must be a type reference");
}
string fnName;
if (holds_alternative<FunctionRef>(l.args[1])) {
fnName = get<FunctionRef>(l.args[1]).fnName;
} else {
error("Second argument of function must be a function reference");
}
Types argType;
Direct ref;
bool expectingType = true;
for (int m = 2; m < l.args.size(); m++) {
if (expectingType) {
if (holds_alternative<TypeRef>(l.args[m])) {
argType = get<TypeRef>(l.args[m]).type;
} else {
error("Functions expect a type reference, then a direct reference. Missing a type reference.");
}
} else {
if (holds_alternative<Direct>(l.args[m])) {
ref = get<Direct>(l.args[m]);
} else {
error("Functions expect a type reference, then a direct reference. Missing a direct reference.");
}
newFunction.args.push_back(pair(ref, argType));
}
expectingType = !expectingType;
}
if (!expectingType) {
error("Incomplete function definition, expecting a direct reference after type reference");
}
functions[fnName] = newFunction;
processingFunction = true;
procFnName = fnName;
}
break; break;
/*
return instruction
Exits a function.
*/
case Instructions::Return: case Instructions::Return:
break; break;
/*
endfun instruction
This should not be reached during normal execution.
*/
case Instructions::Endfun: case Instructions::Endfun:
error("No function is being defined. Cannot end function declaration here");
break; break;
case Instructions::Pusharg: case Instructions::Pusharg:
break; break;
case Instructions::Local:
break;
case Instructions::Call: case Instructions::Call:
break; break;
case Instructions::Use: case Instructions::Use:
@@ -1580,6 +1659,8 @@ vector<Instruction> parser(vector<vector<string>> in) {
else if (type == "double") newType.type = Types::Double; else if (type == "double") newType.type = Types::Double;
else if (type == "int") newType.type = Types::Int; else if (type == "int") newType.type = Types::Int;
else if (type == "bool") newType.type = Types::Bool; else if (type == "bool") newType.type = Types::Bool;
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.");
newInst.args.push_back(newType);
} }
break; break;
case Types::Function: case Types::Function:
@@ -1588,6 +1669,7 @@ vector<Instruction> parser(vector<vector<string>> in) {
newFunction.fnName = i.substr(1); newFunction.fnName = i.substr(1);
newInst.args.push_back(newFunction); newInst.args.push_back(newFunction);
} }
break;
case Types::Line: case Types::Line:
{ {
Line newLine; Line newLine;

6
tests/functions.grnd Normal file
View File

@@ -0,0 +1,6 @@
fun -int !dingle -string &silly
stdlnout &silly
return 10
endfun
stdlnout "This is outside the function"