From bda26b0ddfd34164065405b1f9b1fff8e9d9c047 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Wed, 5 Jun 2019 18:44:23 +0200 Subject: [PATCH] Allow non-local script functions to be called from outside the script --- src/Evaluator/Evaluator.cpp | 16 ++++++++++++++++ src/Evaluator/Evaluator.hpp | 4 +++- src/Script.cpp | 12 ++++++++++++ src/Script.hpp | 3 +++ tests/integration/ExternFunctionsTests.cpp | 3 --- tests/integration/Functions.cpp | 16 ++++++++++++++++ 6 files changed, 50 insertions(+), 4 deletions(-) delete mode 100644 tests/integration/ExternFunctionsTests.cpp diff --git a/src/Evaluator/Evaluator.cpp b/src/Evaluator/Evaluator.cpp index 5525382..94637a7 100644 --- a/src/Evaluator/Evaluator.cpp +++ b/src/Evaluator/Evaluator.cpp @@ -175,3 +175,19 @@ shared_ptr Evaluator::EvaluateFunctionCallExpression(BoundExpression* } +EvalValue* Evaluator::EvaluateFunction(ScriptFunctionEvalValue *function, vector parameters) { + auto type = std::dynamic_pointer_cast(function->GetType()); + auto parameterTypes = type->GetParameterTypes(); + auto parameterKeys = type->GetParameterKeys(); + for (int i = 0; i < parameterTypes->size() && i < parameterKeys->size() && i < parameters.size(); i++){ + auto parameter = parameters[i]; + auto requiredType = parameterTypes->at(i); + if (*parameter->GetType() != requiredType.get()){ + throw EvaluationException("Passed wrong type to function."); + } + auto key = parameterKeys->at(i); + this->_evaluationScope->CreateVariable(key->GetScopeId(), key->GetIdentifier(), parameter->Clone()); + } + this->EvaluateBlockStatement(function->GetInnerBlock().get()); + return nullptr; +} \ No newline at end of file diff --git a/src/Evaluator/Evaluator.hpp b/src/Evaluator/Evaluator.hpp index e23b06f..3b63ff7 100644 --- a/src/Evaluator/Evaluator.hpp +++ b/src/Evaluator/Evaluator.hpp @@ -9,6 +9,7 @@ #include "EvalValues/NumericEvalValue.hpp" #include "EvalValues/StringEvalValue.hpp" #include "EvalValues/StringEvalValue.hpp" +#include "EvalValues/ScriptFunctionEvalValue.hpp" #include "EvaluationScope/EvaluationScope.hpp" using namespace std; @@ -21,6 +22,7 @@ class Evaluator { EvaluationScope* _evaluationScope; void EvaluateStatement(BoundStatement* statement); + void EvaluateBlockStatement(BoundBlockStatement* statement); void EvaluateExpressionStatement(BoundExpressionStatement* statement); void EvaluateAssignmentStatement(BoundAssignmentStatement* statement); void EvaluateFunctionDeclarationStatement(BoundFunctionDeclarationStatement *statement); @@ -52,7 +54,7 @@ public: } void Evaluate(BoundScriptStatement* statement); - void EvaluateBlockStatement(BoundBlockStatement* statement); + EvalValue* EvaluateFunction(ScriptFunctionEvalValue* func, vector parameters); EvaluationScope* GetScope(){ return _evaluationScope; diff --git a/src/Script.cpp b/src/Script.cpp index 979fc38..7d3fdcc 100644 --- a/src/Script.cpp +++ b/src/Script.cpp @@ -1,3 +1,5 @@ +#include + #include #include #include "Script.hpp" @@ -65,6 +67,16 @@ EvalValue *Script::GetLastValue() { return _evaluator->GetLastValue(); } +bool Script::HasFunction(const string &key) { + auto f = _scriptVariables->find(HashedString(key).GetHash()); + return f != _scriptVariables->end() && f.operator->()->second->GetType()->GetClass() == TypeClass ::Function; +} + +EvalValue *Script::CallFunction(const string &key, vector variables) { + auto var = (ScriptFunctionEvalValue*)GetVariable(key); + return this->_evaluator->EvaluateFunction(var, std::move(variables)); +} + extern "C" { Script* CreateScript(char * s){ return Script::Create(s); diff --git a/src/Script.hpp b/src/Script.hpp index 5179ff3..589dc37 100644 --- a/src/Script.hpp +++ b/src/Script.hpp @@ -36,6 +36,9 @@ public: EvalValue* GetVariable(const string& key); bool HasVariable(const string& key); + EvalValue* CallFunction(const string& key, vector variables); + bool HasFunction(const string& key); + }; diff --git a/tests/integration/ExternFunctionsTests.cpp b/tests/integration/ExternFunctionsTests.cpp deleted file mode 100644 index b28b04f..0000000 --- a/tests/integration/ExternFunctionsTests.cpp +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/tests/integration/Functions.cpp b/tests/integration/Functions.cpp index 1939308..98a44d5 100644 --- a/tests/integration/Functions.cpp +++ b/tests/integration/Functions.cpp @@ -38,4 +38,20 @@ TEST_CASE( "Define script function and call multiple times", "[integration]" ) { delete script; } +TEST_CASE( "Define script function and call from extern", "[integration]" ) { + Script* script = Script::Create("result = 0 function add(number a) result = result + a end"); + REQUIRE(!script->Diagnostics -> HasErrors()); + script->Evaluate(); + + REQUIRE(script->HasFunction("add")); + script->CallFunction("add", {new IntegerEvalValue(5)}); + script->CallFunction("add", {new IntegerEvalValue(6)}); + + auto result = script->GetVariable("result"); + REQUIRE(result->GetType()->GetClass() == TypeClass::Number); + REQUIRE(result->EvaluateInteger() == 11); + delete script; +} + + #endif