Chapter 6: Variable Store - The Program’s Memory
In the previous chapter, Chapter 5: Language Logic Unit (ALGO), we saw how the ALGO unit acts like a toolbox, performing specific actions like displaying text or calculating math problems. We noticed that ALGO often needed to remember pieces of information (like the value of Age
) or store results. But how does it remember? Where does that information go?
That’s the job of our final component: the Variable Store.
What’s the Point? The Program’s Whiteboard
Imagine you’re solving a math problem on a whiteboard. You might write down intermediate results or definitions. For example:
- Let
x = 5
- Let
y = 10
- Calculate
x + y
… (You look upx
andy
on the board) … Result is 15.
Your program needs a similar place to keep track of named pieces of data that can change. This “whiteboard” is the Variable Store.
Its main purpose is to:
- Remember Values: Store the connection between a name (like
Age
) and its current value (like"25"
). - Retrieve Values: Look up a name and find the value associated with it.
- Update Values: Change the value associated with a name if the program asks.
Use Case: Let’s say your Hyperbole code is:
declare Name : "Bob"; // Store "Bob" under the name "Name"
display "Hello, ";
display Name; // Look up "Name" and display its value
The Variable Store is what allows the program to remember that Name
holds the value "Bob"
between the first line and the last line. Without it, the program would have no memory!
Key Concepts: How the Whiteboard Works
- Name-Value Pairs: The Variable Store primarily works with pairs of information: a variable name (like
MyScore
) and its corresponding value (like"100"
). Think of it like a dictionary where the word is the name and the definition is the value. - String Storage: In Hyperbole’s Variable Store (
variable.h
), all values are stored as text (strings). Even if you store the number25
, it’s kept as the string"25"
. The Language Logic Unit (ALGO) handles converting this text to a number when needed for calculations. - The Map: Under the hood, the Variable Store uses a data structure called a
map
(specificallystd::map
in C++). A map is very efficient at looking up a value if you know its key (the variable name).variables: { "Name": "Bob", "Age": "25", "Score": "100" }
- Setting Values (
set_value
): When the code saysdeclare X : 10
orX = Y + 5
, the Language Logic Unit (ALGO) ultimately tells the Variable Store to set a value. This involves:- Checking if the variable name is valid (e.g., starts with a letter, contains only letters, numbers, or underscore).
- If the name is valid, adding the name-value pair to the map. If the name already exists, its value is updated.
- Getting Values (
get_value
): When the code needs the value of a variable (like indisplay X
orZ = X + 1
), ALGO asks the Variable Store to get the value associated with the nameX
.- The Variable Store looks for
X
in its map. - If found, it returns the stored value (e.g.,
"10"
). - If not found (maybe the variable was never declared), it returns a special signal (
"\0"
) to indicate an error.
- The Variable Store looks for
- Error Tracking: The Variable Store keeps its own list of errors, mostly related to invalid variable names. If you try to use a name like
123Invalid
, theset_value
function will record an error.
Using the Variable Store (via ALGO)
You don’t interact with the Variable Store directly from your Hyperbole code. Instead, the Language Logic Unit (ALGO) uses it behind the scenes. Remember from Chapter 5 that the ALGO object (alg
) has a pointer (varib
) to the Variable Store object (var
) created by the Execution Engine.
Let’s trace declare Age : 25;
again:
- Engine sees
declare
: The Execution Engine callsalg.declare()
. - ALGO calls
set_value
(initial): Thedeclare()
function in ALGO finds the nameAge
. It might initially callvarib->set_value("Age", "declared")
to register the name.// --- Simplified inside algo::declare() --- string variable_name = "Age"; string initial_status = "declared"; varib->set_value(variable_name, initial_status); // Tell Variable Store about "Age"
- Engine sees assignment logic (implied): The part
: 25
is handled by assignment logic, often viaalg.expression()
. - ALGO calculates value:
alg.expression()
figures out the value is25
. - ALGO calls
set_value
(update): ALGO converts25
to the string"25"
and calls the Variable Store again:// --- Simplified inside algo::expression() after calculating --- string variable_name = "Age"; string calculated_value = "25"; // Value computed and converted to string varib->set_value(variable_name, calculated_value); // Update "Age" in Variable Store
Now, let’s trace display Age;
:
- Engine sees
display
: Callsalg.display()
. - ALGO calls
get_value
: Thedisplay()
function in ALGO sees it needs the value ofAge
. It asks the Variable Store:// --- Simplified inside algo::display() --- string variable_name = "Age"; string value = varib->get_value(variable_name); // Ask Variable Store for "Age"'s value if (value != "\0") { // Check if found cout << value; // Print the value ("25") } else { // Handle error: variable not found }
- Variable Store Looks Up: The Variable Store finds
Age
in its internal map and returns the associated value"25"
. - ALGO Prints: ALGO receives
"25"
and prints it to the screen.
Under the Hood: Inside the Store
How does the Variable Store actually perform these set
and get
operations?
Step-by-Step Flow:
- ALGO calls
set_value("Age", "25")
: ALGO requests to store the value “25” for the variable “Age”. - Variable Store Validates Name: The
set_value
function first checks if “Age” is a valid name (starts with letter, etc.). In this case, it is. - Variable Store Accesses Map: It looks inside its internal
map<string, string> variables
. - Variable Store Checks Existence: Does an entry for “Age” already exist?
- If Yes: It updates the value associated with the key “Age” to the new value “25”.
- If No: It inserts a new pair:
"Age"
(key) and"25"
(value) into the map.
-
Return: The function finishes. (If validation failed, it adds an error message to its
errors
string). - ALGO calls
get_value("Age")
: ALGO requests the value associated with “Age”. - Variable Store Accesses Map: It looks inside its internal
map<string, string> variables
. - Variable Store Finds Key: It searches for the key “Age”.
- Variable Store Returns Value:
- If Found: It retrieves the associated value (“25”) and returns it to ALGO.
- If Not Found: It returns the special signal
"\0"
to ALGO.
Visualizing the Interaction:
sequenceDiagram
participant Algo as Language Logic Unit (algo.h)
participant VarStore as Variable Store (variable.h)
participant IntMap as Internal variables Map
Algo->>VarStore: Calls set_value("Age", "25")
VarStore->>VarStore: Validate name "Age" (OK)
VarStore->>IntMap: Access map
VarStore->>IntMap: Check if key "Age" exists
alt Key "Age" Exists
IntMap->>VarStore: Confirms existence
VarStore->>IntMap: Update map["Age"] = "25"
else Key "Age" Does Not Exist
IntMap->>VarStore: Confirms non-existence
VarStore->>IntMap: Insert {"Age": "25"} into map
end
VarStore-->>Algo: set_value() finishes
Algo->>VarStore: Calls get_value("Age")
VarStore->>IntMap: Access map
VarStore->>IntMap: Find key "Age"
IntMap-->>VarStore: Return associated value "25"
VarStore-->>Algo: Return value "25"
Code Dive: Inside variable.h
Let’s look at the code that makes this happen.
-
The Storage (
variable.h
): The core storage is themap
. It also has a string to collect errors.// --- From variable.h --- #include<map> #include<string> // ... other includes ... using namespace std; class variable{ public: // The map holding variable names (string) and their values (string) map<string, string> variables; // A string to store any error messages encountered string errors = ""; // Function to set a variable's value bool set_value(string &key, string &value); // Function to get a variable's value string get_value(string key); // Function to display collected errors void show_errors(); };
This defines the structure: a map named
variables
and anerrors
string, along with the functions to interact with them. -
Setting a Value (
variable::set_value
): This function validates the name (key
) and then updates or inserts into the map.// --- Simplified from variable::set_value in variable.h --- bool variable::set_value(string &key, string &value) { // --- Basic Name Validation --- bool invalid_name = false; if (!isalpha(key[0])) { // Must start with a letter? invalid_name = true; } else { for (char c : key) { // Check each character if (!(isalpha(c) || isdigit(c) || c == '_')) { invalid_name = true; // Invalid character found break; } } } if (invalid_name) { errors += key + " is an illegal name for a variable;"; // Optional: return false or decide not to set return false; // Indicate failure (or just record error and proceed) } // --- End Validation --- // Check if the key already exists in the map map<string, string>::iterator it = variables.find(key); if (it != variables.end()) { // Key exists, update its value variables[key] = value; // Or it->second = value; } else { // Key doesn't exist, insert a new pair variables.insert({key, value}); } return true; // Indicate success }
Self-Correction: The original code used a loop to check existence, but
map::find
is more direct. Simplified validation shown here. It checks the name, adds an error if needed, and then usesfind
to see if the key exists. It updates the value if found or inserts a new pair if not. -
Getting a Value (
variable::get_value
): This function searches the map for the key and returns the value or"\0"
.// --- Simplified from variable::get_value in variable.h --- string variable::get_value(string key) { // Use map::find to efficiently search for the key map<string, string>::iterator it = variables.find(key); if (it != variables.end()) { // Key was found! Return the associated value. // (The original code checks if value is "\0" but typically // we just return the found value directly here). return it->second; // it->second is the value stored in the map } else { // Key was not found in the map. // Return the special signal "\0" to indicate "not found". return "\0"; } }
This uses
map::find
to locate the variable name (key
). Iffind
returns an iterator pointing to the end of the map (variables.end()
), the key wasn’t found. Otherwise,it->second
gives the stored string value. -
Showing Errors (
variable::show_errors
): This function is called by the Execution Engine at the end to print any errors collected by the Variable Store.// --- Simplified from variable::show_errors in variable.h --- void variable::show_errors() { if (!errors.empty()) { // Only print if there are errors cout << "\n--- Variable Store Errors ---" << endl; string current_error; for (char c : errors) { // Loop through the error string if (c == ';') { // Semicolon separates error messages cout << "- " << current_error << endl; current_error = ""; // Reset for the next message } else { current_error += c; // Build the current message } } // Print any remaining part if errors don't end with ; if (!current_error.empty()) { cout << "- " << current_error << endl; } cout << "----------------------------\n"; } }
It loops through the
errors
string, printing each message separated by semicolons.
Conclusion
The Variable Store is the program’s memory, its whiteboard. It uses a map
to efficiently store and retrieve connections between variable names and their string values. It provides essential set_value
and get_value
functions used heavily by the Language Logic Unit (ALGO) to manage data during program execution. It also performs basic validation on variable names and reports any related errors.
This concludes our tour of the main components of the hyperbole
interpreter! We’ve seen how:
- The IDE Shell welcomes you and directs traffic.
- The Source Code Handler reads and parses your code into the
lol
structure. - The Help System provides built-in documentation.
- The Execution Engine reads the
lol
structure and conducts the execution. - The Language Logic Unit (ALGO) performs the specific actions of the Hyperbole language.
- The Variable Store remembers the data your program uses.
Together, these pieces form a simple but complete system for running Hyperbole code. Hopefully, this journey through the “factory” has given you a clear understanding of how each part contributes to the whole process!
Generated by AI Codebase Knowledge Builder