Experimental function jumping

This commit is contained in:
2025-08-24 16:30:42 +10:00
parent e9600d8500
commit 8da5a2bf93
2 changed files with 44 additions and 21 deletions

View File

@@ -252,6 +252,7 @@ struct Function {
Types returnType;
vector<FnArg> args;
vector<Instruction> instructions;
map<string, int> localLabels;
};
/*
@@ -410,7 +411,15 @@ Literal exec(vector<Instruction> in);
function below) and acts upon their properties. This is the main interpreter
function for the program.
*/
Literal exec(vector<Instruction> in) {
Literal exec(vector<Instruction> in, bool executingFunction) {
map<string, int>* currentLabels = &labels;
for (auto& [fnName, fn] : functions) {
if (&fn.instructions == &in) {
currentLabels = &fn.localLabels;
break;
}
}
for (int i = 0; i < in.size(); i++) {
Instruction l = in[i];
if (processingFunction) {
@@ -434,9 +443,9 @@ Literal exec(vector<Instruction> in) {
} else if (holds_alternative<Line>(l.args[j])) {
Line ln = get<Line>(l.args[j]);
if (ln.isLabel) {
if (labels.find(ln.label) != labels.end()) {
if (currentLabels->find(ln.label) != currentLabels->end()) {
Line newLine;
newLine.lineNum = labels[ln.label];
newLine.lineNum = (*currentLabels)[ln.label];
l.args[j] = newLine;
} else {
error("Could not find label " + ln.label);
@@ -1565,7 +1574,7 @@ Literal exec(vector<Instruction> in) {
Allows functions to be defined.
*/
case Instructions::Fun:
if (l.args.size() < 3) {
if (l.args.size() < 2) {
error("Could not find all arguments required for Fun inbuilt");
}
{
@@ -1705,7 +1714,7 @@ Literal exec(vector<Instruction> in) {
}
// Call the function
Literal retVal = exec(functions[ref.fnName].instructions);
Literal retVal = exec(functions[ref.fnName].instructions, true);
// Remove variables that were declared in this scope
for (Direct delref : localArgStack.top()) {
@@ -1822,12 +1831,14 @@ vector<vector<string>> lexer(string in) {
*/
vector<Instruction> parser(vector<vector<string>> in) {
vector<Instruction> out;
int lineNum = 1;
int functionInstructionIndex = 0;
for (vector<string> lineTokens : in) {
lineNum ++;
Instruction newInst;
if (lineTokens.empty()) {
if (processingFunction) functionInstructionIndex ++;
out.push_back(newInst);
continue;
};
@@ -1837,8 +1848,11 @@ vector<Instruction> parser(vector<vector<string>> in) {
if (firstInst) {
firstInst = false;
if (isLabel(i)) {
labels[i.substr(1)] = lineNum;
//out.push_back(newInst);
if (processingFunction) {
functions[procFnName].localLabels[i.substr(1)] = functionInstructionIndex;
} else {
labels[i.substr(1)] = lineNum;
}
continue;
}
else if (i == "stdin") newInst.inst = Instructions::Stdin;
@@ -1867,7 +1881,10 @@ vector<Instruction> parser(vector<vector<string>> in) {
else if (i == "stoi") newInst.inst = Instructions::Stoi;
else if (i == "stod") newInst.inst = Instructions::Stod;
else if (i == "tostring") newInst.inst = Instructions::Tostring;
else if (i == "fun") newInst.inst = Instructions::Fun;
else if (i == "fun") {
newInst.inst = Instructions::Fun;
functionInstructionIndex = 0;
}
else if (i == "return") newInst.inst = Instructions::Return;
else if (i == "endfun") newInst.inst = Instructions::Endfun;
else if (i == "pusharg") newInst.inst = Instructions::Pusharg;
@@ -1977,6 +1994,7 @@ vector<Instruction> parser(vector<vector<string>> in) {
}
}
}
if (processingFunction) functionInstructionIndex++;
out.push_back(newInst);
}
return out;
@@ -1999,7 +2017,7 @@ int main(int argc, char** argv) {
while (getline(file, lns)) {
in += lns += "\n";
}
Literal ret = exec(parser(lexer(in)));
Literal ret = exec(parser(lexer(in)), false);
if (holds_alternative<int>(ret.val)) {
return get<int>(ret.val);
} else {