Handle bound classes as constants during evaluation
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2019-06-13 17:12:46 +02:00
parent 1cb65f17c9
commit 10a2535c96
12 changed files with 225 additions and 204 deletions

View File

@@ -5,7 +5,7 @@
#include "EvalValues/NumericEvalValue.hpp"
#include "EvalValues/StringEvalValue.hpp"
shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerBinary(BoundBinaryExpression *expression) {
shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerBinary(const BoundBinaryExpression *expression) {
auto leftValue = this -> EvaluateIntegerExpression(expression->GetLeft());
auto rightValue = this -> EvaluateIntegerExpression(expression->GetRight());
@@ -29,7 +29,7 @@ shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerBinary(BoundBinaryExpress
return shared_ptr<NumericEvalValue>(result);
}
shared_ptr<BooleanEvalValue> Evaluator::EvaluateBooleanBinary(BoundBinaryExpression* expression){
shared_ptr<BooleanEvalValue> Evaluator::EvaluateBooleanBinary(const BoundBinaryExpression* expression){
switch (expression->GetOperation()){
case BoundBinaryOperation::Equality:
{
@@ -93,7 +93,7 @@ shared_ptr<BooleanEvalValue> Evaluator::EvaluateBooleanBinary(BoundBinaryExpress
}
}
shared_ptr<StringEvalValue> Evaluator::EvaluateStringBinary(BoundBinaryExpression* expression){
shared_ptr<StringEvalValue> Evaluator::EvaluateStringBinary(const BoundBinaryExpression* expression){
if (expression->GetOperation() != BoundBinaryOperation::Concatenation)
throw;
std::ostringstream strs;

View File

@@ -38,7 +38,7 @@ public:
_hash = rand();
}
std::shared_ptr<ScriptType> GetType(){
std::shared_ptr<ScriptType> GetType() const{
return _type;
}
@@ -57,7 +57,7 @@ public:
return this->_hash == ((ScriptFunctionEvalValue*)b)->_hash;
};
std::shared_ptr<BoundBlockStatement> GetInnerBlock(){
std::shared_ptr<BoundBlockStatement> GetInnerBlock() const{
return _innerBlock;
}
@@ -65,7 +65,7 @@ public:
return _hash;
}
std::shared_ptr<EvaluationScope> GetScope(){
std::shared_ptr<EvaluationScope> GetScope() const{
return _scope;
}
};

View File

@@ -7,7 +7,7 @@ EvaluationScope::EvaluationScope(unordered_map<size_t, shared_ptr<EvalValue>> *s
_localScope = unordered_map<uint64_t, shared_ptr<EvalValue>>(localVariableCount);
}
void EvaluationScope::CreateVariable(BoundVariableKey* key, const shared_ptr<EvalValue> &value) {
void EvaluationScope::CreateVariable(const BoundVariableKey* key, const shared_ptr<EvalValue> &value) {
if (key->GetScopeId() == 0){
_scriptScope -> at(key->GetIdentifier()) = value;
} else{
@@ -18,7 +18,7 @@ void EvaluationScope::CreateVariable(BoundVariableKey* key, const shared_ptr<Eva
}
}
void EvaluationScope::SetVariable(BoundVariableKey* key, const shared_ptr<EvalValue> &value) {
void EvaluationScope::SetVariable(const BoundVariableKey* key, const shared_ptr<EvalValue> &value) {
if (key->GetScopeId() == 0){
_scriptScope -> at(key->GetIdentifier()) = value;
} else{
@@ -26,7 +26,7 @@ void EvaluationScope::SetVariable(BoundVariableKey* key, const shared_ptr<EvalVa
}
}
shared_ptr<EvalValue> EvaluationScope::GetVariable(BoundVariableKey* key) {
shared_ptr<EvalValue> EvaluationScope::GetVariable(const BoundVariableKey* key) {
if (key->GetScopeId() == 0){
return _scriptScope -> at(key->GetIdentifier());
} else{

View File

@@ -13,9 +13,9 @@ public:
explicit EvaluationScope(unordered_map<size_t, shared_ptr<EvalValue>>* scriptVariables, int deepestScope);
~EvaluationScope() = default;
void CreateVariable(BoundVariableKey* key, const shared_ptr<EvalValue>& value);
void SetVariable(BoundVariableKey* key, const shared_ptr<EvalValue>& value);
shared_ptr<EvalValue> GetVariable(BoundVariableKey* key);
void CreateVariable(const BoundVariableKey* key, const shared_ptr<EvalValue>& value);
void SetVariable(const BoundVariableKey* key, const shared_ptr<EvalValue>& value);
shared_ptr<EvalValue> GetVariable(const BoundVariableKey* key);
};

View File

@@ -13,18 +13,18 @@
using namespace std;
EvalValue* Evaluator::Evaluate(BoundScriptStatement *statement) {
EvalValue* Evaluator::Evaluate(const BoundScriptStatement *statement) {
this->_evaluationScope = make_shared<EvaluationScope>(this->_scriptData->_scriptVariables, statement->GetLocalVariableCount());
EvaluateBlockStatement(statement, false);
EvaluateBlockStatement(statement);
return this -> _returnValue.get();
}
void Evaluator::EvaluateStatement(BoundStatement *statement) {
void Evaluator::EvaluateStatement(const BoundStatement *statement) {
if (this->_hasReturned)
return;
switch (statement->GetKind()){
case BoundStatementKind ::Script: throw; // Should never happen
case BoundStatementKind ::Block: return this -> EvaluateBlockStatement((BoundBlockStatement*)statement, true);
case BoundStatementKind ::Block: return this->EvaluateBlockStatement((BoundBlockStatement *) statement);
case BoundStatementKind ::Expression: return this -> EvaluateExpressionStatement((BoundExpressionStatement*)statement);
case BoundStatementKind ::Assignment: return this -> EvaluateAssignmentStatement((BoundAssignmentStatement*)statement);
case BoundStatementKind ::FunctionDeclaration: return this->EvaluateFunctionDeclarationStatement((BoundFunctionDeclarationStatement*)statement);
@@ -36,20 +36,20 @@ void Evaluator::EvaluateStatement(BoundStatement *statement) {
}
}
void Evaluator::EvaluateBlockStatement(BoundBlockStatement* statement, bool clearScope) {
for (auto s: statement->GetStatements()){
void Evaluator::EvaluateBlockStatement(const BoundBlockStatement *statement) {
for (auto s: *statement->GetStatements()){
this -> EvaluateStatement(s);
if (this->_hasReturned)
break;
}
}
void Evaluator::EvaluateExpressionStatement(BoundExpressionStatement *statement) {
void Evaluator::EvaluateExpressionStatement(const BoundExpressionStatement *statement) {
// Save new value
this->_lastValue = this -> EvaluateExpression(statement->GetExpression());
}
void Evaluator::EvaluateAssignmentStatement(BoundAssignmentStatement *statement) {
void Evaluator::EvaluateAssignmentStatement(const BoundAssignmentStatement *statement) {
auto value = this -> EvaluateExpression(statement->GetExpression());
auto key = statement->GetKey();
if (key->IsCreation()){
@@ -59,7 +59,7 @@ void Evaluator::EvaluateAssignmentStatement(BoundAssignmentStatement *statement)
}
}
void Evaluator::EvaluateFunctionDeclarationStatement(BoundFunctionDeclarationStatement *statement) {
void Evaluator::EvaluateFunctionDeclarationStatement(const BoundFunctionDeclarationStatement *statement) {
auto type = statement->GetType();
auto key = statement->GetKey();
auto block = statement->GetBlock();
@@ -71,7 +71,7 @@ void Evaluator::EvaluateFunctionDeclarationStatement(BoundFunctionDeclarationSta
}
}
void Evaluator::EvaluateReturnStatement(BoundReturnStatement* statement){
void Evaluator::EvaluateReturnStatement(const BoundReturnStatement* statement){
auto expression = statement->GetExpression();
if (expression == nullptr){
this->_hasReturned = true;
@@ -82,7 +82,7 @@ void Evaluator::EvaluateReturnStatement(BoundReturnStatement* statement){
this -> _returnValue = value;
}
void Evaluator::EvaluateConditionalStatement(BoundConditionalStatement *statement) {
void Evaluator::EvaluateConditionalStatement(const BoundConditionalStatement *statement) {
auto condition = statement->GetCondition();
if (EvaluateBoolExpression(condition) -> EvaluateBool()){
this -> EvaluateStatement(statement->GetBlock());
@@ -94,7 +94,7 @@ void Evaluator::EvaluateConditionalStatement(BoundConditionalStatement *statemen
}
}
shared_ptr<EvalValue> Evaluator::EvaluateExpression(BoundExpression *expression) {
shared_ptr<EvalValue> Evaluator::EvaluateExpression(const BoundExpression *expression) {
auto type = expression -> GetType();
switch (type->GetClass()){
case TypeClass ::Number: return this -> EvaluateIntegerExpression(expression);
@@ -107,7 +107,7 @@ shared_ptr<EvalValue> Evaluator::EvaluateExpression(BoundExpression *expression)
}
}
shared_ptr<EvalValue> Evaluator::GetVariable(BoundVariableExpression* expression){
shared_ptr<EvalValue> Evaluator::GetVariable(const BoundVariableExpression* expression){
auto variable = this->_evaluationScope->GetVariable(expression->GetKey());
if (variable == nullptr){
throw EvaluationException("Variable not found");
@@ -115,7 +115,7 @@ shared_ptr<EvalValue> Evaluator::GetVariable(BoundVariableExpression* expression
return variable->Clone();
}
shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerExpression(BoundExpression *expression) {
shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerExpression(const BoundExpression *expression) {
switch (expression->GetKind()){
case BoundExpressionKind ::LiteralInteger: return make_shared<IntegerEvalValue>(((BoundLiteralIntegerExpression*)expression)->GetValue());
case BoundExpressionKind ::LiteralFloat: return make_shared<FloatEvalValue>(((BoundLiteralFloatExpression*)expression)->GetValue());
@@ -134,7 +134,7 @@ shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerExpression(BoundExpressio
}
}
shared_ptr<BooleanEvalValue> Evaluator::EvaluateBoolExpression(BoundExpression *expression) {
shared_ptr<BooleanEvalValue> Evaluator::EvaluateBoolExpression(const BoundExpression *expression) {
switch (expression->GetKind()) {
case BoundExpressionKind ::LiteralBool: return make_shared<BooleanEvalValue>(((BoundLiteralBoolExpression*)expression)->GetValue());
case BoundExpressionKind::Unary: return this -> EvaluateBooleanUnary((BoundUnaryExpression*)expression);
@@ -154,7 +154,7 @@ shared_ptr<BooleanEvalValue> Evaluator::EvaluateBoolExpression(BoundExpression *
}
}
shared_ptr<StringEvalValue> Evaluator::EvaluateStringExpression(BoundExpression *expression) {
shared_ptr<StringEvalValue> Evaluator::EvaluateStringExpression(const BoundExpression *expression) {
switch (expression->GetKind()) {
case BoundExpressionKind ::LiteralString:
return make_shared<StringEvalValue>(((BoundLiteralStringExpression*)expression)->GetValue());
@@ -176,14 +176,14 @@ shared_ptr<StringEvalValue> Evaluator::EvaluateStringExpression(BoundExpression
}
}
shared_ptr<EvalValue> Evaluator::EvaluateFunctionExpression(BoundExpression * expression){
shared_ptr<EvalValue> Evaluator::EvaluateFunctionExpression(const BoundExpression * expression){
switch (expression->GetKind()){
case BoundExpressionKind ::Variable: return this->GetVariable((BoundVariableExpression*)expression);
case BoundExpressionKind ::Index: return this->EvaluateIndexExpression(expression);
default: throw;
}
}
shared_ptr<EvalValue> Evaluator::EvaluateNilExpression(BoundExpression * expression){
shared_ptr<EvalValue> Evaluator::EvaluateNilExpression(const BoundExpression * expression){
switch (expression->GetKind()){
case BoundExpressionKind ::FunctionCall:
return this->EvaluateFunctionCallExpression(expression);
@@ -191,7 +191,7 @@ shared_ptr<EvalValue> Evaluator::EvaluateNilExpression(BoundExpression * express
return nullptr;
}
}
shared_ptr<EvalValue> Evaluator::EvaluateTableExpression(BoundExpression * expression){
shared_ptr<EvalValue> Evaluator::EvaluateTableExpression(const BoundExpression * expression){
switch (expression->GetKind()){
case BoundExpressionKind ::FunctionCall:
return this->EvaluateFunctionCallExpression(expression);
@@ -207,14 +207,14 @@ shared_ptr<EvalValue> Evaluator::EvaluateTableExpression(BoundExpression * expre
shared_ptr<EvalValue> Evaluator::EvaluateFunctionCallExpression(BoundExpression* expression){
shared_ptr<EvalValue> Evaluator::EvaluateFunctionCallExpression(const BoundExpression* expression){
auto functionCall = (BoundFunctionCallExpression*)expression;
auto function = dynamic_pointer_cast<ScriptFunctionEvalValue>(this->EvaluateExpression(functionCall->GetFunctionExpression()));
auto boundParameters = functionCall->GetParameters();
auto parameters = vector<shared_ptr<EvalValue>>(boundParameters.size());
for (int i = 0; i < boundParameters.size(); i++){
parameters[i] = this->EvaluateExpression(boundParameters[i]);
auto parameters = vector<shared_ptr<EvalValue>>(boundParameters->size());
for (int i = 0; i < boundParameters->size(); i++){
parameters[i] = this->EvaluateExpression(boundParameters->at(i));
}
auto type = std::dynamic_pointer_cast<FunctionScriptType>(function->GetType());
@@ -228,7 +228,7 @@ shared_ptr<EvalValue> Evaluator::EvaluateFunctionCallExpression(BoundExpression*
auto key = parameterKeys.at(i);
this->_evaluationScope->CreateVariable(key.get(), parameter->Clone());
}
this->EvaluateBlockStatement(function->GetInnerBlock().get(), true);
this->EvaluateBlockStatement(function->GetInnerBlock().get());
this->_evaluationScope = originalScope;
this->_hasReturned = false;
@@ -237,7 +237,7 @@ shared_ptr<EvalValue> Evaluator::EvaluateFunctionCallExpression(BoundExpression*
return r;
}
shared_ptr<EvalValue> Evaluator::EvaluateFunction(ScriptFunctionEvalValue *function, vector<EvalValue *> parameters) {
shared_ptr<EvalValue> Evaluator::EvaluateFunction(const ScriptFunctionEvalValue *function, const vector<EvalValue *>& parameters) {
auto type = std::dynamic_pointer_cast<FunctionScriptType>(function->GetType());
auto parameterTypes = type->GetParameterTypes();
auto parameterKeys = type->GetParameterKeys();
@@ -250,7 +250,7 @@ shared_ptr<EvalValue> Evaluator::EvaluateFunction(ScriptFunctionEvalValue *funct
auto key = parameterKeys.at(i);
this->_evaluationScope->CreateVariable(key.get(), parameter->Clone());
}
this->EvaluateBlockStatement(function->GetInnerBlock().get(), true);
this->EvaluateBlockStatement(function->GetInnerBlock().get());
this->_evaluationScope = originalScope;
this->_hasReturned = false;
auto r = this -> _returnValue;
@@ -258,26 +258,26 @@ shared_ptr<EvalValue> Evaluator::EvaluateFunction(ScriptFunctionEvalValue *funct
return r;
}
shared_ptr<EvalValue> Evaluator::EvaluateIndexExpression(BoundExpression *expression) {
shared_ptr<EvalValue> Evaluator::EvaluateIndexExpression(const BoundExpression *expression) {
auto indexExpression = (BoundIndexExpression*)expression;
auto index = this -> EvaluateExpression(indexExpression->GetIndexExpression());
auto indexable = this -> EvaluateExpression(indexExpression->GetIndexableExpression());
return indexable -> IndexValue(index.get()) -> Clone();
}
shared_ptr<EvalValue> Evaluator::EvaluateNumericTableExpression(BoundExpression *expression) {
shared_ptr<EvalValue> Evaluator::EvaluateNumericTableExpression(const BoundExpression *expression) {
auto tableExpression = (BoundNumericalTableExpression*)expression;
auto valueExpressions = tableExpression->GetExpressions();
auto values = new unordered_map<size_t, shared_ptr<EvalValue>>(valueExpressions.size());
for (int i = 0; i < valueExpressions.size(); i++){
auto val = this -> EvaluateExpression(valueExpressions[i]);
auto values = new unordered_map<size_t, shared_ptr<EvalValue>>(valueExpressions->size());
for (int i = 0; i < valueExpressions->size(); i++){
auto val = this -> EvaluateExpression(valueExpressions -> at(i));
values -> insert({i + 1, val});
}
auto valuesPointer = shared_ptr<unordered_map<size_t, shared_ptr<EvalValue>>>(values);
return make_shared<TableEvalValue>(valuesPointer);
}
shared_ptr<EvalValue> Evaluator::EvaluateComplexTableExpression(BoundExpression *expression) {
shared_ptr<EvalValue> Evaluator::EvaluateComplexTableExpression(const BoundExpression *expression) {
auto tableExpression = (BoundTableExpression*)expression;
auto type = dynamic_pointer_cast<TableScriptType>(tableExpression->GetType());
auto declaredVars = type -> GetValues();
@@ -288,7 +288,7 @@ shared_ptr<EvalValue> Evaluator::EvaluateComplexTableExpression(BoundExpression
auto evaluator = make_shared<EvaluationScope>(variables.get(), type -> GetLocalVariableCount());
auto currentEvaluator = this -> _evaluationScope;
this -> _evaluationScope = evaluator;
this -> EvaluateBlockStatement(tableExpression->GetBlock(), false);
this->EvaluateBlockStatement(tableExpression->GetBlock());
this -> _evaluationScope = currentEvaluator;
return make_shared<TableEvalValue>(variables);
}

View File

@@ -22,34 +22,34 @@ class Evaluator {
Script* _scriptData;
shared_ptr<EvaluationScope> _evaluationScope;
void EvaluateStatement(BoundStatement* statement);
void EvaluateBlockStatement(BoundBlockStatement* statement, bool clearScope);
void EvaluateExpressionStatement(BoundExpressionStatement* statement);
void EvaluateAssignmentStatement(BoundAssignmentStatement* statement);
void EvaluateFunctionDeclarationStatement(BoundFunctionDeclarationStatement *statement);
void EvaluateReturnStatement(BoundReturnStatement *statement);
void EvaluateConditionalStatement(BoundConditionalStatement *statement);
void EvaluateStatement(const BoundStatement* statement);
void EvaluateBlockStatement(const BoundBlockStatement *statement);
void EvaluateExpressionStatement(const BoundExpressionStatement* statement);
void EvaluateAssignmentStatement(const BoundAssignmentStatement* statement);
void EvaluateFunctionDeclarationStatement(const BoundFunctionDeclarationStatement *statement);
void EvaluateReturnStatement(const BoundReturnStatement *statement);
void EvaluateConditionalStatement(const BoundConditionalStatement *statement);
shared_ptr<EvalValue> EvaluateExpression(BoundExpression* expression);
shared_ptr<NumericEvalValue> EvaluateIntegerExpression(BoundExpression* expression);
shared_ptr<BooleanEvalValue> EvaluateBoolExpression(BoundExpression* expression);
shared_ptr<StringEvalValue> EvaluateStringExpression(BoundExpression* expression);
shared_ptr<EvalValue> EvaluateFunctionExpression(BoundExpression *expression);
shared_ptr<EvalValue>EvaluateNilExpression(BoundExpression *expression);
shared_ptr<EvalValue>EvaluateTableExpression(BoundExpression *expression);
shared_ptr<EvalValue> EvaluateExpression(const BoundExpression* expression);
shared_ptr<NumericEvalValue> EvaluateIntegerExpression(const BoundExpression* expression);
shared_ptr<BooleanEvalValue> EvaluateBoolExpression(const BoundExpression* expression);
shared_ptr<StringEvalValue> EvaluateStringExpression(const BoundExpression* expression);
shared_ptr<EvalValue> EvaluateFunctionExpression(const BoundExpression *expression);
shared_ptr<EvalValue>EvaluateNilExpression(const BoundExpression *expression);
shared_ptr<EvalValue>EvaluateTableExpression(const BoundExpression *expression);
shared_ptr<NumericEvalValue> EvaluateIntegerBinary(BoundBinaryExpression* expression);
shared_ptr<BooleanEvalValue> EvaluateBooleanBinary(BoundBinaryExpression *expression);
shared_ptr<StringEvalValue> EvaluateStringBinary(BoundBinaryExpression *expression);
shared_ptr<NumericEvalValue> EvaluateIntegerBinary(const BoundBinaryExpression* expression);
shared_ptr<BooleanEvalValue> EvaluateBooleanBinary(const BoundBinaryExpression *expression);
shared_ptr<StringEvalValue> EvaluateStringBinary(const BoundBinaryExpression *expression);
shared_ptr<NumericEvalValue> EvaluateIntegerUnary(BoundUnaryExpression* expression);
shared_ptr<BooleanEvalValue> EvaluateBooleanUnary(BoundUnaryExpression *expression);
shared_ptr<EvalValue> EvaluateFunctionCallExpression(BoundExpression *expression);
shared_ptr<EvalValue> EvaluateIndexExpression(BoundExpression* expression);
shared_ptr<EvalValue> EvaluateNumericTableExpression(BoundExpression* expression);
shared_ptr<EvalValue> EvaluateComplexTableExpression(BoundExpression *expression);
shared_ptr<NumericEvalValue> EvaluateIntegerUnary(const BoundUnaryExpression* expression);
shared_ptr<BooleanEvalValue> EvaluateBooleanUnary(const BoundUnaryExpression *expression);
shared_ptr<EvalValue> EvaluateFunctionCallExpression(const BoundExpression *expression);
shared_ptr<EvalValue> EvaluateIndexExpression(const BoundExpression* expression);
shared_ptr<EvalValue> EvaluateNumericTableExpression(const BoundExpression* expression);
shared_ptr<EvalValue> EvaluateComplexTableExpression(const BoundExpression *expression);
shared_ptr<EvalValue> GetVariable(BoundVariableExpression *expression);
shared_ptr<EvalValue> GetVariable(const BoundVariableExpression *expression);
public:
explicit Evaluator(Script* script){
_scriptData = script;
@@ -58,8 +58,8 @@ public:
_evaluationScope = nullptr;
}
EvalValue* Evaluate(BoundScriptStatement* statement);
shared_ptr<EvalValue> EvaluateFunction(ScriptFunctionEvalValue* func, vector<EvalValue*> parameters);
EvalValue* Evaluate(const BoundScriptStatement* statement);
shared_ptr<EvalValue> EvaluateFunction(const ScriptFunctionEvalValue *function, const vector<EvalValue *>& parameters);
EvalValue* GetLastValue(){
return _lastValue.get();

View File

@@ -4,7 +4,7 @@
#include "EvaluationException.hpp"
#include "../Script.hpp"
shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerUnary(BoundUnaryExpression *expression) {
shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerUnary(const BoundUnaryExpression *expression) {
switch (expression->GetOperation()){
case BoundUnaryOperation::Negation:
{
@@ -22,7 +22,7 @@ shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerUnary(BoundUnaryExpressio
}
}
shared_ptr<BooleanEvalValue> Evaluator::EvaluateBooleanUnary(BoundUnaryExpression *expression) {
shared_ptr<BooleanEvalValue> Evaluator::EvaluateBooleanUnary(const BoundUnaryExpression *expression) {
switch (expression->GetOperation()){
case BoundUnaryOperation::LogicalNegation:
{