From 22149d92436e77dd5c9fcc31399883629625c482 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Wed, 12 Jun 2019 18:45:47 +0200 Subject: [PATCH] Fixes for return statement, make Evaluate function on script return value --- src/Binder/Binder.cpp | 13 ++++++++++--- src/Evaluator/Evaluator.cpp | 6 ++++-- src/Evaluator/Evaluator.hpp | 4 ++-- src/Script.cpp | 4 ++-- src/Script.hpp | 6 +++++- src/ScriptType.hpp | 4 ++++ tests/integration/Tables.cpp | 10 ++++------ 7 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/Binder/Binder.cpp b/src/Binder/Binder.cpp index f523d71..89523ea 100644 --- a/src/Binder/Binder.cpp +++ b/src/Binder/Binder.cpp @@ -101,6 +101,8 @@ BoundStatement *Binder::BindFunctionDeclarationStatement(ParsedStatement *statem auto identifier = functionStatement->GetIdentifier(); auto returnType = make_shared(TypeClass::Nil); auto type = make_shared(returnType, parameterTypes, parameterKeys, scopeIndex); + this->_currentFunction = type; + auto assignment = this->_scope->AssignVariable(identifier.GetHash(), type); if (assignment.GetResult() != VariableAssignmentResult::Ok){ this -> _scriptData -> Diagnostics -> LogError(DiagnosticCode::CantAssignVariable, statement->GetStartPosition(), statement->GetLength()); @@ -108,6 +110,7 @@ BoundStatement *Binder::BindFunctionDeclarationStatement(ParsedStatement *statem } auto boundBlock = this -> BindBlockStatement(functionStatement->GetBlock()); this->_scope->GoOuterScope(); + this->_currentFunction = nullptr; return new BoundFunctionDeclarationStatement(type, assignment.GetKey(), (BoundBlockStatement*)boundBlock); } @@ -117,7 +120,7 @@ BoundStatement *Binder::BindReturnStatement(ParsedStatement* statement){ if (this->_currentFunction == nullptr){ currentReturnType = this->_scriptData->GetReturnType(); } else{ - currentReturnType = this->_currentFunction; + currentReturnType = this->_currentFunction->GetReturnType(); } if (expression == nullptr && currentReturnType != nullptr){ this -> _scriptData -> Diagnostics -> LogError(DiagnosticCode::InvalidReturnType, statement->GetStartPosition(), statement->GetLength()); @@ -125,8 +128,12 @@ BoundStatement *Binder::BindReturnStatement(ParsedStatement* statement){ } auto boundExpression = this->BindExpression(expression); auto expresionType = boundExpression->GetType(); - if (currentReturnType == nullptr){ - currentReturnType.swap(expresionType); + if (currentReturnType == nullptr || currentReturnType->GetClass() == TypeClass::Nil){ + if (this->_currentFunction == nullptr){ + this->_scriptData->SetReturnType(expresionType); + } else{ + this->_currentFunction->SetReturnType(expresionType); + } return new BoundReturnStatement(boundExpression); } if (currentReturnType.get()->operator!=(expresionType.get())){ diff --git a/src/Evaluator/Evaluator.cpp b/src/Evaluator/Evaluator.cpp index b0050d2..4ee2261 100644 --- a/src/Evaluator/Evaluator.cpp +++ b/src/Evaluator/Evaluator.cpp @@ -11,9 +11,10 @@ using namespace std; -void Evaluator::Evaluate(BoundScriptStatement *statement) { +EvalValue* Evaluator::Evaluate(BoundScriptStatement *statement) { this->_evaluationScope = make_shared(this->_scriptData->_scriptVariables, statement->GetDeepestScope()); EvaluateBlockStatement(statement, false); + return this -> _returnValue.get(); } void Evaluator::EvaluateStatement(BoundStatement *statement) { @@ -73,11 +74,12 @@ void Evaluator::EvaluateFunctionDeclarationStatement(BoundFunctionDeclarationSta void Evaluator::EvaluateReturnStatement(BoundReturnStatement* statement){ auto expression = statement->GetExpression(); - this->_hasReturned = true; if (expression == nullptr){ + this->_hasReturned = true; return; } auto value = this -> EvaluateExpression(expression); + this->_hasReturned = true; this -> _returnValue = value; } diff --git a/src/Evaluator/Evaluator.hpp b/src/Evaluator/Evaluator.hpp index 171cc72..fe5b217 100644 --- a/src/Evaluator/Evaluator.hpp +++ b/src/Evaluator/Evaluator.hpp @@ -47,6 +47,7 @@ class Evaluator { shared_ptr EvaluateFunctionCallExpression(BoundExpression *expression); shared_ptr EvaluateIndexExpression(BoundExpression* expression); shared_ptr EvaluateNumericTableExpression(BoundExpression* expression); + shared_ptr EvaluateComplexTableExpression(BoundExpression *expression); shared_ptr GetVariable(BoundVariableExpression *expression); public: @@ -57,14 +58,13 @@ public: _evaluationScope = nullptr; } - void Evaluate(BoundScriptStatement* statement); + EvalValue* Evaluate(BoundScriptStatement* statement); shared_ptr EvaluateFunction(ScriptFunctionEvalValue* func, vector parameters); EvalValue* GetLastValue(){ return _lastValue.get(); } - shared_ptr EvaluateComplexTableExpression(BoundExpression *expression); }; diff --git a/src/Script.cpp b/src/Script.cpp index bdf76cf..653b03a 100644 --- a/src/Script.cpp +++ b/src/Script.cpp @@ -20,8 +20,8 @@ Script::Script() { _scriptVariables = new unordered_map>(0); } -void Script::Evaluate() { - _evaluator->Evaluate(_boundScript); +EvalValue* Script::Evaluate() { + return _evaluator->Evaluate(_boundScript); } Script::~Script() { diff --git a/src/Script.hpp b/src/Script.hpp index 4ef499b..34208dc 100644 --- a/src/Script.hpp +++ b/src/Script.hpp @@ -34,7 +34,11 @@ public: return _returnType; } - void Evaluate(); + void SetReturnType(shared_ptr t){ + _returnType = t; + } + + EvalValue* Evaluate(); EvalValue* GetLastValue(); diff --git a/src/ScriptType.hpp b/src/ScriptType.hpp index c84835d..598b1a3 100644 --- a/src/ScriptType.hpp +++ b/src/ScriptType.hpp @@ -110,6 +110,10 @@ public: return _returnType; } + void SetReturnType(shared_ptr t){ + _returnType = t; + } + vector> GetParameterTypes(){ return _parameterTypes; } diff --git a/tests/integration/Tables.cpp b/tests/integration/Tables.cpp index 70cd299..44fcd92 100644 --- a/tests/integration/Tables.cpp +++ b/tests/integration/Tables.cpp @@ -34,11 +34,10 @@ TEST_CASE( "Index string table", "[integration]" ) { Script* script = Script::Create( R"( table = {'bla', 'test', 'foo', 'bar'} -result = table[3] +return table[3] )"); REQUIRE(!script->Diagnostics -> HasErrors()); - script->Evaluate(); - auto variable = script->GetVariable("result"); + auto variable = script->Evaluate(); REQUIRE(variable != nullptr); REQUIRE(*variable->EvaluateString() == "foo"); delete script; @@ -71,11 +70,10 @@ table = { return foo end } -result = table["getFoo"]() +return table["getFoo"]() )"); REQUIRE(!script->Diagnostics -> HasErrors()); - script->Evaluate(); - auto variable = script->GetVariable("result"); + auto variable = script->Evaluate(); REQUIRE(variable != nullptr); delete script; }