From 4d452b33e0ff1c4bf910415785dac4de62b6926a Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Sat, 8 Jun 2019 16:44:47 +0200 Subject: [PATCH] Jump to specific function scope when calling function --- src/Binder/Binder.cpp | 3 ++- src/Evaluator/EvaluationScope/EvaluationScope.cpp | 8 ++++++-- src/Evaluator/EvaluationScope/EvaluationScope.hpp | 10 ++++++++-- src/Evaluator/Evaluator.cpp | 5 +++++ src/ScriptType.hpp | 8 +++++++- 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/Binder/Binder.cpp b/src/Binder/Binder.cpp index 440b500..749c34b 100644 --- a/src/Binder/Binder.cpp +++ b/src/Binder/Binder.cpp @@ -80,6 +80,7 @@ BoundStatement *Binder::BindFunctionDeclarationStatement(ParsedStatement *statem auto parameterTypes = vector>(parameters.size()); auto parameterKeys = vector>(parameters.size()); + auto scopeIndex = this->_scope->GetCurrentScope(); this->_scope->GoInnerScope(); for (int i = 0; i < parameters.size(); i++){ auto var = parameters[i]; @@ -97,7 +98,7 @@ BoundStatement *Binder::BindFunctionDeclarationStatement(ParsedStatement *statem auto identifier = functionStatement->GetIdentifier(); auto returnType = make_shared(TypeClass::Nil); - auto type = make_shared(returnType, parameterTypes, parameterKeys); + auto type = make_shared(returnType, parameterTypes, parameterKeys, scopeIndex); auto assignment = this->_scope->AssignVariable(identifier.GetHash(), type); if (assignment.GetResult() != VariableAssignmentResult::Ok){ this -> _scriptData -> Diagnostics -> LogError(DiagnosticCode::CantAssignVariable, statement->GetStartPosition(), statement->GetLength()); diff --git a/src/Evaluator/EvaluationScope/EvaluationScope.cpp b/src/Evaluator/EvaluationScope/EvaluationScope.cpp index 17c00bf..c1eeffa 100644 --- a/src/Evaluator/EvaluationScope/EvaluationScope.cpp +++ b/src/Evaluator/EvaluationScope/EvaluationScope.cpp @@ -8,7 +8,7 @@ EvaluationScope::EvaluationScope(unordered_map> *scri _currentScope = -1; } -void EvaluationScope::CreateVariable(int scope, int id, shared_ptr value) { +void EvaluationScope::CreateVariable(int scope, int id, const shared_ptr& value) { if (scope == 0){ _scriptScope->at(id) = value; } else{ @@ -16,7 +16,7 @@ void EvaluationScope::CreateVariable(int scope, int id, shared_ptr va } } -void EvaluationScope::SetVariable(int scope, int id, shared_ptr value) { +void EvaluationScope::SetVariable(int scope, int id, const shared_ptr& value) { if (scope == 0){ _scriptScope->at(id) = value; } else{ @@ -31,6 +31,10 @@ shared_ptr EvaluationScope::GetVariable(int scope, int id) { return _localScope[scope - 1][id]; } +void EvaluationScope::JumpToScope(int index){ + _currentScope = index; +} + void EvaluationScope::OuterScope() { _currentScope++; } diff --git a/src/Evaluator/EvaluationScope/EvaluationScope.hpp b/src/Evaluator/EvaluationScope/EvaluationScope.hpp index 036c8ef..15bf66f 100644 --- a/src/Evaluator/EvaluationScope/EvaluationScope.hpp +++ b/src/Evaluator/EvaluationScope/EvaluationScope.hpp @@ -14,11 +14,17 @@ public: explicit EvaluationScope(unordered_map>* scriptVariables, int deepestScope); ~EvaluationScope() = default; - void CreateVariable(int scope, int id, shared_ptr value); - void SetVariable(int scope, int id, shared_ptr value); + void CreateVariable(int scope, int id, const shared_ptr& value); + void SetVariable(int scope, int id, const shared_ptr& value); void OuterScope(); void InnerScope(); shared_ptr GetVariable(int scope, int id); + + void JumpToScope(int index); + + int GetCurrentScope(){ + return _currentScope; + } }; diff --git a/src/Evaluator/Evaluator.cpp b/src/Evaluator/Evaluator.cpp index 90d96bf..e8fce5d 100644 --- a/src/Evaluator/Evaluator.cpp +++ b/src/Evaluator/Evaluator.cpp @@ -188,6 +188,10 @@ shared_ptr Evaluator::EvaluateFunctionCallExpression(BoundExpression* auto type = std::dynamic_pointer_cast(function->GetType()); auto parameterTypes = type->GetParameterTypes(); auto parameterKeys = type->GetParameterKeys(); + auto scope = type -> GetScopeIndex(); + auto originalScope = this->_evaluationScope->GetCurrentScope(); + this->_evaluationScope->JumpToScope(scope); + for (int i = 0; i < parameterTypes.size() && i < parameterKeys.size() && i < parameters.size(); i++){ auto parameter = parameters[i]; auto requiredType = parameterTypes.at(i); @@ -198,6 +202,7 @@ shared_ptr Evaluator::EvaluateFunctionCallExpression(BoundExpression* this->_evaluationScope->CreateVariable(key->GetScopeId(), key->GetIdentifier(), parameter->Clone()); } this->EvaluateBlockStatement(function->GetInnerBlock().get()); + this->_evaluationScope->JumpToScope(originalScope); this->_hasReturned = false; auto r = this -> _returnValue; this -> _returnValue = nullptr; diff --git a/src/ScriptType.hpp b/src/ScriptType.hpp index 87acefd..50269d0 100644 --- a/src/ScriptType.hpp +++ b/src/ScriptType.hpp @@ -82,13 +82,15 @@ class FunctionScriptType : public ScriptType{ shared_ptr _returnType; vector> _parameterTypes; vector> _parameterKeys; + int _scopeIndex; public: FunctionScriptType(std::shared_ptr returnType, vector> parameterTypes, - vector> parameterKeys) + vector> parameterKeys, int scopeIndex) : ScriptType(TypeClass::Function){ _returnType = std::move(returnType); _parameterTypes = std::move(parameterTypes); _parameterKeys = std::move(parameterKeys); + _scopeIndex = scopeIndex; } shared_ptr GetReturnType(){ return _returnType; @@ -101,6 +103,10 @@ public: vector> GetParameterKeys(){ return _parameterKeys; } + + int GetScopeIndex(){ + return _scopeIndex; + } }; #endif //PORYGONLANG_SCRIPTTYPE_HPP