diff --git a/src/Binder/Binder.cpp b/src/Binder/Binder.cpp index 28bc49b..303cbf8 100644 --- a/src/Binder/Binder.cpp +++ b/src/Binder/Binder.cpp @@ -32,9 +32,11 @@ BoundStatement* Binder::BindStatement(ParsedStatement* statement){ BoundStatement *Binder::BindBlockStatement(ParsedStatement *statement) { auto statements = ((ParsedBlockStatement*)statement)->GetStatements(); vector boundStatements (statements.size()); + this->_scope->GoInnerScope(); for (int i = 0; i < statements.size(); i++){ boundStatements[i] = this -> BindStatement(statements[i]); } + this->_scope->GoOuterScope(); return new BoundBlockStatement(boundStatements); } @@ -48,8 +50,8 @@ BoundStatement* Binder::BindAssignmentStatement(ParsedStatement *statement){ auto boundExpression = this->BindExpression(s->GetExpression()); VariableAssignment assignment = s->IsLocal() ? - this->_scope->CreateExplicitLocal(s->GetIdentifier().GetHash(), boundExpression->GetType()) - : this->_scope->AssignVariable(s->GetIdentifier().GetHash(), boundExpression->GetType()); + 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 49d70e9..289adff 100644 --- a/src/Binder/BoundVariables/BoundScope.cpp +++ b/src/Binder/BoundVariables/BoundScope.cpp @@ -4,11 +4,34 @@ BoundScope::BoundScope(unordered_map *scriptScope) { _scriptScope = scriptScope; _currentScope = 1; - _localScope = vector>(1); + _deepestScope = 1; + auto localUpmostScope = new unordered_map(); + _localScope.push_back(localUpmostScope); } BoundScope::~BoundScope() { - _localScope.clear(); + 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(); + _localScope.push_back(innerScope); + } + if (_deepestScope < _currentScope){ + _deepestScope = _currentScope; + } +} + +void BoundScope::GoOuterScope() { + _localScope[_currentScope - 1]->clear(); + _currentScope--; } int BoundScope::Exists(int key) { @@ -18,8 +41,8 @@ int BoundScope::Exists(int key) { } for (int i = _currentScope - 1; i >= 0; i--){ auto scope = _localScope.at(i); - found = scope.find(key); - if (found != scope.end()){ + found = scope -> find(key); + if (found != scope -> end()){ return i + 1; } } @@ -35,24 +58,24 @@ BoundVariable *BoundScope::GetVariable(int scope, int identifier) { return nullptr; } else{ auto s = this->_localScope.at(scope); - auto find = s.find(identifier); - if (find != s.end()){ + auto find = s -> find(identifier); + if (find != s -> end()){ return find -> second; } return nullptr; } } -VariableAssignment BoundScope::CreateExplicitLocal(int identifier, ScriptType *type) { +VariableAssignment BoundScope::CreateExplicitLocal(int identifier, const ScriptType& type) { auto scope = this->_localScope.at(this->_currentScope); - if (scope.find(identifier) != scope.end()){ + if (scope -> find(identifier) != scope -> end()){ return VariableAssignment(VariableAssignmentResult::ExplicitLocalVariableExists, nullptr); } - scope.insert({identifier, new BoundVariable(type)}); + scope -> insert({identifier, new BoundVariable(type)}); return VariableAssignment(VariableAssignmentResult::Ok, new BoundVariableKey(identifier, this->_currentScope, true)); } -VariableAssignment BoundScope::AssignVariable(int identifier, ScriptType *type) { +VariableAssignment BoundScope::AssignVariable(int identifier, const ScriptType& type) { int exists = this->Exists(identifier); if (exists == -1){ // Creation diff --git a/src/Binder/BoundVariables/BoundScope.hpp b/src/Binder/BoundVariables/BoundScope.hpp index 28130e1..02faf3a 100644 --- a/src/Binder/BoundVariables/BoundScope.hpp +++ b/src/Binder/BoundVariables/BoundScope.hpp @@ -14,16 +14,20 @@ using namespace std; class BoundScope { unordered_map* _scriptScope; - vector> _localScope; + vector*> _localScope; int _currentScope; + int _deepestScope; public: explicit BoundScope(unordered_map *scriptScope); ~BoundScope(); + void GoInnerScope(); + void GoOuterScope(); + int Exists(int key); BoundVariable* GetVariable(int scope, int identifier); - VariableAssignment CreateExplicitLocal(int identifier, ScriptType* type); - VariableAssignment AssignVariable(int identifier, ScriptType* type); + VariableAssignment CreateExplicitLocal(int identifier, const ScriptType& type); + VariableAssignment AssignVariable(int identifier, const ScriptType& type); }; diff --git a/src/Binder/BoundVariables/BoundVariable.hpp b/src/Binder/BoundVariables/BoundVariable.hpp index b47c18b..295559c 100644 --- a/src/Binder/BoundVariables/BoundVariable.hpp +++ b/src/Binder/BoundVariables/BoundVariable.hpp @@ -5,16 +5,14 @@ #include "../../ScriptType.hpp" class BoundVariable{ - ScriptType* _type; + ScriptType _type; public: - explicit BoundVariable(ScriptType* type){ - _type = type; + explicit BoundVariable(ScriptType type) : _type(type){ } ~BoundVariable(){ - delete _type; } - ScriptType* GetType(){ + ScriptType& GetType(){ return _type; } }; diff --git a/src/ScriptType.hpp b/src/ScriptType.hpp index 1275122..5240e84 100644 --- a/src/ScriptType.hpp +++ b/src/ScriptType.hpp @@ -20,9 +20,19 @@ public: _class = c; } + virtual ~ScriptType() = default; + const TypeClass GetClass(){ return _class; } + + virtual bool operator ==(ScriptType b){ + return _class == b._class; + }; + + virtual bool operator !=(ScriptType b){ + return ! (operator==(b)); + } }; class NumericScriptType : public ScriptType{ diff --git a/tests/integration/Variables.cpp b/tests/integration/Variables.cpp index daa9806..6b0bace 100644 --- a/tests/integration/Variables.cpp +++ b/tests/integration/Variables.cpp @@ -7,6 +7,7 @@ TEST_CASE( "Create script variable", "[integration]" ) { REQUIRE(!script->Diagnostics -> HasErrors()); auto variable = script->GetVariable("foo"); REQUIRE(variable == nullptr); + delete script; }