More fixes for boundscope

This commit is contained in:
Deukhoofd 2019-05-28 18:50:23 +02:00
parent 2c84c1e229
commit 6185f755a4
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
6 changed files with 58 additions and 20 deletions

View File

@ -32,9 +32,11 @@ BoundStatement* Binder::BindStatement(ParsedStatement* statement){
BoundStatement *Binder::BindBlockStatement(ParsedStatement *statement) { BoundStatement *Binder::BindBlockStatement(ParsedStatement *statement) {
auto statements = ((ParsedBlockStatement*)statement)->GetStatements(); auto statements = ((ParsedBlockStatement*)statement)->GetStatements();
vector<BoundStatement*> boundStatements (statements.size()); vector<BoundStatement*> boundStatements (statements.size());
this->_scope->GoInnerScope();
for (int i = 0; i < statements.size(); i++){ for (int i = 0; i < statements.size(); i++){
boundStatements[i] = this -> BindStatement(statements[i]); boundStatements[i] = this -> BindStatement(statements[i]);
} }
this->_scope->GoOuterScope();
return new BoundBlockStatement(boundStatements); return new BoundBlockStatement(boundStatements);
} }
@ -48,8 +50,8 @@ BoundStatement* Binder::BindAssignmentStatement(ParsedStatement *statement){
auto boundExpression = this->BindExpression(s->GetExpression()); auto boundExpression = this->BindExpression(s->GetExpression());
VariableAssignment assignment = VariableAssignment assignment =
s->IsLocal() ? s->IsLocal() ?
this->_scope->CreateExplicitLocal(s->GetIdentifier().GetHash(), boundExpression->GetType()) this->_scope->CreateExplicitLocal(s->GetIdentifier().GetHash(), *boundExpression->GetType())
: this->_scope->AssignVariable(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);

View File

@ -4,11 +4,34 @@
BoundScope::BoundScope(unordered_map<int, BoundVariable *> *scriptScope) { BoundScope::BoundScope(unordered_map<int, BoundVariable *> *scriptScope) {
_scriptScope = scriptScope; _scriptScope = scriptScope;
_currentScope = 1; _currentScope = 1;
_localScope = vector<unordered_map<int, BoundVariable*>>(1); _deepestScope = 1;
auto localUpmostScope = new unordered_map<int, BoundVariable*>();
_localScope.push_back(localUpmostScope);
} }
BoundScope::~BoundScope() { 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<int, BoundVariable*>();
_localScope.push_back(innerScope);
}
if (_deepestScope < _currentScope){
_deepestScope = _currentScope;
}
}
void BoundScope::GoOuterScope() {
_localScope[_currentScope - 1]->clear();
_currentScope--;
} }
int BoundScope::Exists(int key) { int BoundScope::Exists(int key) {
@ -18,8 +41,8 @@ int BoundScope::Exists(int key) {
} }
for (int i = _currentScope - 1; i >= 0; i--){ for (int i = _currentScope - 1; i >= 0; i--){
auto scope = _localScope.at(i); auto scope = _localScope.at(i);
found = scope.find(key); found = scope -> find(key);
if (found != scope.end()){ if (found != scope -> end()){
return i + 1; return i + 1;
} }
} }
@ -35,24 +58,24 @@ BoundVariable *BoundScope::GetVariable(int scope, int identifier) {
return nullptr; return nullptr;
} else{ } else{
auto s = this->_localScope.at(scope); auto s = this->_localScope.at(scope);
auto find = s.find(identifier); auto find = s -> find(identifier);
if (find != s.end()){ if (find != s -> end()){
return find -> second; return find -> second;
} }
return nullptr; return nullptr;
} }
} }
VariableAssignment BoundScope::CreateExplicitLocal(int identifier, ScriptType *type) { VariableAssignment BoundScope::CreateExplicitLocal(int identifier, const ScriptType& type) {
auto scope = this->_localScope.at(this->_currentScope); auto scope = this->_localScope.at(this->_currentScope);
if (scope.find(identifier) != scope.end()){ if (scope -> find(identifier) != scope -> end()){
return VariableAssignment(VariableAssignmentResult::ExplicitLocalVariableExists, nullptr); 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)); 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); int exists = this->Exists(identifier);
if (exists == -1){ if (exists == -1){
// Creation // Creation

View File

@ -14,16 +14,20 @@ using namespace std;
class BoundScope { class BoundScope {
unordered_map<int, BoundVariable*>* _scriptScope; unordered_map<int, BoundVariable*>* _scriptScope;
vector<unordered_map<int, BoundVariable*>> _localScope; vector<unordered_map<int, BoundVariable*>*> _localScope;
int _currentScope; int _currentScope;
int _deepestScope;
public: public:
explicit BoundScope(unordered_map<int, BoundVariable*> *scriptScope); explicit BoundScope(unordered_map<int, BoundVariable*> *scriptScope);
~BoundScope(); ~BoundScope();
void GoInnerScope();
void GoOuterScope();
int Exists(int key); int Exists(int key);
BoundVariable* GetVariable(int scope, int identifier); BoundVariable* GetVariable(int scope, int identifier);
VariableAssignment CreateExplicitLocal(int identifier, ScriptType* type); VariableAssignment CreateExplicitLocal(int identifier, const ScriptType& type);
VariableAssignment AssignVariable(int identifier, ScriptType* type); VariableAssignment AssignVariable(int identifier, const ScriptType& type);
}; };

View File

@ -5,16 +5,14 @@
#include "../../ScriptType.hpp" #include "../../ScriptType.hpp"
class BoundVariable{ class BoundVariable{
ScriptType* _type; ScriptType _type;
public: public:
explicit BoundVariable(ScriptType* type){ explicit BoundVariable(ScriptType type) : _type(type){
_type = type;
} }
~BoundVariable(){ ~BoundVariable(){
delete _type;
} }
ScriptType* GetType(){ ScriptType& GetType(){
return _type; return _type;
} }
}; };

View File

@ -20,9 +20,19 @@ public:
_class = c; _class = c;
} }
virtual ~ScriptType() = default;
const TypeClass GetClass(){ const TypeClass GetClass(){
return _class; return _class;
} }
virtual bool operator ==(ScriptType b){
return _class == b._class;
};
virtual bool operator !=(ScriptType b){
return ! (operator==(b));
}
}; };
class NumericScriptType : public ScriptType{ class NumericScriptType : public ScriptType{

View File

@ -7,6 +7,7 @@ TEST_CASE( "Create script variable", "[integration]" ) {
REQUIRE(!script->Diagnostics -> HasErrors()); REQUIRE(!script->Diagnostics -> HasErrors());
auto variable = script->GetVariable("foo"); auto variable = script->GetVariable("foo");
REQUIRE(variable == nullptr); REQUIRE(variable == nullptr);
delete script;
} }