Implements return statement
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
f143e526ab
commit
f4a3918947
|
@ -25,6 +25,7 @@ BoundStatement* Binder::BindStatement(ParsedStatement* statement){
|
||||||
case ParsedStatementKind ::Expression: return this -> BindExpressionStatement(statement);
|
case ParsedStatementKind ::Expression: return this -> BindExpressionStatement(statement);
|
||||||
case ParsedStatementKind::Assignment: return this -> BindAssignmentStatement(statement);
|
case ParsedStatementKind::Assignment: return this -> BindAssignmentStatement(statement);
|
||||||
case ParsedStatementKind ::FunctionDeclaration: return this->BindFunctionDeclarationStatement(statement);
|
case ParsedStatementKind ::FunctionDeclaration: return this->BindFunctionDeclarationStatement(statement);
|
||||||
|
case ParsedStatementKind::Return: return this -> BindReturnStatement(statement);
|
||||||
|
|
||||||
case ParsedStatementKind::Bad: return new BoundBadStatement();
|
case ParsedStatementKind::Bad: return new BoundBadStatement();
|
||||||
}
|
}
|
||||||
|
@ -105,6 +106,31 @@ BoundStatement *Binder::BindFunctionDeclarationStatement(ParsedStatement *statem
|
||||||
return new BoundBadStatement();
|
return new BoundBadStatement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BoundStatement *Binder::BindReturnStatement(ParsedStatement* statement){
|
||||||
|
auto expression = ((ParsedReturnStatement*)statement)->GetExpression();
|
||||||
|
shared_ptr<ScriptType> currentReturnType;
|
||||||
|
if (this->_currentFunction == nullptr){
|
||||||
|
currentReturnType = this->_scriptData->GetReturnType();
|
||||||
|
} else{
|
||||||
|
currentReturnType = this->_currentFunction;
|
||||||
|
}
|
||||||
|
if (expression == nullptr && currentReturnType != nullptr){
|
||||||
|
this -> _scriptData -> Diagnostics -> LogError(DiagnosticCode::InvalidReturnType, statement->GetStartPosition(), statement->GetLength());
|
||||||
|
return new BoundBadStatement();
|
||||||
|
}
|
||||||
|
auto boundExpression = this->BindExpression(expression);
|
||||||
|
auto expresionType = boundExpression->GetType();
|
||||||
|
if (currentReturnType == nullptr){
|
||||||
|
currentReturnType.swap(expresionType);
|
||||||
|
return new BoundReturnStatement(boundExpression);
|
||||||
|
}
|
||||||
|
if (currentReturnType.get()->operator!=(expresionType.get())){
|
||||||
|
this -> _scriptData -> Diagnostics -> LogError(DiagnosticCode::InvalidReturnType, statement->GetStartPosition(), statement->GetLength());
|
||||||
|
return new BoundBadStatement();
|
||||||
|
}
|
||||||
|
return new BoundReturnStatement(boundExpression);
|
||||||
|
}
|
||||||
|
|
||||||
BoundExpression* Binder::BindExpression(ParsedExpression* expression){
|
BoundExpression* Binder::BindExpression(ParsedExpression* expression){
|
||||||
switch (expression -> GetKind()){
|
switch (expression -> GetKind()){
|
||||||
case ParsedExpressionKind ::LiteralInteger:
|
case ParsedExpressionKind ::LiteralInteger:
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
class Binder {
|
class Binder {
|
||||||
Script* _scriptData;
|
Script* _scriptData;
|
||||||
BoundScope* _scope;
|
BoundScope* _scope;
|
||||||
|
shared_ptr<FunctionScriptType> _currentFunction;
|
||||||
|
|
||||||
~Binder();
|
~Binder();
|
||||||
|
|
||||||
|
@ -18,6 +19,7 @@ class Binder {
|
||||||
BoundStatement *BindExpressionStatement(ParsedStatement *statement);
|
BoundStatement *BindExpressionStatement(ParsedStatement *statement);
|
||||||
BoundStatement *BindAssignmentStatement(ParsedStatement *statement);
|
BoundStatement *BindAssignmentStatement(ParsedStatement *statement);
|
||||||
BoundStatement *BindFunctionDeclarationStatement(ParsedStatement * statement);
|
BoundStatement *BindFunctionDeclarationStatement(ParsedStatement * statement);
|
||||||
|
BoundStatement *BindReturnStatement(ParsedStatement *statement);
|
||||||
|
|
||||||
BoundExpression *BindExpression(ParsedExpression *expression);
|
BoundExpression *BindExpression(ParsedExpression *expression);
|
||||||
BoundExpression *BindVariableExpression(VariableExpression *expression);
|
BoundExpression *BindVariableExpression(VariableExpression *expression);
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef PORYGONLANG_BOUNDSTATEMENT_HPP
|
#ifndef PORYGONLANG_BOUNDSTATEMENT_HPP
|
||||||
#define PORYGONLANG_BOUNDSTATEMENT_HPP
|
#define PORYGONLANG_BOUNDSTATEMENT_HPP
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "../BoundExpressions/BoundExpression.hpp"
|
#include "../BoundExpressions/BoundExpression.hpp"
|
||||||
#include "../BoundVariables/BoundVariableKey.hpp"
|
#include "../BoundVariables/BoundVariableKey.hpp"
|
||||||
|
@ -18,6 +17,7 @@ enum class BoundStatementKind{
|
||||||
Expression,
|
Expression,
|
||||||
Assignment,
|
Assignment,
|
||||||
FunctionDeclaration,
|
FunctionDeclaration,
|
||||||
|
Return,
|
||||||
};
|
};
|
||||||
|
|
||||||
class BoundStatement{
|
class BoundStatement{
|
||||||
|
@ -116,6 +116,25 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BoundReturnStatement : public BoundStatement{
|
||||||
|
BoundExpression* _expression;
|
||||||
|
public:
|
||||||
|
explicit BoundReturnStatement(BoundExpression* expression){
|
||||||
|
_expression = expression;
|
||||||
|
}
|
||||||
|
~BoundReturnStatement() final{
|
||||||
|
delete _expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoundStatementKind GetKind() final{
|
||||||
|
return BoundStatementKind ::Return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BoundExpression* GetExpression(){
|
||||||
|
return _expression;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#include "BoundFunctionDeclarationStatement.hpp"
|
#include "BoundFunctionDeclarationStatement.hpp"
|
||||||
|
|
||||||
#endif //PORYGONLANG_BOUNDSTATEMENT_HPP
|
#endif //PORYGONLANG_BOUNDSTATEMENT_HPP
|
||||||
|
|
|
@ -19,6 +19,7 @@ enum class DiagnosticCode{
|
||||||
ParameterCountMismatch,
|
ParameterCountMismatch,
|
||||||
ParameterTypeMismatch,
|
ParameterTypeMismatch,
|
||||||
CantIndex,
|
CantIndex,
|
||||||
|
InvalidReturnType,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //PORYGONLANG_DIAGNOSTICCODE_HPP
|
#endif //PORYGONLANG_DIAGNOSTICCODE_HPP
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "Evaluator.hpp"
|
#include "Evaluator.hpp"
|
||||||
#include "EvaluationException.hpp"
|
#include "EvaluationException.hpp"
|
||||||
|
@ -18,12 +14,15 @@ void Evaluator::Evaluate(BoundScriptStatement *statement) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Evaluator::EvaluateStatement(BoundStatement *statement) {
|
void Evaluator::EvaluateStatement(BoundStatement *statement) {
|
||||||
|
if (this->_hasReturned)
|
||||||
|
return;
|
||||||
switch (statement->GetKind()){
|
switch (statement->GetKind()){
|
||||||
case BoundStatementKind ::Script: throw; // Should never happen
|
case BoundStatementKind ::Script: throw; // Should never happen
|
||||||
case BoundStatementKind ::Block: return this -> EvaluateBlockStatement((BoundBlockStatement*)statement);
|
case BoundStatementKind ::Block: return this -> EvaluateBlockStatement((BoundBlockStatement*)statement);
|
||||||
case BoundStatementKind ::Expression: return this -> EvaluateExpressionStatement((BoundExpressionStatement*)statement);
|
case BoundStatementKind ::Expression: return this -> EvaluateExpressionStatement((BoundExpressionStatement*)statement);
|
||||||
case BoundStatementKind ::Assignment: return this -> EvaluateAssignmentStatement((BoundAssignmentStatement*)statement);
|
case BoundStatementKind ::Assignment: return this -> EvaluateAssignmentStatement((BoundAssignmentStatement*)statement);
|
||||||
case BoundStatementKind ::FunctionDeclaration: return this->EvaluateFunctionDeclarationStatement((BoundFunctionDeclarationStatement*)statement);
|
case BoundStatementKind ::FunctionDeclaration: return this->EvaluateFunctionDeclarationStatement((BoundFunctionDeclarationStatement*)statement);
|
||||||
|
case BoundStatementKind::Return: return this -> EvaluateReturnStatement((BoundReturnStatement*)statement);
|
||||||
|
|
||||||
case BoundStatementKind::Bad:
|
case BoundStatementKind::Bad:
|
||||||
throw;
|
throw;
|
||||||
|
@ -34,6 +33,8 @@ void Evaluator::EvaluateBlockStatement(BoundBlockStatement* statement) {
|
||||||
this->_evaluationScope->OuterScope();
|
this->_evaluationScope->OuterScope();
|
||||||
for (auto s: statement->GetStatements()){
|
for (auto s: statement->GetStatements()){
|
||||||
this -> EvaluateStatement(s);
|
this -> EvaluateStatement(s);
|
||||||
|
if (this->_hasReturned)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
this->_evaluationScope->InnerScope();
|
this->_evaluationScope->InnerScope();
|
||||||
}
|
}
|
||||||
|
@ -65,6 +66,16 @@ void Evaluator::EvaluateFunctionDeclarationStatement(BoundFunctionDeclarationSta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Evaluator::EvaluateReturnStatement(BoundReturnStatement* statement){
|
||||||
|
auto expression = statement->GetExpression();
|
||||||
|
this->_hasReturned = true;
|
||||||
|
if (expression == nullptr){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto value = this -> EvaluateExpression(expression);
|
||||||
|
this -> _returnValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
shared_ptr<EvalValue> Evaluator::EvaluateExpression(BoundExpression *expression) {
|
shared_ptr<EvalValue> Evaluator::EvaluateExpression(BoundExpression *expression) {
|
||||||
auto type = expression -> GetType();
|
auto type = expression -> GetType();
|
||||||
switch (type->GetClass()){
|
switch (type->GetClass()){
|
||||||
|
@ -174,11 +185,13 @@ shared_ptr<EvalValue> Evaluator::EvaluateFunctionCallExpression(BoundExpression*
|
||||||
this->_evaluationScope->CreateVariable(key->GetScopeId(), key->GetIdentifier(), parameter->Clone());
|
this->_evaluationScope->CreateVariable(key->GetScopeId(), key->GetIdentifier(), parameter->Clone());
|
||||||
}
|
}
|
||||||
this->EvaluateBlockStatement(function->GetInnerBlock().get());
|
this->EvaluateBlockStatement(function->GetInnerBlock().get());
|
||||||
return nullptr;
|
this->_hasReturned = false;
|
||||||
|
auto r = this -> _returnValue;
|
||||||
|
this -> _returnValue = nullptr;
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
EvalValue* Evaluator::EvaluateFunction(ScriptFunctionEvalValue *function, vector<EvalValue *> parameters) {
|
shared_ptr<EvalValue> Evaluator::EvaluateFunction(ScriptFunctionEvalValue *function, vector<EvalValue *> parameters) {
|
||||||
auto type = std::dynamic_pointer_cast<FunctionScriptType>(function->GetType());
|
auto type = std::dynamic_pointer_cast<FunctionScriptType>(function->GetType());
|
||||||
auto parameterTypes = type->GetParameterTypes();
|
auto parameterTypes = type->GetParameterTypes();
|
||||||
auto parameterKeys = type->GetParameterKeys();
|
auto parameterKeys = type->GetParameterKeys();
|
||||||
|
@ -192,7 +205,10 @@ EvalValue* Evaluator::EvaluateFunction(ScriptFunctionEvalValue *function, vector
|
||||||
this->_evaluationScope->CreateVariable(key->GetScopeId(), key->GetIdentifier(), parameter->Clone());
|
this->_evaluationScope->CreateVariable(key->GetScopeId(), key->GetIdentifier(), parameter->Clone());
|
||||||
}
|
}
|
||||||
this->EvaluateBlockStatement(function->GetInnerBlock().get());
|
this->EvaluateBlockStatement(function->GetInnerBlock().get());
|
||||||
return nullptr;
|
this->_hasReturned = false;
|
||||||
|
auto r = this -> _returnValue;
|
||||||
|
this -> _returnValue = nullptr;
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<EvalValue> Evaluator::EvaluateIndexExpression(BoundExpression *expression) {
|
shared_ptr<EvalValue> Evaluator::EvaluateIndexExpression(BoundExpression *expression) {
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class Evaluator {
|
class Evaluator {
|
||||||
shared_ptr<EvalValue> _result;
|
shared_ptr<EvalValue> _returnValue;
|
||||||
|
bool _hasReturned;
|
||||||
shared_ptr<EvalValue> _lastValue;
|
shared_ptr<EvalValue> _lastValue;
|
||||||
|
|
||||||
Script* _scriptData;
|
Script* _scriptData;
|
||||||
|
@ -26,6 +27,7 @@ class Evaluator {
|
||||||
void EvaluateExpressionStatement(BoundExpressionStatement* statement);
|
void EvaluateExpressionStatement(BoundExpressionStatement* statement);
|
||||||
void EvaluateAssignmentStatement(BoundAssignmentStatement* statement);
|
void EvaluateAssignmentStatement(BoundAssignmentStatement* statement);
|
||||||
void EvaluateFunctionDeclarationStatement(BoundFunctionDeclarationStatement *statement);
|
void EvaluateFunctionDeclarationStatement(BoundFunctionDeclarationStatement *statement);
|
||||||
|
void EvaluateReturnStatement(BoundReturnStatement *statement);
|
||||||
|
|
||||||
shared_ptr<EvalValue> EvaluateExpression(BoundExpression* expression);
|
shared_ptr<EvalValue> EvaluateExpression(BoundExpression* expression);
|
||||||
shared_ptr<NumericEvalValue> EvaluateIntegerExpression(BoundExpression* expression);
|
shared_ptr<NumericEvalValue> EvaluateIntegerExpression(BoundExpression* expression);
|
||||||
|
@ -47,6 +49,8 @@ class Evaluator {
|
||||||
public:
|
public:
|
||||||
explicit Evaluator(Script* script){
|
explicit Evaluator(Script* script){
|
||||||
_scriptData = script;
|
_scriptData = script;
|
||||||
|
_hasReturned = false;
|
||||||
|
_returnValue = nullptr;
|
||||||
_evaluationScope = nullptr;
|
_evaluationScope = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +59,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void Evaluate(BoundScriptStatement* statement);
|
void Evaluate(BoundScriptStatement* statement);
|
||||||
EvalValue* EvaluateFunction(ScriptFunctionEvalValue* func, vector<EvalValue*> parameters);
|
shared_ptr<EvalValue> EvaluateFunction(ScriptFunctionEvalValue* func, vector<EvalValue*> parameters);
|
||||||
|
|
||||||
EvalValue* GetLastValue(){
|
EvalValue* GetLastValue(){
|
||||||
return _lastValue.get();
|
return _lastValue.get();
|
||||||
|
|
|
@ -15,7 +15,8 @@ enum class ParsedStatementKind{
|
||||||
Block,
|
Block,
|
||||||
Expression,
|
Expression,
|
||||||
Assignment,
|
Assignment,
|
||||||
FunctionDeclaration
|
FunctionDeclaration,
|
||||||
|
Return
|
||||||
};
|
};
|
||||||
|
|
||||||
class ParsedStatement {
|
class ParsedStatement {
|
||||||
|
@ -166,4 +167,24 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ParsedReturnStatement : public ParsedStatement{
|
||||||
|
ParsedExpression* _expression;
|
||||||
|
public:
|
||||||
|
ParsedReturnStatement(ParsedExpression* expression, unsigned int start, unsigned int length) : ParsedStatement(start, length){
|
||||||
|
_expression = expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ParsedReturnStatement() final{
|
||||||
|
delete _expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParsedStatementKind GetKind() final{
|
||||||
|
return ParsedStatementKind ::Return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParsedExpression* GetExpression(){
|
||||||
|
return _expression;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#endif //PORYGONLANG_PARSEDSTATEMENT_HPP
|
#endif //PORYGONLANG_PARSEDSTATEMENT_HPP
|
||||||
|
|
|
@ -33,6 +33,7 @@ ParsedStatement* Parser::ParseStatement(IToken* current){
|
||||||
switch (currentKind){
|
switch (currentKind){
|
||||||
case TokenKind ::LocalKeyword: return this -> ParseAssignment(current);
|
case TokenKind ::LocalKeyword: return this -> ParseAssignment(current);
|
||||||
case TokenKind ::FunctionKeyword: return this -> ParseFunctionDeclaration(current);
|
case TokenKind ::FunctionKeyword: return this -> ParseFunctionDeclaration(current);
|
||||||
|
case TokenKind ::ReturnKeyword: return this->ParseReturnStatement(current);
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
if (this->Peek()->GetKind() == TokenKind::AssignmentToken){
|
if (this->Peek()->GetKind() == TokenKind::AssignmentToken){
|
||||||
|
@ -134,7 +135,13 @@ ParsedStatement *Parser::ParseFunctionDeclaration(IToken *current) {
|
||||||
}
|
}
|
||||||
auto functionIdentifier = ((IdentifierToken*) functionIdentifierToken)->Value;
|
auto functionIdentifier = ((IdentifierToken*) functionIdentifierToken)->Value;
|
||||||
return new ParsedFunctionDeclarationStatement(HashedString(functionIdentifier), parameters, (ParsedBlockStatement*)block, start, block->GetEndPosition() - start);
|
return new ParsedFunctionDeclarationStatement(HashedString(functionIdentifier), parameters, (ParsedBlockStatement*)block, start, block->GetEndPosition() - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
ParsedStatement* Parser::ParseReturnStatement(IToken* current){
|
||||||
|
//TODO: if next token is on a different line, don't parse it as return expression.
|
||||||
|
auto expression = this->ParseExpression(this->Next());
|
||||||
|
auto start = current->GetStartPosition();
|
||||||
|
return new ParsedReturnStatement(expression, start, expression->GetEndPosition() - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
ParsedExpression* Parser::ParseExpression(IToken* current){
|
ParsedExpression* Parser::ParseExpression(IToken* current){
|
||||||
|
|
|
@ -29,6 +29,7 @@ class Parser {
|
||||||
ParsedStatement* ParseAssignment(IToken* current);
|
ParsedStatement* ParseAssignment(IToken* current);
|
||||||
ParsedStatement *ParseBlock(const vector<TokenKind>& endTokens);
|
ParsedStatement *ParseBlock(const vector<TokenKind>& endTokens);
|
||||||
ParsedStatement* ParseFunctionDeclaration(IToken* current);
|
ParsedStatement* ParseFunctionDeclaration(IToken* current);
|
||||||
|
ParsedStatement *ParseReturnStatement(IToken *current);
|
||||||
|
|
||||||
ParsedExpression* ParseExpression(IToken* current);
|
ParsedExpression* ParseExpression(IToken* current);
|
||||||
ParsedExpression* ParseBinaryExpression(IToken* current, OperatorPrecedence parentPrecedence);
|
ParsedExpression* ParseBinaryExpression(IToken* current, OperatorPrecedence parentPrecedence);
|
||||||
|
|
|
@ -72,7 +72,7 @@ bool Script::HasFunction(const string &key) {
|
||||||
return f != _scriptVariables->end() && f.operator->()->second->GetType()->GetClass() == TypeClass ::Function;
|
return f != _scriptVariables->end() && f.operator->()->second->GetType()->GetClass() == TypeClass ::Function;
|
||||||
}
|
}
|
||||||
|
|
||||||
EvalValue *Script::CallFunction(const string &key, vector<EvalValue *> variables) {
|
shared_ptr<EvalValue> Script::CallFunction(const string &key, vector<EvalValue *> variables) {
|
||||||
auto var = (ScriptFunctionEvalValue*)GetVariable(key);
|
auto var = (ScriptFunctionEvalValue*)GetVariable(key);
|
||||||
return this->_evaluator->EvaluateFunction(var, std::move(variables));
|
return this->_evaluator->EvaluateFunction(var, std::move(variables));
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ extern "C" {
|
||||||
|
|
||||||
EvalValue* CallFunction(Script* script, const char* key, EvalValue* parameters[], int parameterCount){
|
EvalValue* CallFunction(Script* script, const char* key, EvalValue* parameters[], int parameterCount){
|
||||||
std::vector<EvalValue*> v(parameters, parameters + parameterCount);
|
std::vector<EvalValue*> v(parameters, parameters + parameterCount);
|
||||||
return script->CallFunction(key, v);
|
return script->CallFunction(key, v).get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ class Script {
|
||||||
Evaluator* _evaluator;
|
Evaluator* _evaluator;
|
||||||
unordered_map<int, shared_ptr<EvalValue>>* _scriptVariables;
|
unordered_map<int, shared_ptr<EvalValue>>* _scriptVariables;
|
||||||
BoundScriptStatement* _boundScript;
|
BoundScriptStatement* _boundScript;
|
||||||
|
shared_ptr<ScriptType> _returnType;
|
||||||
|
|
||||||
explicit Script();
|
explicit Script();
|
||||||
void Parse(string script);
|
void Parse(string script);
|
||||||
|
@ -29,6 +30,10 @@ public:
|
||||||
|
|
||||||
~Script();
|
~Script();
|
||||||
|
|
||||||
|
shared_ptr<ScriptType> GetReturnType(){
|
||||||
|
return _returnType;
|
||||||
|
}
|
||||||
|
|
||||||
void Evaluate();
|
void Evaluate();
|
||||||
|
|
||||||
EvalValue* GetLastValue();
|
EvalValue* GetLastValue();
|
||||||
|
@ -36,10 +41,8 @@ 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);
|
shared_ptr<EvalValue> CallFunction(const string& key, vector<EvalValue*> variables);
|
||||||
bool HasFunction(const string& key);
|
bool HasFunction(const string& key);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -57,5 +57,32 @@ TEST_CASE( "Define script function and call from extern", "[integration]" ) {
|
||||||
delete script;
|
delete script;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE( "Define script function and return", "[integration]" ) {
|
||||||
|
Script* script = Script::Create(
|
||||||
|
"val = 0\n"
|
||||||
|
"function add(number a, number b) \n"
|
||||||
|
"return a + b \n"
|
||||||
|
"val = val + 1\n"
|
||||||
|
"end");
|
||||||
|
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||||
|
script->Evaluate();
|
||||||
|
|
||||||
|
REQUIRE(script->HasFunction("add"));
|
||||||
|
auto toAddVal = new IntegerEvalValue(5);
|
||||||
|
auto toAddVal2 = new IntegerEvalValue(6);
|
||||||
|
auto result = script->CallFunction("add", {toAddVal, toAddVal2});
|
||||||
|
delete toAddVal;
|
||||||
|
delete toAddVal2;
|
||||||
|
|
||||||
|
REQUIRE(result->GetType()->GetClass() == TypeClass::Number);
|
||||||
|
REQUIRE(result->EvaluateInteger() == 11);
|
||||||
|
|
||||||
|
auto variable = script->GetVariable("val");
|
||||||
|
REQUIRE(variable->GetType()->GetClass() == TypeClass::Number);
|
||||||
|
REQUIRE(variable->EvaluateInteger() == 0);
|
||||||
|
|
||||||
|
delete script;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue