From 2c84c1e22982bf7e7948da0d3e6ca40a6b0a7390 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Tue, 28 May 2019 18:22:07 +0200 Subject: [PATCH] Cleanup and fixes for boundscope --- src/Binder/Binder.cpp | 5 +- src/Binder/BoundVariables/BoundScope.cpp | 70 ++++++++++++++++++++++++ src/Binder/BoundVariables/BoundScope.hpp | 70 ++---------------------- 3 files changed, 80 insertions(+), 65 deletions(-) diff --git a/src/Binder/Binder.cpp b/src/Binder/Binder.cpp index 72852a1..28bc49b 100644 --- a/src/Binder/Binder.cpp +++ b/src/Binder/Binder.cpp @@ -46,7 +46,10 @@ BoundStatement *Binder::BindExpressionStatement(ParsedStatement *statement) { BoundStatement* Binder::BindAssignmentStatement(ParsedStatement *statement){ auto s = (ParsedAssignmentStatement*) statement; auto boundExpression = this->BindExpression(s->GetExpression()); - auto assignment = this->_scope->AssignVariable(s->GetIdentifier().GetHash(), boundExpression->GetType()); + VariableAssignment assignment = + s->IsLocal() ? + this->_scope->CreateExplicitLocal(s->GetIdentifier().GetHash(), boundExpression->GetType()) + : this->_scope->AssignVariable(s->GetIdentifier().GetHash(), boundExpression->GetType()); if (assignment.GetResult() == VariableAssignmentResult::Ok){ auto key = assignment.GetKey(); return new BoundAssignmentStatement(key, boundExpression); diff --git a/src/Binder/BoundVariables/BoundScope.cpp b/src/Binder/BoundVariables/BoundScope.cpp index 8f01473..49d70e9 100644 --- a/src/Binder/BoundVariables/BoundScope.cpp +++ b/src/Binder/BoundVariables/BoundScope.cpp @@ -1,2 +1,72 @@ #include "BoundScope.hpp" + +BoundScope::BoundScope(unordered_map *scriptScope) { + _scriptScope = scriptScope; + _currentScope = 1; + _localScope = vector>(1); +} + +BoundScope::~BoundScope() { + _localScope.clear(); +} + +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); + auto find = s.find(identifier); + if (find != s.end()){ + return find -> second; + } + return nullptr; + } +} + +VariableAssignment BoundScope::CreateExplicitLocal(int identifier, ScriptType *type) { + auto scope = this->_localScope.at(this->_currentScope); + 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, 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)); + } +} + + + diff --git a/src/Binder/BoundVariables/BoundScope.hpp b/src/Binder/BoundVariables/BoundScope.hpp index 6a7d3f3..28130e1 100644 --- a/src/Binder/BoundVariables/BoundScope.hpp +++ b/src/Binder/BoundVariables/BoundScope.hpp @@ -17,71 +17,13 @@ class BoundScope { vector> _localScope; int _currentScope; public: - explicit BoundScope(unordered_map *scriptScope){ - _scriptScope = scriptScope; - _currentScope = 1; - _localScope = vector>(1); - } - ~BoundScope(){ - _localScope.clear(); - } + explicit BoundScope(unordered_map *scriptScope); + ~BoundScope(); - int 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* 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); - auto find = s.find(identifier); - if (find != s.end()){ - return find -> second; - } - return nullptr; - } - } - - VariableAssignment CreateExplicitLocal(HashedString& identifier, ScriptType* type){ - auto scope = this->_localScope.at(this->_currentScope); - if (scope.find(identifier.GetHash()) != scope.end()){ - return VariableAssignment(VariableAssignmentResult::ExplicitLocalVariableExists, nullptr); - } - scope.insert({identifier.GetHash(), new BoundVariable(type)}); - return VariableAssignment(VariableAssignmentResult::Ok, new BoundVariableKey(identifier.GetHash(), this->_currentScope, true)); - } - - VariableAssignment AssignVariable(int identifier, 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)); - } - } + int Exists(int key); + BoundVariable* GetVariable(int scope, int identifier); + VariableAssignment CreateExplicitLocal(int identifier, ScriptType* type); + VariableAssignment AssignVariable(int identifier, ScriptType* type); };