This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
#include "Evaluator.hpp"
|
||||
#include "EvaluationException.hpp"
|
||||
#include "../Script.hpp"
|
||||
#include "EvaluationScope/EvaluationScope.hpp"
|
||||
#include "EvalValues/ScriptFunctionEvalValue.hpp"
|
||||
#include "EvalValues/TableEvalValue.hpp"
|
||||
@@ -11,17 +9,15 @@
|
||||
#include "../Binder/BoundExpressions/BoundFunctionCallExpression.hpp"
|
||||
#include "../TableScriptType.hpp"
|
||||
#include "../UserData/UserDataFunction.hpp"
|
||||
#include "../Utilities/StringUtils.hpp"
|
||||
#include "EvalValues/NumericalTableEvalValue.hpp"
|
||||
#include "../FunctionScriptType.hpp"
|
||||
#include "../Utilities/Random.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Porygon::Binder;
|
||||
|
||||
namespace Porygon::Evaluation {
|
||||
EvalValue *Evaluator::Evaluate(const BoundScriptStatement *statement) {
|
||||
this->_evaluationScope = make_shared<EvaluationScope>(this->_scriptVariables,
|
||||
statement->GetLocalVariableCount());
|
||||
const EvalValue *Evaluator::Evaluate(const BoundScriptStatement *statement) {
|
||||
this->_evaluationScope = make_shared<EvaluationScope>(this->_scriptVariables);
|
||||
EvaluateBlockStatement(statement);
|
||||
return this->_returnValue.get();
|
||||
}
|
||||
@@ -101,11 +97,11 @@ namespace Porygon::Evaluation {
|
||||
auto option = new Evaluation::EvaluationScriptFunctionOption(block, this->_evaluationScope);
|
||||
|
||||
if (key->IsCreation()) {
|
||||
auto value = make_shared<GenericFunctionEvalValue>(type, rand());
|
||||
auto value = make_shared<GenericFunctionEvalValue>(type, Utilities::Random::Get());
|
||||
value->RegisterOption(option);
|
||||
this->_evaluationScope->CreateVariable(key, value);
|
||||
} else {
|
||||
auto var = dynamic_pointer_cast<GenericFunctionEvalValue>(this -> _evaluationScope ->GetVariable(key));
|
||||
auto var = dynamic_pointer_cast<const GenericFunctionEvalValue>(this -> _evaluationScope ->GetVariable(key));
|
||||
var->RegisterOption(option);
|
||||
this->_evaluationScope->SetVariable(key, var);
|
||||
}
|
||||
@@ -223,7 +219,7 @@ namespace Porygon::Evaluation {
|
||||
// Expressions //
|
||||
/////////////////
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateExpression(const BoundExpression *expression) {
|
||||
shared_ptr<const EvalValue> Evaluator::EvaluateExpression(const BoundExpression *expression) {
|
||||
auto type = expression->GetType();
|
||||
switch (type->GetClass()) {
|
||||
case TypeClass::Number:
|
||||
@@ -245,7 +241,7 @@ namespace Porygon::Evaluation {
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::GetVariable(const BoundVariableExpression *expression) {
|
||||
shared_ptr<const EvalValue> Evaluator::GetVariable(const BoundVariableExpression *expression) {
|
||||
auto variable = this->_evaluationScope->GetVariable(expression->GetKey());
|
||||
if (variable == nullptr) {
|
||||
throw EvaluationException("Variable not found");
|
||||
@@ -253,7 +249,7 @@ namespace Porygon::Evaluation {
|
||||
return variable->Clone();
|
||||
}
|
||||
|
||||
const shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerExpression(const BoundExpression *expression) {
|
||||
shared_ptr<const NumericEvalValue> Evaluator::EvaluateIntegerExpression(const BoundExpression *expression) {
|
||||
switch (expression->GetKind()) {
|
||||
case BoundExpressionKind::LiteralInteger:
|
||||
return make_shared<IntegerEvalValue>(((BoundLiteralIntegerExpression *) expression)->GetValue());
|
||||
@@ -264,21 +260,21 @@ namespace Porygon::Evaluation {
|
||||
case BoundExpressionKind::Binary:
|
||||
return this->EvaluateIntegerBinary((BoundBinaryExpression *) expression);
|
||||
case BoundExpressionKind::Variable:
|
||||
return dynamic_pointer_cast<NumericEvalValue>(
|
||||
return dynamic_pointer_cast<const NumericEvalValue>(
|
||||
this->GetVariable((BoundVariableExpression *) expression));
|
||||
case BoundExpressionKind::FunctionCall:
|
||||
return dynamic_pointer_cast<NumericEvalValue>(this->EvaluateFunctionCallExpression(expression));
|
||||
return dynamic_pointer_cast<const NumericEvalValue>(this->EvaluateFunctionCallExpression(expression));
|
||||
case BoundExpressionKind::Index:
|
||||
return dynamic_pointer_cast<NumericEvalValue>(this->EvaluateIndexExpression(expression));
|
||||
return dynamic_pointer_cast<const NumericEvalValue>(this->EvaluateIndexExpression(expression));
|
||||
case BoundExpressionKind::PeriodIndex:
|
||||
return dynamic_pointer_cast<NumericEvalValue>(this->EvaluatePeriodIndexExpression(expression));
|
||||
return dynamic_pointer_cast<const NumericEvalValue>(this->EvaluatePeriodIndexExpression(expression));
|
||||
|
||||
default:
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<BooleanEvalValue> Evaluator::EvaluateBoolExpression(const BoundExpression *expression) {
|
||||
shared_ptr<const BooleanEvalValue> Evaluator::EvaluateBoolExpression(const BoundExpression *expression) {
|
||||
switch (expression->GetKind()) {
|
||||
case BoundExpressionKind::LiteralBool:
|
||||
return make_shared<BooleanEvalValue>(((BoundLiteralBoolExpression *) expression)->GetValue());
|
||||
@@ -287,14 +283,14 @@ namespace Porygon::Evaluation {
|
||||
case BoundExpressionKind::Binary:
|
||||
return this->EvaluateBooleanBinary((BoundBinaryExpression *) expression);
|
||||
case BoundExpressionKind::Variable:
|
||||
return dynamic_pointer_cast<BooleanEvalValue>(
|
||||
return dynamic_pointer_cast<const BooleanEvalValue>(
|
||||
this->GetVariable((BoundVariableExpression *) expression));
|
||||
case BoundExpressionKind::FunctionCall:
|
||||
return dynamic_pointer_cast<BooleanEvalValue>(this->EvaluateFunctionCallExpression(expression));
|
||||
return dynamic_pointer_cast<const BooleanEvalValue>(this->EvaluateFunctionCallExpression(expression));
|
||||
case BoundExpressionKind::Index:
|
||||
return dynamic_pointer_cast<BooleanEvalValue>(this->EvaluateIndexExpression(expression));
|
||||
return dynamic_pointer_cast<const BooleanEvalValue>(this->EvaluateIndexExpression(expression));
|
||||
case BoundExpressionKind::PeriodIndex:
|
||||
return dynamic_pointer_cast<BooleanEvalValue>(this->EvaluatePeriodIndexExpression(expression));
|
||||
return dynamic_pointer_cast<const BooleanEvalValue>(this->EvaluatePeriodIndexExpression(expression));
|
||||
|
||||
default:
|
||||
throw;
|
||||
@@ -302,20 +298,20 @@ namespace Porygon::Evaluation {
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<StringEvalValue> Evaluator::EvaluateStringExpression(const BoundExpression *expression) {
|
||||
shared_ptr<const StringEvalValue> Evaluator::EvaluateStringExpression(const BoundExpression *expression) {
|
||||
switch (expression->GetKind()) {
|
||||
case BoundExpressionKind::LiteralString:
|
||||
return make_shared<StringEvalValue>(((BoundLiteralStringExpression *) expression)->GetValue());
|
||||
return make_shared<StringEvalValue>(*((BoundLiteralStringExpression *) expression)->GetValue());
|
||||
case BoundExpressionKind::Binary:
|
||||
return this->EvaluateStringBinary((BoundBinaryExpression *) expression);
|
||||
case BoundExpressionKind::Variable:
|
||||
return dynamic_pointer_cast<StringEvalValue>(this->GetVariable((BoundVariableExpression *) expression));
|
||||
return dynamic_pointer_cast<const StringEvalValue>(this->GetVariable((BoundVariableExpression *) expression));
|
||||
case BoundExpressionKind::FunctionCall:
|
||||
return dynamic_pointer_cast<StringEvalValue>(this->EvaluateFunctionCallExpression(expression));
|
||||
return dynamic_pointer_cast<const StringEvalValue>(this->EvaluateFunctionCallExpression(expression));
|
||||
case BoundExpressionKind::Index:
|
||||
return dynamic_pointer_cast<StringEvalValue>(this->EvaluateIndexExpression(expression));
|
||||
return dynamic_pointer_cast<const StringEvalValue>(this->EvaluateIndexExpression(expression));
|
||||
case BoundExpressionKind::PeriodIndex:
|
||||
return dynamic_pointer_cast<StringEvalValue>(this->EvaluatePeriodIndexExpression(expression));
|
||||
return dynamic_pointer_cast<const StringEvalValue>(this->EvaluatePeriodIndexExpression(expression));
|
||||
|
||||
default:
|
||||
throw;
|
||||
@@ -323,7 +319,7 @@ namespace Porygon::Evaluation {
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateFunctionExpression(const BoundExpression *expression) {
|
||||
shared_ptr<const EvalValue> Evaluator::EvaluateFunctionExpression(const BoundExpression *expression) {
|
||||
switch (expression->GetKind()) {
|
||||
case BoundExpressionKind::Variable:
|
||||
return this->GetVariable((BoundVariableExpression *) expression);
|
||||
@@ -336,7 +332,7 @@ namespace Porygon::Evaluation {
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateNilExpression(const BoundExpression *expression) {
|
||||
shared_ptr<const EvalValue> Evaluator::EvaluateNilExpression(const BoundExpression *expression) {
|
||||
switch (expression->GetKind()) {
|
||||
case BoundExpressionKind::FunctionCall:
|
||||
return this->EvaluateFunctionCallExpression(expression);
|
||||
@@ -345,7 +341,7 @@ namespace Porygon::Evaluation {
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateTableExpression(const BoundExpression *expression) {
|
||||
shared_ptr<const EvalValue> Evaluator::EvaluateTableExpression(const BoundExpression *expression) {
|
||||
switch (expression->GetKind()) {
|
||||
case BoundExpressionKind::FunctionCall:
|
||||
return this->EvaluateFunctionCallExpression(expression);
|
||||
@@ -365,19 +361,19 @@ namespace Porygon::Evaluation {
|
||||
}
|
||||
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateFunctionCallExpression(const BoundExpression *expression) {
|
||||
shared_ptr<const EvalValue> Evaluator::EvaluateFunctionCallExpression(const BoundExpression *expression) {
|
||||
auto functionCall = (BoundFunctionCallExpression *) expression;
|
||||
auto function = dynamic_pointer_cast<GenericFunctionEvalValue>(
|
||||
auto function = dynamic_pointer_cast<const GenericFunctionEvalValue>(
|
||||
this->EvaluateExpression(functionCall->GetFunctionExpression()));
|
||||
|
||||
auto boundParameters = functionCall->GetParameters();
|
||||
auto parameters = vector<shared_ptr<EvalValue>>(boundParameters->size());
|
||||
for (int i = 0; i < boundParameters->size(); i++) {
|
||||
auto parameters = vector<shared_ptr<const EvalValue>>(boundParameters->size());
|
||||
for (size_t i = 0; i < boundParameters->size(); i++) {
|
||||
parameters[i] = this->EvaluateExpression(boundParameters->at(i));
|
||||
}
|
||||
|
||||
auto type = std::dynamic_pointer_cast<GenericFunctionScriptType>(function->GetType());
|
||||
auto func = dynamic_pointer_cast<GenericFunctionEvalValue>(function);
|
||||
auto type = std::dynamic_pointer_cast<const GenericFunctionScriptType>(function->GetType());
|
||||
auto func = dynamic_pointer_cast<const GenericFunctionEvalValue>(function);
|
||||
auto option = functionCall ->GetFunctionOption();
|
||||
auto opt = func->GetOption(option->GetOptionId());
|
||||
if (option -> IsScriptFunction()){
|
||||
@@ -385,7 +381,7 @@ namespace Porygon::Evaluation {
|
||||
auto scriptFunctionType = dynamic_cast<const ScriptFunctionOption*>(option);
|
||||
auto parameterKeys = scriptFunctionType->GetParameterKeys();
|
||||
auto originalScope = this->_evaluationScope;
|
||||
auto scriptOption = dynamic_pointer_cast<EvaluationScriptFunctionOption>(opt);
|
||||
auto scriptOption = dynamic_pointer_cast<const EvaluationScriptFunctionOption>(opt);
|
||||
this->_evaluationScope = scriptOption->GetScope();
|
||||
|
||||
for (int i = 0; i < parameterTypes.size() && i < parameterKeys.size() && i < parameters.size(); i++) {
|
||||
@@ -401,25 +397,25 @@ namespace Porygon::Evaluation {
|
||||
this->_returnValue = nullptr;
|
||||
return r;
|
||||
} else{
|
||||
auto scriptOption = dynamic_pointer_cast<UserData::UserDataFunction>(opt);
|
||||
EvalValue* arr[parameters.size()];
|
||||
for (int i = 0; i < parameters.size(); i++){
|
||||
auto scriptOption = dynamic_pointer_cast<const UserData::UserDataFunction>(opt);
|
||||
const EvalValue* arr[parameters.size()];
|
||||
for (size_t i = 0; i < parameters.size(); i++){
|
||||
arr[i] = parameters[i].get();
|
||||
}
|
||||
return shared_ptr<EvalValue>(scriptOption -> Call(arr, parameters.size()));
|
||||
return shared_ptr<const EvalValue>(scriptOption -> Call(arr, parameters.size()));
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateFunction(const GenericFunctionEvalValue *function,
|
||||
shared_ptr<const EvalValue> Evaluator::EvaluateFunction(const GenericFunctionEvalValue *function,
|
||||
const vector<EvalValue *> ¶meters) {
|
||||
auto type = std::dynamic_pointer_cast<GenericFunctionScriptType>(function->GetType());
|
||||
auto type = std::dynamic_pointer_cast<const GenericFunctionScriptType>(function->GetType());
|
||||
auto option = dynamic_cast<const ScriptFunctionOption*>(type->GetFirstOption());
|
||||
|
||||
auto parameterTypes = option->GetParameterTypes();
|
||||
auto parameterKeys = option->GetParameterKeys();
|
||||
|
||||
auto originalScope = this->_evaluationScope;
|
||||
auto scriptOption = dynamic_pointer_cast<EvaluationScriptFunctionOption>(function->GetOption(0));
|
||||
auto scriptOption = dynamic_pointer_cast<const EvaluationScriptFunctionOption>(function->GetOption(0));
|
||||
this->_evaluationScope = scriptOption->GetScope();
|
||||
|
||||
for (int i = 0; i < parameterTypes.size() && i < parameterKeys.size() && i < parameters.size(); i++) {
|
||||
@@ -435,41 +431,41 @@ namespace Porygon::Evaluation {
|
||||
return r;
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateIndexExpression(const BoundExpression *expression) {
|
||||
shared_ptr<const 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();
|
||||
return indexable->IndexValue(index.get());
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluatePeriodIndexExpression(const BoundExpression *expression) {
|
||||
shared_ptr<const EvalValue> Evaluator::EvaluatePeriodIndexExpression(const BoundExpression *expression) {
|
||||
auto indexExpression = (BoundPeriodIndexExpression *) expression;
|
||||
auto index = indexExpression->GetIndex().GetHash();
|
||||
auto index = indexExpression->GetIndex()->GetHash();
|
||||
auto indexable = this->EvaluateExpression(indexExpression->GetIndexableExpression());
|
||||
return indexable->IndexValue(index)->Clone();
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateNumericTableExpression(const BoundExpression *expression) {
|
||||
shared_ptr<const EvalValue> Evaluator::EvaluateNumericTableExpression(const BoundExpression *expression) {
|
||||
auto tableExpression = (BoundNumericalTableExpression *) expression;
|
||||
auto valueExpressions = tableExpression->GetExpressions();
|
||||
auto values = new vector<shared_ptr<EvalValue>>(valueExpressions->size());
|
||||
for (int i = 0; i < valueExpressions->size(); i++) {
|
||||
auto values = new vector<shared_ptr<const EvalValue>>(valueExpressions->size());
|
||||
for (size_t i = 0; i < valueExpressions->size(); i++) {
|
||||
auto val = this->EvaluateExpression(valueExpressions->at(i));
|
||||
values->at(i) = val;
|
||||
}
|
||||
auto valuesPointer = shared_ptr<vector<shared_ptr<EvalValue>>>(values);
|
||||
auto valuesPointer = shared_ptr<vector<shared_ptr<const EvalValue>>>(values);
|
||||
return make_shared<NumericalTableEvalValue>(valuesPointer);
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateComplexTableExpression(const BoundExpression *expression) {
|
||||
shared_ptr<const EvalValue> Evaluator::EvaluateComplexTableExpression(const BoundExpression *expression) {
|
||||
auto tableExpression = (BoundTableExpression *) expression;
|
||||
auto type = dynamic_pointer_cast<TableScriptType>(tableExpression->GetType());
|
||||
auto type = dynamic_pointer_cast<const TableScriptType>(tableExpression->GetType());
|
||||
auto declaredVars = type->GetValues();
|
||||
auto variables = make_shared<map<Utilities::HashedString, shared_ptr<EvalValue>>>();
|
||||
auto variables = make_shared<map<Utilities::HashedString, shared_ptr<const EvalValue>>>();
|
||||
for (const auto& i : *declaredVars) {
|
||||
variables->insert({i.first, nullptr});
|
||||
}
|
||||
auto evaluator = make_shared<EvaluationScope>(variables.get(), type->GetLocalVariableCount());
|
||||
auto evaluator = make_shared<EvaluationScope>(variables.get());
|
||||
auto currentEvaluator = this->_evaluationScope;
|
||||
this->_evaluationScope = evaluator;
|
||||
this->EvaluateBlockStatement(tableExpression->GetBlock());
|
||||
@@ -477,7 +473,7 @@ namespace Porygon::Evaluation {
|
||||
return make_shared<TableEvalValue>(variables);
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateUserDataExpression(const BoundExpression *expression) {
|
||||
shared_ptr<const EvalValue> Evaluator::EvaluateUserDataExpression(const BoundExpression *expression) {
|
||||
switch (expression->GetKind()) {
|
||||
case BoundExpressionKind::Variable:
|
||||
return this->GetVariable((BoundVariableExpression *) expression);
|
||||
|
||||
Reference in New Issue
Block a user