Fixes for return statement, make Evaluate function on script return value
continuous-integration/drone/push Build was killed Details

This commit is contained in:
Deukhoofd 2019-06-12 18:45:47 +02:00
parent 3477ddd18c
commit 22149d9243
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
7 changed files with 31 additions and 16 deletions

View File

@ -101,6 +101,8 @@ BoundStatement *Binder::BindFunctionDeclarationStatement(ParsedStatement *statem
auto identifier = functionStatement->GetIdentifier(); auto identifier = functionStatement->GetIdentifier();
auto returnType = make_shared<ScriptType>(TypeClass::Nil); auto returnType = make_shared<ScriptType>(TypeClass::Nil);
auto type = make_shared<FunctionScriptType>(returnType, parameterTypes, parameterKeys, scopeIndex); auto type = make_shared<FunctionScriptType>(returnType, parameterTypes, parameterKeys, scopeIndex);
this->_currentFunction = type;
auto assignment = this->_scope->AssignVariable(identifier.GetHash(), type); auto assignment = this->_scope->AssignVariable(identifier.GetHash(), type);
if (assignment.GetResult() != VariableAssignmentResult::Ok){ if (assignment.GetResult() != VariableAssignmentResult::Ok){
this -> _scriptData -> Diagnostics -> LogError(DiagnosticCode::CantAssignVariable, statement->GetStartPosition(), statement->GetLength()); 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()); auto boundBlock = this -> BindBlockStatement(functionStatement->GetBlock());
this->_scope->GoOuterScope(); this->_scope->GoOuterScope();
this->_currentFunction = nullptr;
return new BoundFunctionDeclarationStatement(type, assignment.GetKey(), (BoundBlockStatement*)boundBlock); return new BoundFunctionDeclarationStatement(type, assignment.GetKey(), (BoundBlockStatement*)boundBlock);
} }
@ -117,7 +120,7 @@ BoundStatement *Binder::BindReturnStatement(ParsedStatement* statement){
if (this->_currentFunction == nullptr){ if (this->_currentFunction == nullptr){
currentReturnType = this->_scriptData->GetReturnType(); currentReturnType = this->_scriptData->GetReturnType();
} else{ } else{
currentReturnType = this->_currentFunction; currentReturnType = this->_currentFunction->GetReturnType();
} }
if (expression == nullptr && currentReturnType != nullptr){ if (expression == nullptr && currentReturnType != nullptr){
this -> _scriptData -> Diagnostics -> LogError(DiagnosticCode::InvalidReturnType, statement->GetStartPosition(), statement->GetLength()); 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 boundExpression = this->BindExpression(expression);
auto expresionType = boundExpression->GetType(); auto expresionType = boundExpression->GetType();
if (currentReturnType == nullptr){ if (currentReturnType == nullptr || currentReturnType->GetClass() == TypeClass::Nil){
currentReturnType.swap(expresionType); if (this->_currentFunction == nullptr){
this->_scriptData->SetReturnType(expresionType);
} else{
this->_currentFunction->SetReturnType(expresionType);
}
return new BoundReturnStatement(boundExpression); return new BoundReturnStatement(boundExpression);
} }
if (currentReturnType.get()->operator!=(expresionType.get())){ if (currentReturnType.get()->operator!=(expresionType.get())){

View File

@ -11,9 +11,10 @@
using namespace std; using namespace std;
void Evaluator::Evaluate(BoundScriptStatement *statement) { EvalValue* Evaluator::Evaluate(BoundScriptStatement *statement) {
this->_evaluationScope = make_shared<EvaluationScope>(this->_scriptData->_scriptVariables, statement->GetDeepestScope()); this->_evaluationScope = make_shared<EvaluationScope>(this->_scriptData->_scriptVariables, statement->GetDeepestScope());
EvaluateBlockStatement(statement, false); EvaluateBlockStatement(statement, false);
return this -> _returnValue.get();
} }
void Evaluator::EvaluateStatement(BoundStatement *statement) { void Evaluator::EvaluateStatement(BoundStatement *statement) {
@ -73,11 +74,12 @@ void Evaluator::EvaluateFunctionDeclarationStatement(BoundFunctionDeclarationSta
void Evaluator::EvaluateReturnStatement(BoundReturnStatement* statement){ void Evaluator::EvaluateReturnStatement(BoundReturnStatement* statement){
auto expression = statement->GetExpression(); auto expression = statement->GetExpression();
this->_hasReturned = true;
if (expression == nullptr){ if (expression == nullptr){
this->_hasReturned = true;
return; return;
} }
auto value = this -> EvaluateExpression(expression); auto value = this -> EvaluateExpression(expression);
this->_hasReturned = true;
this -> _returnValue = value; this -> _returnValue = value;
} }

View File

@ -47,6 +47,7 @@ class Evaluator {
shared_ptr<EvalValue> EvaluateFunctionCallExpression(BoundExpression *expression); shared_ptr<EvalValue> EvaluateFunctionCallExpression(BoundExpression *expression);
shared_ptr<EvalValue> EvaluateIndexExpression(BoundExpression* expression); shared_ptr<EvalValue> EvaluateIndexExpression(BoundExpression* expression);
shared_ptr<EvalValue> EvaluateNumericTableExpression(BoundExpression* expression); shared_ptr<EvalValue> EvaluateNumericTableExpression(BoundExpression* expression);
shared_ptr<EvalValue> EvaluateComplexTableExpression(BoundExpression *expression);
shared_ptr<EvalValue> GetVariable(BoundVariableExpression *expression); shared_ptr<EvalValue> GetVariable(BoundVariableExpression *expression);
public: public:
@ -57,14 +58,13 @@ public:
_evaluationScope = nullptr; _evaluationScope = nullptr;
} }
void Evaluate(BoundScriptStatement* statement); EvalValue* Evaluate(BoundScriptStatement* statement);
shared_ptr<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();
} }
shared_ptr<EvalValue> EvaluateComplexTableExpression(BoundExpression *expression);
}; };

View File

@ -20,8 +20,8 @@ Script::Script() {
_scriptVariables = new unordered_map<size_t, shared_ptr<EvalValue>>(0); _scriptVariables = new unordered_map<size_t, shared_ptr<EvalValue>>(0);
} }
void Script::Evaluate() { EvalValue* Script::Evaluate() {
_evaluator->Evaluate(_boundScript); return _evaluator->Evaluate(_boundScript);
} }
Script::~Script() { Script::~Script() {

View File

@ -34,7 +34,11 @@ public:
return _returnType; return _returnType;
} }
void Evaluate(); void SetReturnType(shared_ptr<ScriptType> t){
_returnType = t;
}
EvalValue* Evaluate();
EvalValue* GetLastValue(); EvalValue* GetLastValue();

View File

@ -110,6 +110,10 @@ public:
return _returnType; return _returnType;
} }
void SetReturnType(shared_ptr<ScriptType> t){
_returnType = t;
}
vector<shared_ptr<ScriptType>> GetParameterTypes(){ vector<shared_ptr<ScriptType>> GetParameterTypes(){
return _parameterTypes; return _parameterTypes;
} }

View File

@ -34,11 +34,10 @@ TEST_CASE( "Index string table", "[integration]" ) {
Script* script = Script::Create( Script* script = Script::Create(
R"( R"(
table = {'bla', 'test', 'foo', 'bar'} table = {'bla', 'test', 'foo', 'bar'}
result = table[3] return table[3]
)"); )");
REQUIRE(!script->Diagnostics -> HasErrors()); REQUIRE(!script->Diagnostics -> HasErrors());
script->Evaluate(); auto variable = script->Evaluate();
auto variable = script->GetVariable("result");
REQUIRE(variable != nullptr); REQUIRE(variable != nullptr);
REQUIRE(*variable->EvaluateString() == "foo"); REQUIRE(*variable->EvaluateString() == "foo");
delete script; delete script;
@ -71,11 +70,10 @@ table = {
return foo return foo
end end
} }
result = table["getFoo"]() return table["getFoo"]()
)"); )");
REQUIRE(!script->Diagnostics -> HasErrors()); REQUIRE(!script->Diagnostics -> HasErrors());
script->Evaluate(); auto variable = script->Evaluate();
auto variable = script->GetVariable("result");
REQUIRE(variable != nullptr); REQUIRE(variable != nullptr);
delete script; delete script;
} }