96 lines
2.9 KiB
C++
96 lines
2.9 KiB
C++
|
|
#include "BoundScope.hpp"
|
|
|
|
BoundScope::BoundScope(unordered_map<int, BoundVariable *> *scriptScope) {
|
|
_scriptScope = scriptScope;
|
|
_currentScope = 1;
|
|
_deepestScope = 1;
|
|
auto localUpmostScope = new unordered_map<int, BoundVariable*>();
|
|
_localScope.push_back(localUpmostScope);
|
|
}
|
|
|
|
BoundScope::~BoundScope() {
|
|
for (auto scope : _localScope){
|
|
for (auto v : *scope){
|
|
delete v.second;
|
|
}
|
|
delete scope;
|
|
}
|
|
}
|
|
|
|
void BoundScope::GoInnerScope() {
|
|
_currentScope++;
|
|
if (_localScope.size() < _currentScope){
|
|
auto innerScope = new unordered_map<int, BoundVariable*>();
|
|
_localScope.push_back(innerScope);
|
|
}
|
|
if (_deepestScope < _currentScope){
|
|
_deepestScope = _currentScope;
|
|
}
|
|
}
|
|
|
|
void BoundScope::GoOuterScope() {
|
|
_localScope[_currentScope - 1]->clear();
|
|
_currentScope--;
|
|
}
|
|
|
|
int BoundScope::Exists(int key) {
|
|
auto found = this -> _scriptScope -> find(key);
|
|
if (found != _scriptScope -> end()){
|
|
return 0;
|
|
}
|
|
for (int i = _currentScope - 1; i >= 0; i--){
|
|
auto scope = _localScope.at(i);
|
|
found = scope -> find(key);
|
|
if (found != scope -> end()){
|
|
return i + 1;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
BoundVariable *BoundScope::GetVariable(int scope, int identifier) {
|
|
if (scope == 0){
|
|
auto find = this -> _scriptScope->find(identifier);
|
|
if (find != _scriptScope->end()){
|
|
return find -> second;
|
|
}
|
|
return nullptr;
|
|
} else{
|
|
auto s = this->_localScope.at(scope - 1);
|
|
auto find = s -> find(identifier);
|
|
if (find != s -> end()){
|
|
return find -> second;
|
|
}
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
VariableAssignment BoundScope::CreateExplicitLocal(int identifier, const ScriptType& type) {
|
|
auto scope = this->_localScope.at(this->_currentScope - 1);
|
|
if (scope -> find(identifier) != scope -> end()){
|
|
return VariableAssignment(VariableAssignmentResult::ExplicitLocalVariableExists, nullptr);
|
|
}
|
|
scope -> insert({identifier, new BoundVariable(type)});
|
|
return VariableAssignment(VariableAssignmentResult::Ok, new BoundVariableKey(identifier, this->_currentScope, true));
|
|
}
|
|
|
|
VariableAssignment BoundScope::AssignVariable(int identifier, const ScriptType& type) {
|
|
int exists = this->Exists(identifier);
|
|
if (exists == -1){
|
|
// Creation
|
|
_scriptScope->insert({identifier, new BoundVariable(type)});
|
|
return VariableAssignment(VariableAssignmentResult::Ok, new BoundVariableKey(identifier, 0, true));
|
|
} else{
|
|
// Assigning
|
|
auto var = this->GetVariable(exists, identifier);
|
|
if (var->GetType() != type){
|
|
return VariableAssignment(VariableAssignmentResult::VariableDefinedWithDifferentType, nullptr);
|
|
}
|
|
return VariableAssignment(VariableAssignmentResult::Ok, new BoundVariableKey(identifier, exists, false));
|
|
}
|
|
}
|
|
|
|
|
|
|