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

View File

@@ -1,14 +1,19 @@
fun -int !dingle -string &silly fun -bool !jumpy
stdlnout "This is inside the function" stdlnout "This is the jumpy function"
stdout "The function argument is " set &counter 0
stdlnout $silly jump %inloop
return 10 @jumpback
stdlnout "Yay I jumped!"
@inloop
add 1 $counter &counter
inequal 10 $counter &out
stdout "Condition is"
stdlnout $out
if $out %jumpback
stdlnout "Finished"
return true
endfun endfun
stdlnout "This is outside the function" call !jumpy &tmp
pusharg "heheheha" stdlnout "I called a function"
call !dingle &var
stdout "Function returned "
stdlnout $var