Cleanup and fixes for boundscope
This commit is contained in:
parent
5d1c3ac9ba
commit
2c84c1e229
|
@ -46,7 +46,10 @@ BoundStatement *Binder::BindExpressionStatement(ParsedStatement *statement) {
|
||||||
BoundStatement* Binder::BindAssignmentStatement(ParsedStatement *statement){
|
BoundStatement* Binder::BindAssignmentStatement(ParsedStatement *statement){
|
||||||
auto s = (ParsedAssignmentStatement*) statement;
|
auto s = (ParsedAssignmentStatement*) statement;
|
||||||
auto boundExpression = this->BindExpression(s->GetExpression());
|
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){
|
if (assignment.GetResult() == VariableAssignmentResult::Ok){
|
||||||
auto key = assignment.GetKey();
|
auto key = assignment.GetKey();
|
||||||
return new BoundAssignmentStatement(key, boundExpression);
|
return new BoundAssignmentStatement(key, boundExpression);
|
||||||
|
|
|
@ -1,2 +1,72 @@
|
||||||
|
|
||||||
#include "BoundScope.hpp"
|
#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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,71 +17,13 @@ class BoundScope {
|
||||||
vector<unordered_map<int, BoundVariable*>> _localScope;
|
vector<unordered_map<int, BoundVariable*>> _localScope;
|
||||||
int _currentScope;
|
int _currentScope;
|
||||||
public:
|
public:
|
||||||
explicit BoundScope(unordered_map<int, BoundVariable*> *scriptScope){
|
explicit BoundScope(unordered_map<int, BoundVariable*> *scriptScope);
|
||||||
_scriptScope = scriptScope;
|
~BoundScope();
|
||||||
_currentScope = 1;
|
|
||||||
_localScope = vector<unordered_map<int, BoundVariable*>>(1);
|
|
||||||
}
|
|
||||||
~BoundScope(){
|
|
||||||
_localScope.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
int Exists(int key){
|
int Exists(int key);
|
||||||
auto found = this -> _scriptScope -> find(key);
|
BoundVariable* GetVariable(int scope, int identifier);
|
||||||
if (found != _scriptScope -> end()){
|
VariableAssignment CreateExplicitLocal(int identifier, ScriptType* type);
|
||||||
return 0;
|
VariableAssignment AssignVariable(int identifier, ScriptType* type);
|
||||||
}
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue