From 16660c6a8d8dcfe11006205d5a6a14fdb7e982d3 Mon Sep 17 00:00:00 2001 From: Maxwell Jeffress Date: Mon, 25 Aug 2025 13:35:22 +1000 Subject: [PATCH] More reliable scoping --- docs/writing-a-program | 0 docs/writing-a-program.md | 25 +++++++++++++ src/main.cpp | 77 +++------------------------------------ 3 files changed, 30 insertions(+), 72 deletions(-) create mode 100644 docs/writing-a-program create mode 100644 docs/writing-a-program.md diff --git a/docs/writing-a-program b/docs/writing-a-program new file mode 100644 index 0000000..e69de29 diff --git a/docs/writing-a-program.md b/docs/writing-a-program.md new file mode 100644 index 0000000..db4aa4f --- /dev/null +++ b/docs/writing-a-program.md @@ -0,0 +1,25 @@ +## Writing programs with Ground + +Ground is a very easy language to learn. In this guide, you will learn how to write a simple calculator in Ground, as well as best practices (which there aren't many of, since Ground is so simple). + +Note: This assumes you've read and understand the syntax.md document in this folder. + +### Let's start! + +Open a new file with the `.grnd` extension. Should look something like this: + +``` + +``` + +(Real empty in that file.) + +Let's add some code! Create a label for the start, since we'll loop back once we've calculated, and ask for the user's input: + +``` +@start +stdout "Calculation: " +stdin &calc +``` + +At the calc variable, we have whatever the user typed in. This should look something like `9+10`, `1 / 3` or who knows what else. But first we should organise this data. Let's create a loop to iterate through this input, and a counter to keep moving forward: diff --git a/src/main.cpp b/src/main.cpp index 0c970ef..ab1f522 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -269,12 +268,6 @@ map functions; */ vector fnArgs; -/* - localArgStack stack - This keeps track of all the local arguments in functions that are being called. -*/ -stack> localArgStack; - /* error function Takes a string (which is a debug message) and prints it to the console, letting the @@ -563,9 +556,6 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = varContents; - if (!localArgStack.empty() && !existed) { - localArgStack.top().push_back(varRef); - } } break; /* @@ -639,9 +629,6 @@ Literal exec(vector in, bool executingFunction) { 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); } @@ -695,9 +682,6 @@ Literal exec(vector in, bool executingFunction) { 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); } @@ -809,9 +793,6 @@ Literal exec(vector in, bool executingFunction) { 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); } @@ -850,9 +831,6 @@ Literal exec(vector in, bool executingFunction) { 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; } @@ -890,9 +868,6 @@ Literal exec(vector in, bool executingFunction) { 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"); } @@ -932,9 +907,6 @@ Literal exec(vector in, bool executingFunction) { 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"); } @@ -983,9 +955,6 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(ref.varName) > 0; variables[ref.varName] = newLit; - if (!localArgStack.empty() && !existed) { - localArgStack.top().push_back(ref); - } } break; @@ -1006,9 +975,6 @@ Literal exec(vector in, bool executingFunction) { userLit.val = userIn; 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"); } @@ -1069,9 +1035,6 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = final; - if (!localArgStack.empty() && !existed) { - localArgStack.top().push_back(varRef); - } } break; /* @@ -1122,9 +1085,6 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = final; - if (!localArgStack.empty() && !existed) { - localArgStack.top().push_back(varRef); - } } break; /* @@ -1175,9 +1135,6 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = final; - if (!localArgStack.empty() && !existed) { - localArgStack.top().push_back(varRef); - } } break; /* @@ -1240,9 +1197,6 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = final; - if (!localArgStack.empty() && !existed) { - localArgStack.top().push_back(varRef); - } } break; /* @@ -1299,9 +1253,6 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = final; - if (!localArgStack.empty() && !existed) { - localArgStack.top().push_back(varRef); - } } break; /* @@ -1358,9 +1309,6 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = final; - if (!localArgStack.empty() && !existed) { - localArgStack.top().push_back(varRef); - } } break; /* @@ -1394,9 +1342,6 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = boolean; - if (!localArgStack.empty() && !existed) { - localArgStack.top().push_back(varRef); - } } break; /* @@ -1453,9 +1398,6 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = final; - if (!localArgStack.empty() && !existed) { - localArgStack.top().push_back(varRef); - } } break; /* @@ -1512,9 +1454,6 @@ Literal exec(vector in, bool executingFunction) { bool existed = variables.count(varRef.varName) > 0; variables[varRef.varName] = final; - if (!localArgStack.empty() && !existed) { - localArgStack.top().push_back(varRef); - } } break; /* @@ -1704,7 +1643,8 @@ Literal exec(vector in, bool executingFunction) { " arguments, got " + to_string(fnArgs.size())); } - localArgStack.push(vector()); + // Create backup of variables to be restored + map scopeBackup = variables; // Create function arguments with type checking for (int m = 0; m < functions[ref.fnName].args.size(); m++) { @@ -1718,27 +1658,20 @@ Literal exec(vector in, bool executingFunction) { // Create the variable variables[arg.ref.varName] = fnArgs[m]; - localArgStack.top().push_back(arg.ref); } // Call the function Literal retVal = exec(functions[ref.fnName].instructions, true); - // Remove variables that were declared in this scope - for (Direct delref : localArgStack.top()) { - variables.erase(delref.varName); - } - localArgStack.pop(); - + // Restore scope + variables = scopeBackup; + // 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: