Cleanup and fixes for boundscope

This commit is contained in:
Deukhoofd 2019-05-28 18:22:07 +02:00
parent 5d1c3ac9ba
commit 2c84c1e229
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
3 changed files with 80 additions and 65 deletions

View File

@ -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);

View File

@ -1,2 +1,72 @@
#include "BoundScope.hpp"
BoundScope::BoundScope(unordered_map<int, BoundVariable *> *scriptScope) {
_scriptScope = scriptScope;
_currentScope = 1;
_localScope = vector<unordered_map<int, BoundVariable*>>(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));
}
}

View File

@ -17,71 +17,13 @@ class BoundScope {
vector<unordered_map<int, BoundVariable*>> _localScope;
int _currentScope;
public:
explicit BoundScope(unordered_map<int, BoundVariable*> *scriptScope){
_scriptScope = scriptScope;
_currentScope = 1;
_localScope = vector<unordered_map<int, BoundVariable*>>(1);
}
~BoundScope(){
_localScope.clear();
}
explicit BoundScope(unordered_map<int, BoundVariable*> *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);
};