#include "include/memory.h" #include "include/utils.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, CodePosition entry_pos, MemoryVar* fn) { Scope& top = scopes.back(); scopes.emplace_back(); scopes.back().depth = top.depth + 1; scopes.back().type = type; scopes.back().entry_pos = entry_pos; scopes.back().fn = fn; } 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]; } throw exception(); } Scope& Memory::get_function_scope(void) { for (auto rit = scopes.rbegin(); rit != scopes.rend(); ++rit) { Scope& scope = *rit; if (scope.type == ScopeType::Function) return scope; } throw exception(); } void Memory::declare(string identifier, Type type, CodePosition pos) { Scope& top = scopes.back(); top.vars[identifier].type = type; top.vars[identifier].declarationPos = pos; } 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; } } throw exception(); } Scope& Memory::_debug_top(void) { Scope& top = scopes.back(); return top; } void _debug_print_memory_var(MemoryVar var) { if (var.initialized && !holds_alternative(var.value)) { cout << " "; if (holds_alternative(var.value)) { cout << get(var.value); } else if (holds_alternative(var.value)) { cout << get(var.value); } else { cout << "{Unsupported}"; } } else { cout << setw (5) << "{}"; } } 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_get_type_type_name(it.second.type.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); } }