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/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<EvalValue*> parameters);
|
||||
|
||||
EvaluationScope* GetScope(){
|
||||
return _evaluationScope;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <utility>
|
||||
|
||||
#include <utility>
|
||||
#include <unordered_map>
|
||||
#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<EvalValue *> variables) {
|
||||
auto var = (ScriptFunctionEvalValue*)GetVariable(key);
|
||||
return this->_evaluator->EvaluateFunction(var, std::move(variables));
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
Script* CreateScript(char * s){
|
||||
return Script::Create(s);
|
||||
|
|
|
@ -36,6 +36,9 @@ public:
|
|||
EvalValue* GetVariable(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;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue