From e9600d8500a698a5c52627b6730ed35d9e550b51 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Sun, 24 Aug 2025 15:08:07 +1000 Subject: [PATCH] Scoping --- src/main.cpp | 144 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 114 insertions(+), 30 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 2444d5c..ed91d3f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -529,11 +529,11 @@ Literal exec(vector in) { error("Could not find all arguments required for Set inbuilt"); } { - string varName; + Direct varRef; Literal varContents; if (holds_alternative(l.args[0])) { - varName = get(l.args[0]).varName; + varRef = get(l.args[0]); } else { error("First argument of set must be a direct reference"); } @@ -543,7 +543,12 @@ Literal exec(vector in) { } else { error("Second argument of set must be a value (literal or value reference)"); } - variables[varName] = varContents; + + bool existed = variables.count(varRef.varName) > 0; + variables[varRef.varName] = varContents; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(varRef); + } } break; /* @@ -615,7 +620,11 @@ Literal exec(vector in) { if (lists.find(listref.listName) != lists.end()) { if (lists[listref.listName].val.size() > ref) { + bool existed = variables.count(var.varName) > 0; variables[var.varName] = lists[listref.listName].val[ref]; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(var); + } } else { error("Index " + to_string(ref) + " out of range of list " + listref.listName); } @@ -667,7 +676,11 @@ Literal exec(vector in) { if (instr.size() > ref) { Literal newLit; newLit.val = instr[ref]; + bool existed = variables.count(var.varName) > 0; variables[var.varName] = newLit; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(var); + } } else { error("Index " + to_string(ref) + " out of range of string " + instr); } @@ -777,7 +790,11 @@ Literal exec(vector in) { Literal newLit; if (lists.find(ref.listName) != lists.end()) { newLit.val = int(lists[ref.listName].val.size()); + bool existed = variables.count(var.varName) > 0; variables[var.varName] = newLit; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(var); + } } else { error("Couldn't find the list " + ref.listName); } @@ -814,7 +831,11 @@ Literal exec(vector in) { Literal newLit; newLit.val = int(ref.size()); + bool existed = variables.count(var.varName) > 0; variables[var.varName] = newLit; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(var); + } break; } @@ -850,7 +871,11 @@ Literal exec(vector in) { if (isInt(toConv)) { Literal newLit; newLit.val = stoi(toConv); + bool existed = variables.count(ref.varName) > 0; variables[ref.varName] = newLit; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(ref); + } } else { error("Cannot convert the value " + toConv + " to an int"); } @@ -888,7 +913,11 @@ Literal exec(vector in) { if (isDouble(toConv) || isInt(toConv)) { Literal newLit; newLit.val = stod(toConv); + bool existed = variables.count(ref.varName) > 0; variables[ref.varName] = newLit; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(ref); + } } else { error("Cannot convert the value " + toConv + " to a decimal"); } @@ -935,7 +964,11 @@ Literal exec(vector in) { } } + bool existed = variables.count(ref.varName) > 0; variables[ref.varName] = newLit; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(ref); + } } break; @@ -949,11 +982,16 @@ Literal exec(vector in) { error("Could not find all arguments required for Stdin inbuilt"); } if (holds_alternative(l.args[0])) { + Direct varRef = get(l.args[0]); string userIn; getline(cin, userIn); Literal userLit; userLit.val = userIn; - variables[get(l.args[0]).varName] = userLit; + bool existed = variables.count(varRef.varName) > 0; + variables[varRef.varName] = userLit; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(varRef); + } } else { error("First argument of stdin must be a direct reference"); } @@ -968,7 +1006,7 @@ Literal exec(vector in) { error("Could not find all arguments required for Add inbuilt"); } { - string varName; + Direct varRef; Literal left; Literal right; Literal final; @@ -986,7 +1024,7 @@ Literal exec(vector in) { } if (holds_alternative(l.args[2])) { - varName = get(l.args[2]).varName; + varRef = get(l.args[2]); } else { error("Third argument of add must be a direct reference"); } @@ -1012,7 +1050,11 @@ Literal exec(vector in) { error("Cannot add those two values"); } - variables[varName] = final; + bool existed = variables.count(varRef.varName) > 0; + variables[varRef.varName] = final; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(varRef); + } } break; /* @@ -1025,7 +1067,7 @@ Literal exec(vector in) { error("Could not find all arguments required for Subtract inbuilt"); } { - string varName; + Direct varRef; Literal left; Literal right; Literal final; @@ -1043,7 +1085,7 @@ Literal exec(vector in) { } if (holds_alternative(l.args[2])) { - varName = get(l.args[2]).varName; + varRef = get(l.args[2]); } else { error("Third argument of subtract must be a direct reference"); } @@ -1061,7 +1103,11 @@ Literal exec(vector in) { error("Cannot subtract those two values"); } - variables[varName] = final; + bool existed = variables.count(varRef.varName) > 0; + variables[varRef.varName] = final; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(varRef); + } } break; /* @@ -1074,7 +1120,7 @@ Literal exec(vector in) { error("Could not find all arguments required for Multiply inbuilt"); } { - string varName; + Direct varRef; Literal left; Literal right; Literal final; @@ -1092,7 +1138,7 @@ Literal exec(vector in) { } if (holds_alternative(l.args[2])) { - varName = get(l.args[2]).varName; + varRef = get(l.args[2]); } else { error("Third argument of multiply must be a direct reference"); } @@ -1110,7 +1156,11 @@ Literal exec(vector in) { error("Cannot multiply those two values"); } - variables[varName] = final; + bool existed = variables.count(varRef.varName) > 0; + variables[varRef.varName] = final; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(varRef); + } } break; /* @@ -1123,7 +1173,7 @@ Literal exec(vector in) { error("Could not find all arguments required for Divide inbuilt"); } { - string varName; + Direct varRef; Literal left; Literal right; Literal final; @@ -1141,7 +1191,7 @@ Literal exec(vector in) { } if (holds_alternative(l.args[2])) { - varName = get(l.args[2]).varName; + varRef = get(l.args[2]); } else { error("Third argument of divide must be a direct reference"); } @@ -1171,7 +1221,11 @@ Literal exec(vector in) { error("Cannot divide those two values"); } - variables[varName] = final; + bool existed = variables.count(varRef.varName) > 0; + variables[varRef.varName] = final; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(varRef); + } } break; /* @@ -1184,7 +1238,7 @@ Literal exec(vector in) { error("Could not find all arguments required for Equal inbuilt"); } { - string varName; + Direct varRef; Literal left; Literal right; Literal final; @@ -1202,7 +1256,7 @@ Literal exec(vector in) { } if (holds_alternative(l.args[2])) { - varName = get(l.args[2]).varName; + varRef = get(l.args[2]); } else { error("Third argument of equal must be a direct reference"); } @@ -1226,7 +1280,11 @@ Literal exec(vector in) { error("Cannot equal those two values"); } - variables[varName] = final; + bool existed = variables.count(varRef.varName) > 0; + variables[varRef.varName] = final; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(varRef); + } } break; /* @@ -1239,7 +1297,7 @@ Literal exec(vector in) { error("Could not find all arguments required for Inequal inbuilt"); } { - string varName; + Direct varRef; Literal left; Literal right; Literal final; @@ -1257,7 +1315,7 @@ Literal exec(vector in) { } if (holds_alternative(l.args[2])) { - varName = get(l.args[2]).varName; + varRef = get(l.args[2]); } else { error("Third argument of inequal must be a direct reference"); } @@ -1281,7 +1339,11 @@ Literal exec(vector in) { error("Cannot inequal those two values"); } - variables[varName] = final; + bool existed = variables.count(varRef.varName) > 0; + variables[varRef.varName] = final; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(varRef); + } } break; /* @@ -1295,6 +1357,7 @@ Literal exec(vector in) { { Literal boolean; + Direct varRef; if (holds_alternative(l.args[0])) { if (holds_alternative(get(l.args[0]).val)) { @@ -1307,10 +1370,16 @@ Literal exec(vector in) { } if (holds_alternative(l.args[1])) { - variables[get(l.args[1]).varName] = boolean; + varRef = get(l.args[1]); } else { error("Second argument of not must be a direct reference"); } + + bool existed = variables.count(varRef.varName) > 0; + variables[varRef.varName] = boolean; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(varRef); + } } break; /* @@ -1323,7 +1392,7 @@ Literal exec(vector in) { error("Could not find all arguments required for Greater inbuilt"); } { - string varName; + Direct varRef; Literal left; Literal right; Literal final; @@ -1341,7 +1410,7 @@ Literal exec(vector in) { } if (holds_alternative(l.args[2])) { - varName = get(l.args[2]).varName; + varRef = get(l.args[2]); } else { error("Third argument of greater must be a direct reference"); } @@ -1365,7 +1434,11 @@ Literal exec(vector in) { error("Cannot greater those two values"); } - variables[varName] = final; + bool existed = variables.count(varRef.varName) > 0; + variables[varRef.varName] = final; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(varRef); + } } break; /* @@ -1378,7 +1451,7 @@ Literal exec(vector in) { error("Could not find all arguments required for Lesser inbuilt"); } { - string varName; + Direct varRef; Literal left; Literal right; Literal final; @@ -1396,7 +1469,7 @@ Literal exec(vector in) { } if (holds_alternative(l.args[2])) { - varName = get(l.args[2]).varName; + varRef = get(l.args[2]); } else { error("Third argument of lesser must be a direct reference"); } @@ -1420,7 +1493,11 @@ Literal exec(vector in) { error("Cannot lesser those two values"); } - variables[varName] = final; + bool existed = variables.count(varRef.varName) > 0; + variables[varRef.varName] = final; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(varRef); + } } break; /* @@ -1628,7 +1705,7 @@ Literal exec(vector in) { } // Call the function - variables[returnRef.varName] = exec(functions[ref.fnName].instructions); + Literal retVal = exec(functions[ref.fnName].instructions); // Remove variables that were declared in this scope for (Direct delref : localArgStack.top()) { @@ -1638,6 +1715,13 @@ Literal exec(vector in) { // Clear function arguments for next call fnArgs.clear(); + + // Now, assign the return value in the current scope. + bool existed = variables.count(returnRef.varName) > 0; + variables[returnRef.varName] = retVal; + if (!localArgStack.empty() && !existed) { + localArgStack.top().push_back(returnRef); + } } break; case Instructions::Use: