More fixes for boundscope
This commit is contained in:
parent
2c84c1e229
commit
6185f755a4
|
@ -32,9 +32,11 @@ BoundStatement* Binder::BindStatement(ParsedStatement* statement){
|
|||
BoundStatement *Binder::BindBlockStatement(ParsedStatement *statement) {
|
||||
auto statements = ((ParsedBlockStatement*)statement)->GetStatements();
|
||||
vector<BoundStatement*> 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);
|
||||
|
|
|
@ -4,11 +4,34 @@
|
|||
BoundScope::BoundScope(unordered_map<int, BoundVariable *> *scriptScope) {
|
||||
_scriptScope = scriptScope;
|
||||
_currentScope = 1;
|
||||
_localScope = vector<unordered_map<int, BoundVariable*>>(1);
|
||||
_deepestScope = 1;
|
||||
auto localUpmostScope = new unordered_map<int, BoundVariable*>();
|
||||
_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<int, BoundVariable*>();
|
||||
_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
|
||||
|
|
|
@ -14,16 +14,20 @@ using namespace std;
|
|||
|
||||
class BoundScope {
|
||||
unordered_map<int, BoundVariable*>* _scriptScope;
|
||||
vector<unordered_map<int, BoundVariable*>> _localScope;
|
||||
vector<unordered_map<int, BoundVariable*>*> _localScope;
|
||||
int _currentScope;
|
||||
int _deepestScope;
|
||||
public:
|
||||
explicit BoundScope(unordered_map<int, BoundVariable*> *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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -7,6 +7,7 @@ TEST_CASE( "Create script variable", "[integration]" ) {
|
|||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
auto variable = script->GetVariable("foo");
|
||||
REQUIRE(variable == nullptr);
|
||||
delete script;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue