forked from ground/ground
Experimental function jumping
This commit is contained in:
38
src/main.cpp
38
src/main.cpp
@@ -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 {
|
||||
|
Reference in New Issue
Block a user