2023-12-08 15:29:30 +01:00
|
|
|
#include "include/memory.h"
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
Memory::Memory(void) {
|
|
|
|
scopes.emplace_back();
|
|
|
|
scopes.back().depth = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Memory::contains(string identifier) {
|
|
|
|
for (auto rit = scopes.rbegin(); rit != scopes.rend(); ++rit) {
|
|
|
|
Scope& scope = *rit;
|
|
|
|
if (scope.vars.contains(identifier)) return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Memory::contains_top(string identifier) {
|
|
|
|
Scope& top = scopes.back();
|
|
|
|
return top.vars.contains(identifier);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Memory::add_scope(ScopeType type) {
|
|
|
|
Scope& top = scopes.back();
|
|
|
|
scopes.emplace_back();
|
|
|
|
scopes.back().depth = top.depth + 1;
|
|
|
|
scopes.back().type = type;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Memory::remove_scope(void) {
|
|
|
|
scopes.pop_back();
|
|
|
|
}
|
|
|
|
|
|
|
|
MemoryVar& Memory::get(string identifier) {
|
|
|
|
for (auto rit = scopes.rbegin(); rit != scopes.rend(); ++rit) {
|
|
|
|
Scope& scope = *rit;
|
|
|
|
if (scope.vars.contains(identifier)) return scope.vars[identifier];
|
|
|
|
}
|
|
|
|
|
2023-12-09 11:41:14 +01:00
|
|
|
throw exception();
|
2023-12-08 15:29:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Memory::declare(string identifier, Type type) {
|
|
|
|
Scope& top = scopes.back();
|
|
|
|
top.vars[identifier].type = type;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Memory::update(string identifier, EvalResult value) {
|
|
|
|
for (auto rit = scopes.rbegin(); rit != scopes.rend(); ++rit) {
|
|
|
|
Scope& scope = *rit;
|
|
|
|
if (scope.vars.contains(identifier)) {
|
|
|
|
scope.vars[identifier].value = value;
|
|
|
|
scope.vars[identifier].initialized = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-09 11:41:14 +01:00
|
|
|
throw exception();
|
2023-12-08 15:29:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Scope& Memory::_debug_top(void) {
|
|
|
|
Scope& top = scopes.back();
|
|
|
|
return top;
|
2023-12-09 12:27:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void _debug_print_memory_var(MemoryVar var) {
|
|
|
|
if (var.initialized && !holds_alternative<monostate>(var.value)) {
|
|
|
|
cout << " ";
|
|
|
|
if (holds_alternative<int>(var.value)) {
|
|
|
|
cout << get<int>(var.value);
|
|
|
|
} else if (holds_alternative<double>(var.value)) {
|
|
|
|
cout << get<double>(var.value);
|
|
|
|
} else {
|
|
|
|
cout << "{Unsupported}";
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
cout << setw (5) << "{}";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* _debug_type_names[] = {
|
|
|
|
"Int", "Double"
|
|
|
|
};
|
|
|
|
|
|
|
|
void _debug_print_scope(Scope scope) {
|
|
|
|
for (auto it : scope.vars) {
|
|
|
|
if (it.first.length() > 6) {
|
|
|
|
cout << it.first.substr(0, 6) << "..";
|
|
|
|
} else {
|
|
|
|
cout << setw (6) << it.first << " ";
|
|
|
|
}
|
|
|
|
cout << "|";
|
|
|
|
cout << setw (7) << _debug_type_names[int(it.second.type)] << " |";
|
|
|
|
|
|
|
|
_debug_print_memory_var(it.second);
|
|
|
|
cout << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Memory::_debug_print(void) {
|
|
|
|
cout << BOLD " Name | Type | Value" RESET << endl;
|
|
|
|
for (auto rit = scopes.rbegin(); rit != scopes.rend(); ++rit) {
|
|
|
|
Scope& scope = *rit;
|
|
|
|
if (rit != scopes.rbegin()) {
|
|
|
|
cout << " --- New Scope ---" << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
_debug_print_scope(scope);
|
|
|
|
}
|
2023-12-08 15:29:30 +01:00
|
|
|
}
|