Allow non-local script functions to be called from outside the script
This commit is contained in:
parent
43dede9ae2
commit
bda26b0ddf
|
@ -175,3 +175,19 @@ shared_ptr<EvalValue> Evaluator::EvaluateFunctionCallExpression(BoundExpression*
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EvalValue* Evaluator::EvaluateFunction(ScriptFunctionEvalValue *function, vector<EvalValue *> parameters) {
|
||||||
|
auto type = std::dynamic_pointer_cast<FunctionScriptType>(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;
|
||||||
|
}
|
|
@ -9,6 +9,7 @@
|
||||||
#include "EvalValues/NumericEvalValue.hpp"
|
#include "EvalValues/NumericEvalValue.hpp"
|
||||||
#include "EvalValues/StringEvalValue.hpp"
|
#include "EvalValues/StringEvalValue.hpp"
|
||||||
#include "EvalValues/StringEvalValue.hpp"
|
#include "EvalValues/StringEvalValue.hpp"
|
||||||
|
#include "EvalValues/ScriptFunctionEvalValue.hpp"
|
||||||
#include "EvaluationScope/EvaluationScope.hpp"
|
#include "EvaluationScope/EvaluationScope.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -21,6 +22,7 @@ class Evaluator {
|
||||||
EvaluationScope* _evaluationScope;
|
EvaluationScope* _evaluationScope;
|
||||||
|
|
||||||
void EvaluateStatement(BoundStatement* statement);
|
void EvaluateStatement(BoundStatement* statement);
|
||||||
|
void EvaluateBlockStatement(BoundBlockStatement* statement);
|
||||||
void EvaluateExpressionStatement(BoundExpressionStatement* statement);
|
void EvaluateExpressionStatement(BoundExpressionStatement* statement);
|
||||||
void EvaluateAssignmentStatement(BoundAssignmentStatement* statement);
|
void EvaluateAssignmentStatement(BoundAssignmentStatement* statement);
|
||||||
void EvaluateFunctionDeclarationStatement(BoundFunctionDeclarationStatement *statement);
|
void EvaluateFunctionDeclarationStatement(BoundFunctionDeclarationStatement *statement);
|
||||||
|
@ -52,7 +54,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void Evaluate(BoundScriptStatement* statement);
|
void Evaluate(BoundScriptStatement* statement);
|
||||||
void EvaluateBlockStatement(BoundBlockStatement* statement);
|
EvalValue* EvaluateFunction(ScriptFunctionEvalValue* func, vector<EvalValue*> parameters);
|
||||||
|
|
||||||
EvaluationScope* GetScope(){
|
EvaluationScope* GetScope(){
|
||||||
return _evaluationScope;
|
return _evaluationScope;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "Script.hpp"
|
#include "Script.hpp"
|
||||||
|
@ -65,6 +67,16 @@ EvalValue *Script::GetLastValue() {
|
||||||
return _evaluator->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<EvalValue *> variables) {
|
||||||
|
auto var = (ScriptFunctionEvalValue*)GetVariable(key);
|
||||||
|
return this->_evaluator->EvaluateFunction(var, std::move(variables));
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
Script* CreateScript(char * s){
|
Script* CreateScript(char * s){
|
||||||
return Script::Create(s);
|
return Script::Create(s);
|
||||||
|
|
|
@ -36,6 +36,9 @@ public:
|
||||||
EvalValue* GetVariable(const string& key);
|
EvalValue* GetVariable(const string& key);
|
||||||
bool HasVariable(const string& key);
|
bool HasVariable(const string& key);
|
||||||
|
|
||||||
|
EvalValue* CallFunction(const string& key, vector<EvalValue*> variables);
|
||||||
|
bool HasFunction(const string& key);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,4 +38,20 @@ TEST_CASE( "Define script function and call multiple times", "[integration]" ) {
|
||||||
delete script;
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue