From 4f2a8454a65da23e8d28a1a754d8b58be69a1387 Mon Sep 17 00:00:00 2001 From: Jan Date: Mon, 22 Nov 2021 21:47:05 +0100 Subject: [PATCH] Move common expression classes to simple parsing setup --- .../Parsing/Menu/Domain/CommonItemDef.h | 28 +- .../Parsing/Menu/Domain/CommonMenuDef.h | 16 +- .../CommonEventHandlerCondition.cpp | 2 +- .../CommonEventHandlerCondition.h | 6 +- .../CommonEventHandlerSetLocalVar.cpp | 2 +- .../CommonEventHandlerSetLocalVar.h | 6 +- .../CommonExpressionBinaryOperation.cpp | 439 ------------------ .../CommonExpressionBinaryOperation.h | 100 ---- .../CommonExpressionFunctionCall.cpp | 4 +- .../Expression/CommonExpressionFunctionCall.h | 8 +- .../CommonExpressionUnaryOperation.cpp | 75 --- .../CommonExpressionUnaryOperation.h | 53 --- .../Domain/Expression/CommonExpressionValue.h | 38 -- .../Domain/Expression/ICommonExpression.h | 23 - .../Menu/Matcher/MenuCommonMatchers.cpp | 78 ++-- .../Parsing/Menu/Matcher/MenuCommonMatchers.h | 10 +- .../EventHandlerSetScopeSequences.cpp | 20 +- .../GenericExpressionPropertySequence.h | 4 +- .../Menu/Sequence/ItemScopeSequences.cpp | 50 +- .../Menu/Sequence/MenuScopeSequences.cpp | 10 +- .../Simple/Expression/ISimpleExpression.h | 20 + .../SimpleExpressionBinaryOperation.cpp | 437 +++++++++++++++++ .../SimpleExpressionBinaryOperation.h | 97 ++++ .../SimpleExpressionUnaryOperation.cpp | 73 +++ .../SimpleExpressionUnaryOperation.h | 50 ++ .../Expression/SimpleExpressionValue.cpp} | 16 +- .../Simple/Expression/SimpleExpressionValue.h | 35 ++ .../EventHandlerSetScopeSequencesTests.cpp | 4 +- 28 files changed, 843 insertions(+), 861 deletions(-) delete mode 100644 src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionBinaryOperation.cpp delete mode 100644 src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionBinaryOperation.h delete mode 100644 src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionUnaryOperation.cpp delete mode 100644 src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionUnaryOperation.h delete mode 100644 src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionValue.h delete mode 100644 src/ObjLoading/Parsing/Menu/Domain/Expression/ICommonExpression.h create mode 100644 src/Parser/Parsing/Simple/Expression/ISimpleExpression.h create mode 100644 src/Parser/Parsing/Simple/Expression/SimpleExpressionBinaryOperation.cpp create mode 100644 src/Parser/Parsing/Simple/Expression/SimpleExpressionBinaryOperation.h create mode 100644 src/Parser/Parsing/Simple/Expression/SimpleExpressionUnaryOperation.cpp create mode 100644 src/Parser/Parsing/Simple/Expression/SimpleExpressionUnaryOperation.h rename src/{ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionValue.cpp => Parser/Parsing/Simple/Expression/SimpleExpressionValue.cpp} (63%) create mode 100644 src/Parser/Parsing/Simple/Expression/SimpleExpressionValue.h diff --git a/src/ObjLoading/Parsing/Menu/Domain/CommonItemDef.h b/src/ObjLoading/Parsing/Menu/Domain/CommonItemDef.h index 4ef06051..2d0ce69c 100644 --- a/src/ObjLoading/Parsing/Menu/Domain/CommonItemDef.h +++ b/src/ObjLoading/Parsing/Menu/Domain/CommonItemDef.h @@ -5,7 +5,7 @@ #include "CommonMenuTypes.h" #include "EventHandler/CommonEventHandlerSet.h" -#include "Expression/ICommonExpression.h" +#include "Parsing/Simple/Expression/ISimpleExpression.h" namespace menu { @@ -82,11 +82,11 @@ namespace menu class ColorExpressions { public: - std::unique_ptr m_r_exp; - std::unique_ptr m_g_exp; - std::unique_ptr m_b_exp; - std::unique_ptr m_a_exp; - std::unique_ptr m_rgb_exp; + std::unique_ptr m_r_exp; + std::unique_ptr m_g_exp; + std::unique_ptr m_b_exp; + std::unique_ptr m_a_exp; + std::unique_ptr m_rgb_exp; }; std::string m_name; @@ -133,14 +133,14 @@ namespace menu int m_fx_decay_start_time; int m_fx_decay_duration; - std::unique_ptr m_visible_expression; - std::unique_ptr m_disabled_expression; - std::unique_ptr m_text_expression; - std::unique_ptr m_material_expression; - std::unique_ptr m_rect_x_exp; - std::unique_ptr m_rect_y_exp; - std::unique_ptr m_rect_w_exp; - std::unique_ptr m_rect_h_exp; + std::unique_ptr m_visible_expression; + std::unique_ptr m_disabled_expression; + std::unique_ptr m_text_expression; + std::unique_ptr m_material_expression; + std::unique_ptr m_rect_x_exp; + std::unique_ptr m_rect_y_exp; + std::unique_ptr m_rect_w_exp; + std::unique_ptr m_rect_h_exp; ColorExpressions m_forecolor_expressions; ColorExpressions m_glowcolor_expressions; ColorExpressions m_backcolor_expressions; diff --git a/src/ObjLoading/Parsing/Menu/Domain/CommonMenuDef.h b/src/ObjLoading/Parsing/Menu/Domain/CommonMenuDef.h index ad806273..bac7f8a4 100644 --- a/src/ObjLoading/Parsing/Menu/Domain/CommonMenuDef.h +++ b/src/ObjLoading/Parsing/Menu/Domain/CommonMenuDef.h @@ -8,7 +8,7 @@ #include "CommonItemDef.h" #include "CommonMenuTypes.h" #include "EventHandler/CommonEventHandlerSet.h" -#include "Expression/ICommonExpression.h" +#include "Parsing/Simple/Expression/ISimpleExpression.h" namespace menu { @@ -34,13 +34,13 @@ namespace menu double m_fade_in_amount; double m_blur_radius; std::string m_allowed_binding; - std::unique_ptr m_visible_expression; - std::unique_ptr m_rect_x_exp; - std::unique_ptr m_rect_y_exp; - std::unique_ptr m_rect_w_exp; - std::unique_ptr m_rect_h_exp; - std::unique_ptr m_open_sound_exp; - std::unique_ptr m_close_sound_exp; + std::unique_ptr m_visible_expression; + std::unique_ptr m_rect_x_exp; + std::unique_ptr m_rect_y_exp; + std::unique_ptr m_rect_w_exp; + std::unique_ptr m_rect_h_exp; + std::unique_ptr m_open_sound_exp; + std::unique_ptr m_close_sound_exp; std::unique_ptr m_on_open; std::unique_ptr m_on_close; std::unique_ptr m_on_request_close; diff --git a/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerCondition.cpp b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerCondition.cpp index a213d94d..2de32761 100644 --- a/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerCondition.cpp +++ b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerCondition.cpp @@ -5,7 +5,7 @@ using namespace menu; CommonEventHandlerCondition::CommonEventHandlerCondition() = default; -CommonEventHandlerCondition::CommonEventHandlerCondition(std::unique_ptr condition, std::unique_ptr conditionElements, +CommonEventHandlerCondition::CommonEventHandlerCondition(std::unique_ptr condition, std::unique_ptr conditionElements, std::unique_ptr elseElements) : m_condition(std::move(condition)), m_condition_elements(std::move(conditionElements)), diff --git a/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerCondition.h b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerCondition.h index a8dba67d..8d581411 100644 --- a/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerCondition.h +++ b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerCondition.h @@ -4,19 +4,19 @@ #include "CommonEventHandlerSet.h" #include "ICommonEventHandlerElement.h" -#include "Parsing/Menu/Domain/Expression/ICommonExpression.h" +#include "Parsing/Simple/Expression/ISimpleExpression.h" namespace menu { class CommonEventHandlerCondition final : public ICommonEventHandlerElement { public: - std::unique_ptr m_condition; + std::unique_ptr m_condition; std::unique_ptr m_condition_elements; std::unique_ptr m_else_elements; CommonEventHandlerCondition(); - CommonEventHandlerCondition(std::unique_ptr condition, std::unique_ptr conditionElements, + CommonEventHandlerCondition(std::unique_ptr condition, std::unique_ptr conditionElements, std::unique_ptr elseElements); _NODISCARD CommonEventHandlerElementType GetType() const override; diff --git a/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSetLocalVar.cpp b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSetLocalVar.cpp index e50a2606..7ebee3fd 100644 --- a/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSetLocalVar.cpp +++ b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSetLocalVar.cpp @@ -7,7 +7,7 @@ CommonEventHandlerSetLocalVar::CommonEventHandlerSetLocalVar() { } -CommonEventHandlerSetLocalVar::CommonEventHandlerSetLocalVar(SetLocalVarType type, std::string varName, std::unique_ptr value) +CommonEventHandlerSetLocalVar::CommonEventHandlerSetLocalVar(SetLocalVarType type, std::string varName, std::unique_ptr value) : m_type(type), m_var_name(std::move(varName)), m_value(std::move(value)) diff --git a/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSetLocalVar.h b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSetLocalVar.h index 5164d83e..69324a51 100644 --- a/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSetLocalVar.h +++ b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSetLocalVar.h @@ -3,7 +3,7 @@ #include #include "ICommonEventHandlerElement.h" -#include "Parsing/Menu/Domain/Expression/ICommonExpression.h" +#include "Parsing/Simple/Expression/ISimpleExpression.h" namespace menu { @@ -21,10 +21,10 @@ namespace menu public: SetLocalVarType m_type; std::string m_var_name; - std::unique_ptr m_value; + std::unique_ptr m_value; CommonEventHandlerSetLocalVar(); - CommonEventHandlerSetLocalVar(SetLocalVarType type, std::string varName, std::unique_ptr value); + CommonEventHandlerSetLocalVar(SetLocalVarType type, std::string varName, std::unique_ptr value); _NODISCARD CommonEventHandlerElementType GetType() const override; }; diff --git a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionBinaryOperation.cpp b/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionBinaryOperation.cpp deleted file mode 100644 index 5ba24b65..00000000 --- a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionBinaryOperation.cpp +++ /dev/null @@ -1,439 +0,0 @@ -#include "CommonExpressionBinaryOperation.h" - -#include -#include - -using namespace menu; - -CommonExpressionBinaryOperationType::CommonExpressionBinaryOperationType(std::string syntax, const OperationPrecedence precedence, evaluation_function_t evaluationFunction) - : m_syntax(std::move(syntax)), - m_precedence(precedence), - m_evaluation_function(std::move(evaluationFunction)) -{ -} - -const CommonExpressionBinaryOperationType CommonExpressionBinaryOperationType::OPERATION_ADD( - "+", - OperationPrecedence::ADDITION_SUBTRACTION, - [](const CommonExpressionValue& operand1, const CommonExpressionValue& operand2) -> CommonExpressionValue - { - if (operand1.m_type == CommonExpressionValue::Type::DOUBLE) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(operand1.m_double_value + operand2.m_double_value); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_double_value + static_cast(operand2.m_int_value)); - if (operand2.m_type == CommonExpressionValue::Type::STRING) - return CommonExpressionValue(std::to_string(operand1.m_double_value) + *operand2.m_string_value); - } - else if (operand1.m_type == CommonExpressionValue::Type::INT) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(static_cast(operand1.m_int_value) + operand2.m_double_value); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_int_value + operand2.m_int_value); - if (operand2.m_type == CommonExpressionValue::Type::STRING) - return CommonExpressionValue(std::to_string(operand1.m_int_value) + *operand2.m_string_value); - } - else if (operand1.m_type == CommonExpressionValue::Type::STRING) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(*operand1.m_string_value + std::to_string(operand2.m_double_value)); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(*operand1.m_string_value + std::to_string(operand2.m_int_value)); - if (operand2.m_type == CommonExpressionValue::Type::STRING) - return CommonExpressionValue(*operand1.m_string_value + *operand2.m_string_value); - } - - return CommonExpressionValue(0); - } -); - -const CommonExpressionBinaryOperationType CommonExpressionBinaryOperationType::OPERATION_SUBTRACT( - "-", - OperationPrecedence::ADDITION_SUBTRACTION, - [](const CommonExpressionValue& operand1, const CommonExpressionValue& operand2) -> CommonExpressionValue - { - if (operand1.m_type == CommonExpressionValue::Type::DOUBLE) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(operand1.m_double_value - operand2.m_double_value); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_double_value - static_cast(operand2.m_int_value)); - } - else if (operand1.m_type == CommonExpressionValue::Type::INT) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(static_cast(operand1.m_int_value) - operand2.m_double_value); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_int_value - operand2.m_int_value); - } - - return CommonExpressionValue(0); - } -); - -const CommonExpressionBinaryOperationType CommonExpressionBinaryOperationType::OPERATION_MULTIPLY( - "*", - OperationPrecedence::MULTIPLICATION_DIVISION_REMAINDER, - [](const CommonExpressionValue& operand1, const CommonExpressionValue& operand2) -> CommonExpressionValue - { - if (operand1.m_type == CommonExpressionValue::Type::DOUBLE) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(operand1.m_double_value * operand2.m_double_value); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_double_value * static_cast(operand2.m_int_value)); - } - else if (operand1.m_type == CommonExpressionValue::Type::INT) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(static_cast(operand1.m_int_value) * operand2.m_double_value); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_int_value * operand2.m_int_value); - } - - return CommonExpressionValue(0); - } -); - -const CommonExpressionBinaryOperationType CommonExpressionBinaryOperationType::OPERATION_DIVIDE( - "/", - OperationPrecedence::MULTIPLICATION_DIVISION_REMAINDER, - [](const CommonExpressionValue& operand1, const CommonExpressionValue& operand2) -> CommonExpressionValue - { - if (operand1.m_type == CommonExpressionValue::Type::DOUBLE) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(operand1.m_double_value / operand2.m_double_value); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_double_value / static_cast(operand2.m_int_value)); - } - else if (operand1.m_type == CommonExpressionValue::Type::INT) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(static_cast(operand1.m_int_value) / operand2.m_double_value); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_int_value / operand2.m_int_value); - } - - return CommonExpressionValue(0); - } -); - -const CommonExpressionBinaryOperationType CommonExpressionBinaryOperationType::OPERATION_REMAINDER( - "%", - OperationPrecedence::MULTIPLICATION_DIVISION_REMAINDER, - [](const CommonExpressionValue& operand1, const CommonExpressionValue& operand2) -> CommonExpressionValue - { - if (operand1.m_type == CommonExpressionValue::Type::INT && operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_int_value % operand2.m_int_value); - - return CommonExpressionValue(0); - } -); - -const CommonExpressionBinaryOperationType CommonExpressionBinaryOperationType::OPERATION_BITWISE_AND( - "&", - OperationPrecedence::BITWISE_AND, - [](const CommonExpressionValue& operand1, const CommonExpressionValue& operand2) -> CommonExpressionValue - { - if (operand1.m_type == CommonExpressionValue::Type::INT && operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_int_value & operand2.m_int_value); - - return CommonExpressionValue(0); - } -); - -const CommonExpressionBinaryOperationType CommonExpressionBinaryOperationType::OPERATION_BITWISE_OR( - "|", - OperationPrecedence::BITWISE_OR, - [](const CommonExpressionValue& operand1, const CommonExpressionValue& operand2) -> CommonExpressionValue - { - if (operand1.m_type == CommonExpressionValue::Type::INT && operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_int_value | operand2.m_int_value); - - return CommonExpressionValue(0); - } -); - -const CommonExpressionBinaryOperationType CommonExpressionBinaryOperationType::OPERATION_SHIFT_LEFT( - "<<", - OperationPrecedence::BITWISE_SHIFT, - [](const CommonExpressionValue& operand1, const CommonExpressionValue& operand2) -> CommonExpressionValue - { - if (operand1.m_type == CommonExpressionValue::Type::INT && operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_int_value << operand2.m_int_value); - - return CommonExpressionValue(0); - } -); - -const CommonExpressionBinaryOperationType CommonExpressionBinaryOperationType::OPERATION_SHIFT_RIGHT( - ">>", - OperationPrecedence::BITWISE_SHIFT, - [](const CommonExpressionValue& operand1, const CommonExpressionValue& operand2) -> CommonExpressionValue - { - if (operand1.m_type == CommonExpressionValue::Type::INT && operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_int_value >> operand2.m_int_value); - - return CommonExpressionValue(0); - } -); - -const CommonExpressionBinaryOperationType CommonExpressionBinaryOperationType::OPERATION_GREATER_THAN( - ">", - OperationPrecedence::RELATIONAL_GREATER_LESS_THAN, - [](const CommonExpressionValue& operand1, const CommonExpressionValue& operand2) -> CommonExpressionValue - { - if (operand1.m_type == CommonExpressionValue::Type::STRING || operand2.m_type == CommonExpressionValue::Type::STRING) - return CommonExpressionValue(operand1.IsTruthy() > operand2.IsTruthy()); - - if (operand1.m_type == CommonExpressionValue::Type::DOUBLE) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(operand1.m_double_value > operand2.m_double_value); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_double_value > operand2.m_int_value); - } - else if (operand1.m_type == CommonExpressionValue::Type::INT) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(operand1.m_int_value > operand2.m_double_value); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_int_value > operand2.m_int_value); - } - - return CommonExpressionValue(0); - } -); - -const CommonExpressionBinaryOperationType CommonExpressionBinaryOperationType::OPERATION_GREATER_EQUAL_THAN( - ">=", - OperationPrecedence::RELATIONAL_GREATER_LESS_THAN, - [](const CommonExpressionValue& operand1, const CommonExpressionValue& operand2) -> CommonExpressionValue - { - if (operand1.m_type == CommonExpressionValue::Type::STRING || operand2.m_type == CommonExpressionValue::Type::STRING) - return CommonExpressionValue(operand1.IsTruthy() >= operand2.IsTruthy()); - - if (operand1.m_type == CommonExpressionValue::Type::DOUBLE) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(operand1.m_double_value >= operand2.m_double_value); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_double_value >= operand2.m_int_value); - } - else if (operand1.m_type == CommonExpressionValue::Type::INT) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(operand1.m_int_value >= operand2.m_double_value); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_int_value >= operand2.m_int_value); - } - - return CommonExpressionValue(0); - } -); - -const CommonExpressionBinaryOperationType CommonExpressionBinaryOperationType::OPERATION_LESS_THAN( - "<", - OperationPrecedence::RELATIONAL_GREATER_LESS_THAN, - [](const CommonExpressionValue& operand1, const CommonExpressionValue& operand2) -> CommonExpressionValue - { - if (operand1.m_type == CommonExpressionValue::Type::STRING || operand2.m_type == CommonExpressionValue::Type::STRING) - return CommonExpressionValue(operand1.IsTruthy() < operand2.IsTruthy()); - - if (operand1.m_type == CommonExpressionValue::Type::DOUBLE) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(operand1.m_double_value < operand2.m_double_value); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_double_value < operand2.m_int_value); - } - else if (operand1.m_type == CommonExpressionValue::Type::INT) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(operand1.m_int_value < operand2.m_double_value); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_int_value < operand2.m_int_value); - } - - return CommonExpressionValue(0); - } -); - -const CommonExpressionBinaryOperationType CommonExpressionBinaryOperationType::OPERATION_LESS_EQUAL_THAN( - "<=", - OperationPrecedence::RELATIONAL_GREATER_LESS_THAN, - [](const CommonExpressionValue& operand1, const CommonExpressionValue& operand2) -> CommonExpressionValue - { - if (operand1.m_type == CommonExpressionValue::Type::STRING || operand2.m_type == CommonExpressionValue::Type::STRING) - return CommonExpressionValue(operand1.IsTruthy() <= operand2.IsTruthy()); - - if (operand1.m_type == CommonExpressionValue::Type::DOUBLE) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(operand1.m_double_value <= operand2.m_double_value); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_double_value <= operand2.m_int_value); - } - else if (operand1.m_type == CommonExpressionValue::Type::INT) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(operand1.m_int_value <= operand2.m_double_value); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_int_value <= operand2.m_int_value); - } - - return CommonExpressionValue(0); - } -); - -const CommonExpressionBinaryOperationType CommonExpressionBinaryOperationType::OPERATION_EQUALS( - "==", - OperationPrecedence::RELATIONAL_EQUALS, - [](const CommonExpressionValue& operand1, const CommonExpressionValue& operand2) -> CommonExpressionValue - { - if (operand1.m_type == CommonExpressionValue::Type::DOUBLE) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(std::fpclassify(operand1.m_double_value - operand2.m_double_value) == FP_ZERO); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(std::fpclassify(operand1.m_double_value - static_cast(operand2.m_int_value)) == FP_ZERO); - - return CommonExpressionValue(0); - } - - if (operand1.m_type == CommonExpressionValue::Type::INT) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(std::fpclassify(operand1.m_double_value - operand2.m_double_value) == FP_ZERO); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_int_value == operand2.m_int_value); - - return CommonExpressionValue(0); - } - - if (operand1.m_type == CommonExpressionValue::Type::STRING) - { - if (operand2.m_type == CommonExpressionValue::Type::STRING) - return CommonExpressionValue(*operand1.m_string_value == *operand2.m_string_value); - - return CommonExpressionValue(0); - } - - return CommonExpressionValue(0); - } -); - -const CommonExpressionBinaryOperationType CommonExpressionBinaryOperationType::OPERATION_NOT_EQUAL( - "!=", - OperationPrecedence::RELATIONAL_EQUALS, - [](const CommonExpressionValue& operand1, const CommonExpressionValue& operand2) -> CommonExpressionValue - { - if (operand1.m_type == CommonExpressionValue::Type::DOUBLE) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(std::fpclassify(operand1.m_double_value - operand2.m_double_value) != FP_ZERO); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(std::fpclassify(operand1.m_double_value - static_cast(operand2.m_int_value)) != FP_ZERO); - - return CommonExpressionValue(0); - } - - if (operand1.m_type == CommonExpressionValue::Type::INT) - { - if (operand2.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(std::fpclassify(operand1.m_double_value - operand2.m_double_value) != FP_ZERO); - if (operand2.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(operand1.m_int_value != operand2.m_int_value); - - return CommonExpressionValue(0); - } - - if (operand1.m_type == CommonExpressionValue::Type::STRING) - { - if (operand2.m_type == CommonExpressionValue::Type::STRING) - return CommonExpressionValue(*operand1.m_string_value != *operand2.m_string_value); - - return CommonExpressionValue(0); - } - - return CommonExpressionValue(0); - } -); - -const CommonExpressionBinaryOperationType CommonExpressionBinaryOperationType::OPERATION_AND( - "&&", - OperationPrecedence::LOGICAL_AND, - [](const CommonExpressionValue& operand1, const CommonExpressionValue& operand2) -> CommonExpressionValue - { - if (operand1.IsTruthy()) - return operand2; - return operand1; - } -); - -const CommonExpressionBinaryOperationType CommonExpressionBinaryOperationType::OPERATION_OR( - "||", - OperationPrecedence::LOGICAL_OR, - [](const CommonExpressionValue& operand1, const CommonExpressionValue& operand2) -> CommonExpressionValue - { - if (operand1.IsTruthy()) - return operand1; - return operand2; - } -); - -const CommonExpressionBinaryOperationType* const CommonExpressionBinaryOperationType::ALL_OPERATION_TYPES[static_cast(BinaryOperationId::COUNT)] -{ - &OPERATION_ADD, - &OPERATION_SUBTRACT, - &OPERATION_MULTIPLY, - &OPERATION_DIVIDE, - &OPERATION_REMAINDER, - &OPERATION_BITWISE_AND, - &OPERATION_BITWISE_OR, - &OPERATION_SHIFT_LEFT, - &OPERATION_SHIFT_RIGHT, - &OPERATION_GREATER_THAN, - &OPERATION_GREATER_EQUAL_THAN, - &OPERATION_LESS_THAN, - &OPERATION_LESS_EQUAL_THAN, - &OPERATION_EQUALS, - &OPERATION_NOT_EQUAL, - &OPERATION_AND, - &OPERATION_OR -}; - -CommonExpressionBinaryOperation::CommonExpressionBinaryOperation(const CommonExpressionBinaryOperationType* operationType, std::unique_ptr operand1, - std::unique_ptr operand2) - : m_operation_type(operationType), - m_operand1(std::move(operand1)), - m_operand2(std::move(operand2)) -{ -} - -bool CommonExpressionBinaryOperation::Operand1NeedsParenthesis() const -{ - const auto* operation = dynamic_cast(m_operand1.get()); - return operation && operation->m_operation_type->m_precedence > m_operation_type->m_precedence; -} - -bool CommonExpressionBinaryOperation::Operand2NeedsParenthesis() const -{ - const auto* operation = dynamic_cast(m_operand2.get()); - return operation && operation->m_operation_type->m_precedence > m_operation_type->m_precedence; -} - -bool CommonExpressionBinaryOperation::IsStatic() -{ - assert(m_operand1 && m_operand2); - - return m_operand1->IsStatic() && m_operand2->IsStatic(); -} - -CommonExpressionValue CommonExpressionBinaryOperation::Evaluate() -{ - return m_operation_type->m_evaluation_function(m_operand1->Evaluate(), m_operand2->Evaluate()); -} diff --git a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionBinaryOperation.h b/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionBinaryOperation.h deleted file mode 100644 index 1a88a8bc..00000000 --- a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionBinaryOperation.h +++ /dev/null @@ -1,100 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "ICommonExpression.h" -#include "CommonExpressionValue.h" - -namespace menu -{ - // https://en.cppreference.com/w/cpp/language/operator_precedence - enum class OperationPrecedence - { - MULTIPLICATION_DIVISION_REMAINDER = 1, - ADDITION_SUBTRACTION = 2, - BITWISE_SHIFT = 3, - RELATIONAL_GREATER_LESS_THAN = 4, - RELATIONAL_EQUALS = 5, - BITWISE_AND = 6, - BITWISE_OR = 8, - LOGICAL_AND = 9, - LOGICAL_OR = 10 - }; - - enum class BinaryOperationId - { - ADD, - SUBTRACT, - MULTIPLY, - DIVIDE, - REMAINDER, - BITWISE_AND, - BITWISE_OR, - SHIFT_LEFT, - SHIFT_RIGHT, - GREATER_THAN, - GREATER_EQUAL_THAN, - LESS_THAN, - LESS_EQUAL_THAN, - EQUALS, - NOT_EQUAL, - AND, - OR, - - COUNT - }; - - class CommonExpressionBinaryOperationType - { - public: - using evaluation_function_t = std::function; - - std::string m_syntax; - OperationPrecedence m_precedence; - evaluation_function_t m_evaluation_function; - - private: - CommonExpressionBinaryOperationType(std::string syntax, OperationPrecedence precedence, evaluation_function_t evaluationFunction); - - public: - static const CommonExpressionBinaryOperationType OPERATION_ADD; - static const CommonExpressionBinaryOperationType OPERATION_SUBTRACT; - static const CommonExpressionBinaryOperationType OPERATION_MULTIPLY; - static const CommonExpressionBinaryOperationType OPERATION_DIVIDE; - static const CommonExpressionBinaryOperationType OPERATION_REMAINDER; - static const CommonExpressionBinaryOperationType OPERATION_BITWISE_AND; - static const CommonExpressionBinaryOperationType OPERATION_BITWISE_OR; - static const CommonExpressionBinaryOperationType OPERATION_SHIFT_LEFT; - static const CommonExpressionBinaryOperationType OPERATION_SHIFT_RIGHT; - static const CommonExpressionBinaryOperationType OPERATION_GREATER_THAN; - static const CommonExpressionBinaryOperationType OPERATION_GREATER_EQUAL_THAN; - static const CommonExpressionBinaryOperationType OPERATION_LESS_THAN; - static const CommonExpressionBinaryOperationType OPERATION_LESS_EQUAL_THAN; - static const CommonExpressionBinaryOperationType OPERATION_EQUALS; - static const CommonExpressionBinaryOperationType OPERATION_NOT_EQUAL; - static const CommonExpressionBinaryOperationType OPERATION_AND; - static const CommonExpressionBinaryOperationType OPERATION_OR; - - static const CommonExpressionBinaryOperationType* const ALL_OPERATION_TYPES[static_cast(BinaryOperationId::COUNT)]; - }; - - class CommonExpressionBinaryOperation final : public ICommonExpression - { - public: - const CommonExpressionBinaryOperationType* m_operation_type; - std::unique_ptr m_operand1; - std::unique_ptr m_operand2; - - CommonExpressionBinaryOperation(const CommonExpressionBinaryOperationType* operationType, - std::unique_ptr operand1, - std::unique_ptr operand2); - - _NODISCARD bool Operand1NeedsParenthesis() const; - _NODISCARD bool Operand2NeedsParenthesis() const; - - bool IsStatic() override; - CommonExpressionValue Evaluate() override; - }; -} diff --git a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionFunctionCall.cpp b/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionFunctionCall.cpp index 614393d0..ccfc1503 100644 --- a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionFunctionCall.cpp +++ b/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionFunctionCall.cpp @@ -12,7 +12,7 @@ bool CommonExpressionFunctionCall::IsStatic() return false; } -CommonExpressionValue CommonExpressionFunctionCall::Evaluate() +SimpleExpressionValue CommonExpressionFunctionCall::Evaluate() { - return CommonExpressionValue(0); + return SimpleExpressionValue(0); } diff --git a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionFunctionCall.h b/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionFunctionCall.h index ca7e88c6..ed7d95cf 100644 --- a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionFunctionCall.h +++ b/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionFunctionCall.h @@ -1,19 +1,19 @@ #pragma once #include -#include "ICommonExpression.h" +#include "Parsing/Simple/Expression/ISimpleExpression.h" namespace menu { - class CommonExpressionFunctionCall final : public ICommonExpression + class CommonExpressionFunctionCall final : public ISimpleExpression { public: std::string m_function_name; - std::vector> m_args; + std::vector> m_args; explicit CommonExpressionFunctionCall(std::string functionName); bool IsStatic() override; - CommonExpressionValue Evaluate() override; + SimpleExpressionValue Evaluate() override; }; } diff --git a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionUnaryOperation.cpp b/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionUnaryOperation.cpp deleted file mode 100644 index c2e3dce9..00000000 --- a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionUnaryOperation.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "CommonExpressionUnaryOperation.h" - -#include - -#include "CommonExpressionBinaryOperation.h" - -using namespace menu; - -CommonExpressionUnaryOperationType::CommonExpressionUnaryOperationType(std::string syntax, evaluation_function_t evaluationFunction) - : m_syntax(std::move(syntax)), - m_evaluation_function(std::move(evaluationFunction)) -{ -} - -const CommonExpressionUnaryOperationType CommonExpressionUnaryOperationType::OPERATION_NOT( - "!", - [](const CommonExpressionValue& operand) -> CommonExpressionValue - { - return CommonExpressionValue(!operand.IsTruthy()); - } -); - -const CommonExpressionUnaryOperationType CommonExpressionUnaryOperationType::OPERATION_BITWISE_NOT( - "~", - [](const CommonExpressionValue& operand) -> CommonExpressionValue - { - if(operand.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(~operand.m_int_value); - - return CommonExpressionValue(0); - } -); - -const CommonExpressionUnaryOperationType CommonExpressionUnaryOperationType::OPERATION_NEGATIVE( - "-", - [](const CommonExpressionValue& operand) -> CommonExpressionValue - { - if(operand.m_type == CommonExpressionValue::Type::INT) - return CommonExpressionValue(-operand.m_int_value); - if (operand.m_type == CommonExpressionValue::Type::DOUBLE) - return CommonExpressionValue(-operand.m_double_value); - - return CommonExpressionValue(0); - } -); - -const CommonExpressionUnaryOperationType* const CommonExpressionUnaryOperationType::ALL_OPERATION_TYPES[static_cast(UnaryOperationId::COUNT)] -{ - &OPERATION_NOT, - &OPERATION_BITWISE_NOT, - &OPERATION_NEGATIVE, -}; - -CommonExpressionUnaryOperation::CommonExpressionUnaryOperation(const CommonExpressionUnaryOperationType* operationType, std::unique_ptr operand) - : m_operation_type(operationType), - m_operand(std::move(operand)) -{ -} - -bool CommonExpressionUnaryOperation::OperandNeedsParenthesis() const -{ - return dynamic_cast(m_operand.get()) != nullptr; -} - -bool CommonExpressionUnaryOperation::IsStatic() -{ - assert(m_operand); - - return m_operand->IsStatic(); -} - -CommonExpressionValue CommonExpressionUnaryOperation::Evaluate() -{ - return m_operation_type->m_evaluation_function(m_operand->Evaluate()); -} diff --git a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionUnaryOperation.h b/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionUnaryOperation.h deleted file mode 100644 index 6ad3916f..00000000 --- a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionUnaryOperation.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "ICommonExpression.h" -#include "CommonExpressionValue.h" - -namespace menu -{ - enum class UnaryOperationId - { - NOT, - BITWISE_NOT, - NEGATIVE, - - COUNT - }; - - class CommonExpressionUnaryOperationType - { - public: - using evaluation_function_t = std::function; - - std::string m_syntax; - evaluation_function_t m_evaluation_function; - - private: - CommonExpressionUnaryOperationType(std::string syntax, evaluation_function_t evaluationFunction); - - public: - static const CommonExpressionUnaryOperationType OPERATION_NOT; - static const CommonExpressionUnaryOperationType OPERATION_BITWISE_NOT; - static const CommonExpressionUnaryOperationType OPERATION_NEGATIVE; - - static const CommonExpressionUnaryOperationType* const ALL_OPERATION_TYPES[static_cast(UnaryOperationId::COUNT)]; - }; - - class CommonExpressionUnaryOperation final : public ICommonExpression - { - public: - const CommonExpressionUnaryOperationType* m_operation_type; - std::unique_ptr m_operand; - - CommonExpressionUnaryOperation(const CommonExpressionUnaryOperationType* operationType, std::unique_ptr operand); - - _NODISCARD bool OperandNeedsParenthesis() const; - - bool IsStatic() override; - CommonExpressionValue Evaluate() override; - }; -} diff --git a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionValue.h b/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionValue.h deleted file mode 100644 index 819ae94b..00000000 --- a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionValue.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include -#include - -#include "ICommonExpression.h" -#include "Utils/ClassUtils.h" - -namespace menu -{ - class ICommonExpression; - class CommonExpressionValue final : public ICommonExpression - { - public: - enum class Type - { - STRING, - DOUBLE, - INT - }; - - Type m_type; - std::shared_ptr m_string_value; - union - { - double m_double_value; - int m_int_value; - }; - - explicit CommonExpressionValue(std::string stringValue); - explicit CommonExpressionValue(double doubleValue); - explicit CommonExpressionValue(int intValue); - - bool IsStatic() override; - CommonExpressionValue Evaluate() override; - _NODISCARD bool IsTruthy() const; - }; -} diff --git a/src/ObjLoading/Parsing/Menu/Domain/Expression/ICommonExpression.h b/src/ObjLoading/Parsing/Menu/Domain/Expression/ICommonExpression.h deleted file mode 100644 index 4d8448e1..00000000 --- a/src/ObjLoading/Parsing/Menu/Domain/Expression/ICommonExpression.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -namespace menu -{ - class CommonExpressionValue; - class ICommonExpression - { - protected: - ICommonExpression() = default; - public: - virtual ~ICommonExpression() = default; - ICommonExpression(const ICommonExpression& other) = default; - ICommonExpression(ICommonExpression&& other) noexcept = default; - ICommonExpression& operator=(const ICommonExpression& other) = default; - ICommonExpression& operator=(ICommonExpression&& other) noexcept = default; - - virtual bool IsStatic() = 0; - virtual CommonExpressionValue Evaluate() = 0; - }; -} - -// Include CommonExpressionValue after definition to avoid "base class not defined" -#include "CommonExpressionValue.h" \ No newline at end of file diff --git a/src/ObjLoading/Parsing/Menu/Matcher/MenuCommonMatchers.cpp b/src/ObjLoading/Parsing/Menu/Matcher/MenuCommonMatchers.cpp index 4cac4301..c1158c2d 100644 --- a/src/ObjLoading/Parsing/Menu/Matcher/MenuCommonMatchers.cpp +++ b/src/ObjLoading/Parsing/Menu/Matcher/MenuCommonMatchers.cpp @@ -4,9 +4,9 @@ #include "MenuMatcherFactory.h" #include "Parsing/Menu/MenuFileLexing.h" -#include "Parsing/Menu/Domain/Expression/CommonExpressionBinaryOperation.h" +#include "Parsing/Simple/Expression/SimpleExpressionBinaryOperation.h" #include "Parsing/Menu/Domain/Expression/CommonExpressionFunctionCall.h" -#include "Parsing/Menu/Domain/Expression/CommonExpressionUnaryOperation.h" +#include "Parsing/Simple/Expression/SimpleExpressionUnaryOperation.h" using namespace menu; @@ -24,7 +24,7 @@ static constexpr int CAPTURE_UNARY_OPERATION_TYPE = std::numeric_limits::ma static constexpr int CAPTURE_BINARY_OPERATION_TYPE = std::numeric_limits::max() - 3; static constexpr int CAPTURE_FUNCTION_NAME = std::numeric_limits::max() - 4; -std::unique_ptr MenuCommonMatchers::ProcessExpressionInParenthesis(MenuFileParserState* state, SequenceResult& result) +std::unique_ptr MenuCommonMatchers::ProcessExpressionInParenthesis(MenuFileParserState* state, SequenceResult& result) { auto processedEvaluation = ProcessExpression(state, result); @@ -34,26 +34,26 @@ std::unique_ptr MenuCommonMatchers::ProcessExpressionInParent return processedEvaluation; } -std::unique_ptr MenuCommonMatchers::ProcessOperand(MenuFileParserState* state, SequenceResult& result) +std::unique_ptr MenuCommonMatchers::ProcessOperand(MenuFileParserState* state, SequenceResult& result) { const auto& operandToken = result.NextCapture(CAPTURE_OPERAND); switch (operandToken.m_type) { case SimpleParserValueType::INTEGER: - return std::make_unique(operandToken.IntegerValue()); + return std::make_unique(operandToken.IntegerValue()); case SimpleParserValueType::FLOATING_POINT: - return std::make_unique(operandToken.FloatingPointValue()); + return std::make_unique(operandToken.FloatingPointValue()); case SimpleParserValueType::STRING: - return std::make_unique(operandToken.StringValue()); + return std::make_unique(operandToken.StringValue()); case SimpleParserValueType::IDENTIFIER: - return std::make_unique(operandToken.IdentifierValue()); + return std::make_unique(operandToken.IdentifierValue()); default: throw ParsingException(TokenPos(), "Unknown operand type @ Operand"); } } -std::unique_ptr MenuCommonMatchers::ProcessFunctionCall(MenuFileParserState* state, SequenceResult& result) +std::unique_ptr MenuCommonMatchers::ProcessFunctionCall(MenuFileParserState* state, SequenceResult& result) { auto functionCall = std::make_unique(result.NextCapture(CAPTURE_FUNCTION_NAME).IdentifierValue()); @@ -65,17 +65,17 @@ std::unique_ptr MenuCommonMatchers::ProcessFunctionCall(MenuF return std::move(functionCall); } -std::unique_ptr MenuCommonMatchers::ProcessExpression(MenuFileParserState* state, SequenceResult& result) +std::unique_ptr MenuCommonMatchers::ProcessExpression(MenuFileParserState* state, SequenceResult& result) { if (result.PeekAndRemoveIfTag(TAG_EXPRESSION) != TAG_EXPRESSION) return nullptr; - std::vector> operands; - std::list> operators; + std::vector> operands; + std::list> operators; while (true) { - std::unique_ptr firstStatementPart; + std::unique_ptr firstStatementPart; std::vector unaryOperations; auto nextTag = result.NextTag(); @@ -106,9 +106,9 @@ std::unique_ptr MenuCommonMatchers::ProcessExpression(MenuFil for (auto i = unaryOperations.size(); i > 0; i--) { const auto operationIndex = unaryOperations[i - 1]; - if (operationIndex < 0 || operationIndex >= static_cast(UnaryOperationId::COUNT)) + if (operationIndex < 0 || operationIndex >= static_cast(SimpleUnaryOperationId::COUNT)) throw ParsingException(TokenPos(), "Invalid unary operation id @ Expression"); - firstStatementPart = std::make_unique(CommonExpressionUnaryOperationType::ALL_OPERATION_TYPES[operationIndex], + firstStatementPart = std::make_unique(SimpleExpressionUnaryOperationType::ALL_OPERATION_TYPES[operationIndex], std::move(firstStatementPart)); } @@ -117,10 +117,10 @@ std::unique_ptr MenuCommonMatchers::ProcessExpression(MenuFil if (result.PeekAndRemoveIfTag(TAG_EXPRESSION_BINARY_OPERATION) == TAG_EXPRESSION_BINARY_OPERATION) { const auto operationIndex = result.NextCapture(CAPTURE_BINARY_OPERATION_TYPE).IntegerValue(); - if (operationIndex < 0 || operationIndex >= static_cast(BinaryOperationId::COUNT)) + if (operationIndex < 0 || operationIndex >= static_cast(SimpleBinaryOperationId::COUNT)) throw ParsingException(TokenPos(), "Invalid binary operation id @ Expression"); - operators.emplace_back(operators.size(), CommonExpressionBinaryOperationType::ALL_OPERATION_TYPES[operationIndex]); + operators.emplace_back(operators.size(), SimpleExpressionBinaryOperationType::ALL_OPERATION_TYPES[operationIndex]); } else break; @@ -129,7 +129,7 @@ std::unique_ptr MenuCommonMatchers::ProcessExpression(MenuFil throw ParsingException(TokenPos(), "Expected EvaluationTag @ Evaluation"); } - operators.sort([](const std::pair& p1, const std::pair& p2) + operators.sort([](const std::pair& p1, const std::pair& p2) { if (p1.second->m_precedence != p2.second->m_precedence) return p1.second->m_precedence > p2.second->m_precedence; @@ -141,7 +141,7 @@ std::unique_ptr MenuCommonMatchers::ProcessExpression(MenuFil { const auto [operatorIndex, operatorType] = operators.back(); - auto operation = std::make_unique(operatorType, std::move(operands[operatorIndex]), std::move(operands[operatorIndex + 1])); + auto operation = std::make_unique(operatorType, std::move(operands[operatorIndex]), std::move(operands[operatorIndex + 1])); operands.erase(operands.begin() + static_cast(operatorIndex)); operands[operatorIndex] = std::move(operation); @@ -176,71 +176,71 @@ std::unique_ptr MenuCommonMatchers::ParseBinaryOp return create.Or({ create.Char('+').Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(BinaryOperationId::ADD)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleBinaryOperationId::ADD)); }), create.Char('-').Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(BinaryOperationId::SUBTRACT)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleBinaryOperationId::SUBTRACT)); }), create.Char('*').Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(BinaryOperationId::MULTIPLY)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleBinaryOperationId::MULTIPLY)); }), create.Char('/').Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(BinaryOperationId::DIVIDE)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleBinaryOperationId::DIVIDE)); }), create.Char('%').Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(BinaryOperationId::REMAINDER)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleBinaryOperationId::REMAINDER)); }), create.Char('&').Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(BinaryOperationId::BITWISE_AND)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleBinaryOperationId::BITWISE_AND)); }), create.Char('|').Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(BinaryOperationId::BITWISE_OR)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleBinaryOperationId::BITWISE_OR)); }), create.MultiChar(static_cast(MenuFileLexing::MultiChar::SHIFT_LEFT)).Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(BinaryOperationId::SHIFT_LEFT)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleBinaryOperationId::SHIFT_LEFT)); }), create.MultiChar(static_cast(MenuFileLexing::MultiChar::SHIFT_RIGHT)).Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(BinaryOperationId::SHIFT_RIGHT)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleBinaryOperationId::SHIFT_RIGHT)); }), create.Char('>').Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(BinaryOperationId::GREATER_THAN)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleBinaryOperationId::GREATER_THAN)); }), create.MultiChar(static_cast(MenuFileLexing::MultiChar::GREATER_EQUAL)).Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(BinaryOperationId::GREATER_EQUAL_THAN)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleBinaryOperationId::GREATER_EQUAL_THAN)); }), create.Char('<').Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(BinaryOperationId::LESS_THAN)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleBinaryOperationId::LESS_THAN)); }), create.MultiChar(static_cast(MenuFileLexing::MultiChar::LESS_EQUAL)).Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(BinaryOperationId::LESS_EQUAL_THAN)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleBinaryOperationId::LESS_EQUAL_THAN)); }), create.MultiChar(static_cast(MenuFileLexing::MultiChar::EQUALS)).Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(BinaryOperationId::EQUALS)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleBinaryOperationId::EQUALS)); }), create.MultiChar(static_cast(MenuFileLexing::MultiChar::NOT_EQUAL)).Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(BinaryOperationId::NOT_EQUAL)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleBinaryOperationId::NOT_EQUAL)); }), create.MultiChar(static_cast(MenuFileLexing::MultiChar::LOGICAL_AND)).Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(BinaryOperationId::AND)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleBinaryOperationId::AND)); }), create.MultiChar(static_cast(MenuFileLexing::MultiChar::LOGICAL_OR)).Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(BinaryOperationId::OR)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleBinaryOperationId::OR)); }), }).Capture(CAPTURE_BINARY_OPERATION_TYPE); } @@ -270,15 +270,15 @@ std::unique_ptr MenuCommonMatchers::ParseUnaryOpe return create.Or({ create.Char('!').Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(UnaryOperationId::NOT)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleUnaryOperationId::NOT)); }), create.Char('~').Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(UnaryOperationId::BITWISE_NOT)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleUnaryOperationId::BITWISE_NOT)); }), create.Char('-').Transform([](const MenuMatcherFactory::token_list_t& values) { - return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(UnaryOperationId::NEGATIVE)); + return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast(SimpleUnaryOperationId::NEGATIVE)); }), }).Tag(TAG_EXPRESSION_UNARY_OPERATION).Capture(CAPTURE_UNARY_OPERATION_TYPE); } diff --git a/src/ObjLoading/Parsing/Menu/Matcher/MenuCommonMatchers.h b/src/ObjLoading/Parsing/Menu/Matcher/MenuCommonMatchers.h index d95433a4..6d90151b 100644 --- a/src/ObjLoading/Parsing/Menu/Matcher/MenuCommonMatchers.h +++ b/src/ObjLoading/Parsing/Menu/Matcher/MenuCommonMatchers.h @@ -6,7 +6,7 @@ #include "Parsing/Matcher/AbstractMatcher.h" #include "Parsing/Matcher/MatcherLabel.h" #include "Parsing/Menu/MenuFileParser.h" -#include "Parsing/Menu/Domain/Expression/ICommonExpression.h" +#include "Parsing/Simple/Expression/ISimpleExpression.h" #include "Parsing/Sequence/SequenceResult.h" #include "Parsing/Simple/SimpleParserValue.h" @@ -26,12 +26,12 @@ namespace menu static std::unique_ptr ParseFunctionCall(const supplier_t* labelSupplier); static std::unique_ptr ParseUnaryOperationType(const supplier_t* labelSupplier); - static std::unique_ptr ProcessExpressionInParenthesis(MenuFileParserState* state, SequenceResult& result); - static std::unique_ptr ProcessOperand(MenuFileParserState* state, SequenceResult& result); - static std::unique_ptr ProcessFunctionCall(MenuFileParserState* state, SequenceResult& result); + static std::unique_ptr ProcessExpressionInParenthesis(MenuFileParserState* state, SequenceResult& result); + static std::unique_ptr ProcessOperand(MenuFileParserState* state, SequenceResult& result); + static std::unique_ptr ProcessFunctionCall(MenuFileParserState* state, SequenceResult& result); public: static std::unique_ptr Expression(const supplier_t* labelSupplier); - static std::unique_ptr ProcessExpression(MenuFileParserState* state, SequenceResult& result); + static std::unique_ptr ProcessExpression(MenuFileParserState* state, SequenceResult& result); }; } diff --git a/src/ObjLoading/Parsing/Menu/Sequence/EventHandlerSetScopeSequences.cpp b/src/ObjLoading/Parsing/Menu/Sequence/EventHandlerSetScopeSequences.cpp index f88efc52..5325bbb8 100644 --- a/src/ObjLoading/Parsing/Menu/Sequence/EventHandlerSetScopeSequences.cpp +++ b/src/ObjLoading/Parsing/Menu/Sequence/EventHandlerSetScopeSequences.cpp @@ -360,40 +360,40 @@ namespace menu::event_handler_set_scope_sequences } } - static void EmitStaticValue(MenuFileParserState* state, const CommonExpressionValue& value) + static void EmitStaticValue(MenuFileParserState* state, const SimpleExpressionValue& value) { switch (value.m_type) { - case CommonExpressionValue::Type::DOUBLE: + case SimpleExpressionValue::Type::DOUBLE: state->m_current_script << value.m_double_value; break; - case CommonExpressionValue::Type::INT: + case SimpleExpressionValue::Type::INT: state->m_current_script << value.m_int_value; break; - case CommonExpressionValue::Type::STRING: + case SimpleExpressionValue::Type::STRING: state->m_current_script << *value.m_string_value; break; } } - static void CheckStaticValueType(const TokenPos& pos, const SetLocalVarType type, const CommonExpressionValue& staticValue) + static void CheckStaticValueType(const TokenPos& pos, const SetLocalVarType type, const SimpleExpressionValue& staticValue) { switch (type) { case SetLocalVarType::BOOL: - if (staticValue.m_type != CommonExpressionValue::Type::INT) + if (staticValue.m_type != SimpleExpressionValue::Type::INT) throw ParsingException(pos, "Static value must be BOOL"); break; case SetLocalVarType::INT: - if (staticValue.m_type != CommonExpressionValue::Type::INT) + if (staticValue.m_type != SimpleExpressionValue::Type::INT) throw ParsingException(pos, "Static value must be INT"); break; case SetLocalVarType::FLOAT: - if (staticValue.m_type != CommonExpressionValue::Type::DOUBLE && staticValue.m_type != CommonExpressionValue::Type::INT) + if (staticValue.m_type != SimpleExpressionValue::Type::DOUBLE && staticValue.m_type != SimpleExpressionValue::Type::INT) throw ParsingException(pos, "Static value must be FLOAT"); break; @@ -403,7 +403,7 @@ namespace menu::event_handler_set_scope_sequences } } - static void EmitStaticSetLocalVar(MenuFileParserState* state, const TokenPos& pos, const SetLocalVarType type, const std::string& varName, std::unique_ptr expression) + static void EmitStaticSetLocalVar(MenuFileParserState* state, const TokenPos& pos, const SetLocalVarType type, const std::string& varName, std::unique_ptr expression) { state->m_current_script << "\"" << ScriptKeywordForType(type) << "\" \"" << varName << "\" \""; const auto staticValue = expression->Evaluate(); @@ -412,7 +412,7 @@ namespace menu::event_handler_set_scope_sequences state->m_current_script << "\" ; "; } - static void EmitDynamicSetLocalVar(const MenuFileParserState* state, const SetLocalVarType type, const std::string& varName, std::unique_ptr expression) + static void EmitDynamicSetLocalVar(const MenuFileParserState* state, const SetLocalVarType type, const std::string& varName, std::unique_ptr expression) { state->m_current_nested_event_handler_set->m_elements.emplace_back(std::make_unique(type, varName, std::move(expression))); } diff --git a/src/ObjLoading/Parsing/Menu/Sequence/Generic/GenericExpressionPropertySequence.h b/src/ObjLoading/Parsing/Menu/Sequence/Generic/GenericExpressionPropertySequence.h index 7d85f04c..dab86f5e 100644 --- a/src/ObjLoading/Parsing/Menu/Sequence/Generic/GenericExpressionPropertySequence.h +++ b/src/ObjLoading/Parsing/Menu/Sequence/Generic/GenericExpressionPropertySequence.h @@ -4,14 +4,14 @@ #include #include "Parsing/Menu/MenuFileParser.h" -#include "Parsing/Menu/Domain/Expression/ICommonExpression.h" +#include "Parsing/Simple/Expression/ISimpleExpression.h" namespace menu { class GenericExpressionPropertySequence final : public MenuFileParser::sequence_t { public: - using callback_t = std::function value)>; + using callback_t = std::function value)>; private: static constexpr auto CAPTURE_FIRST_TOKEN = 1; diff --git a/src/ObjLoading/Parsing/Menu/Sequence/ItemScopeSequences.cpp b/src/ObjLoading/Parsing/Menu/Sequence/ItemScopeSequences.cpp index cb8ba142..30a9a22a 100644 --- a/src/ObjLoading/Parsing/Menu/Sequence/ItemScopeSequences.cpp +++ b/src/ObjLoading/Parsing/Menu/Sequence/ItemScopeSequences.cpp @@ -664,103 +664,103 @@ void ItemScopeSequences::AddSequences(FeatureLevel featureLevel) state->m_current_item->m_game_message_window_mode = value; })); AddSequence(std::make_unique()); - AddSequence(GenericExpressionPropertySequence::WithKeywordAndBool("visible", [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywordAndBool("visible", [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_visible_expression = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywordAndBool("disabled", [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywordAndBool("disabled", [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_disabled_expression = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "disabled"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "disabled"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_disabled_expression = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "text"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "text"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_text_expression = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "material"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "material"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_material_expression = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "material"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "material"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_material_expression = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "X"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "X"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_rect_x_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "Y"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "Y"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_rect_y_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "W"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "W"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_rect_w_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "H"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "H"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_rect_h_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "forecolor", "R"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "forecolor", "R"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_forecolor_expressions.m_r_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "forecolor", "G"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "forecolor", "G"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_forecolor_expressions.m_g_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "forecolor", "B"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "forecolor", "B"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_forecolor_expressions.m_b_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "forecolor", "A"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "forecolor", "A"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_forecolor_expressions.m_a_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "forecolor", "RGB"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "forecolor", "RGB"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_forecolor_expressions.m_rgb_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "glowcolor", "R"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "glowcolor", "R"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_glowcolor_expressions.m_r_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "glowcolor", "G"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "glowcolor", "G"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_glowcolor_expressions.m_g_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "glowcolor", "B"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "glowcolor", "B"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_glowcolor_expressions.m_b_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "glowcolor", "A"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "glowcolor", "A"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_glowcolor_expressions.m_a_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "glowcolor", "RGB"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "glowcolor", "RGB"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_glowcolor_expressions.m_rgb_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "backcolor", "R"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "backcolor", "R"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_backcolor_expressions.m_r_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "backcolor", "G"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "backcolor", "G"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_backcolor_expressions.m_g_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "backcolor", "B"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "backcolor", "B"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_backcolor_expressions.m_b_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "backcolor", "A"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "backcolor", "A"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_backcolor_expressions.m_a_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "backcolor", "RGB"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "backcolor", "RGB"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_item->m_backcolor_expressions.m_rgb_exp = std::move(value); })); diff --git a/src/ObjLoading/Parsing/Menu/Sequence/MenuScopeSequences.cpp b/src/ObjLoading/Parsing/Menu/Sequence/MenuScopeSequences.cpp index 64840370..e6c21d32 100644 --- a/src/ObjLoading/Parsing/Menu/Sequence/MenuScopeSequences.cpp +++ b/src/ObjLoading/Parsing/Menu/Sequence/MenuScopeSequences.cpp @@ -323,23 +323,23 @@ void MenuScopeSequences::AddSequences(FeatureLevel featureLevel) { state->m_current_menu->m_text_only_focus = true; })); - AddSequence(GenericExpressionPropertySequence::WithKeywordAndBool("visible", [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywordAndBool("visible", [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_menu->m_visible_expression = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "X"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "X"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_menu->m_rect_x_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "Y"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "Y"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_menu->m_rect_y_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "W"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "W"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_menu->m_rect_w_exp = std::move(value); })); - AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "H"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) + AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "H"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr value) { state->m_current_menu->m_rect_h_exp = std::move(value); })); diff --git a/src/Parser/Parsing/Simple/Expression/ISimpleExpression.h b/src/Parser/Parsing/Simple/Expression/ISimpleExpression.h new file mode 100644 index 00000000..35d80591 --- /dev/null +++ b/src/Parser/Parsing/Simple/Expression/ISimpleExpression.h @@ -0,0 +1,20 @@ +#pragma once + +class SimpleExpressionValue; +class ISimpleExpression +{ +protected: + ISimpleExpression() = default; +public: + virtual ~ISimpleExpression() = default; + ISimpleExpression(const ISimpleExpression& other) = default; + ISimpleExpression(ISimpleExpression&& other) noexcept = default; + ISimpleExpression& operator=(const ISimpleExpression& other) = default; + ISimpleExpression& operator=(ISimpleExpression&& other) noexcept = default; + + virtual bool IsStatic() = 0; + virtual SimpleExpressionValue Evaluate() = 0; +}; + +// Include SimpleExpressionValue after definition to avoid "base class not defined" +#include "SimpleExpressionValue.h" \ No newline at end of file diff --git a/src/Parser/Parsing/Simple/Expression/SimpleExpressionBinaryOperation.cpp b/src/Parser/Parsing/Simple/Expression/SimpleExpressionBinaryOperation.cpp new file mode 100644 index 00000000..7120b30f --- /dev/null +++ b/src/Parser/Parsing/Simple/Expression/SimpleExpressionBinaryOperation.cpp @@ -0,0 +1,437 @@ +#include "SimpleExpressionBinaryOperation.h" + +#include +#include + +SimpleExpressionBinaryOperationType::SimpleExpressionBinaryOperationType(std::string syntax, const SimpleOperationPrecedence precedence, evaluation_function_t evaluationFunction) + : m_syntax(std::move(syntax)), + m_precedence(precedence), + m_evaluation_function(std::move(evaluationFunction)) +{ +} + +const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_ADD( + "+", + SimpleOperationPrecedence::ADDITION_SUBTRACTION, + [](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue + { + if (operand1.m_type == SimpleExpressionValue::Type::DOUBLE) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(operand1.m_double_value + operand2.m_double_value); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_double_value + static_cast(operand2.m_int_value)); + if (operand2.m_type == SimpleExpressionValue::Type::STRING) + return SimpleExpressionValue(std::to_string(operand1.m_double_value) + *operand2.m_string_value); + } + else if (operand1.m_type == SimpleExpressionValue::Type::INT) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(static_cast(operand1.m_int_value) + operand2.m_double_value); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_int_value + operand2.m_int_value); + if (operand2.m_type == SimpleExpressionValue::Type::STRING) + return SimpleExpressionValue(std::to_string(operand1.m_int_value) + *operand2.m_string_value); + } + else if (operand1.m_type == SimpleExpressionValue::Type::STRING) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(*operand1.m_string_value + std::to_string(operand2.m_double_value)); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(*operand1.m_string_value + std::to_string(operand2.m_int_value)); + if (operand2.m_type == SimpleExpressionValue::Type::STRING) + return SimpleExpressionValue(*operand1.m_string_value + *operand2.m_string_value); + } + + return SimpleExpressionValue(0); + } +); + +const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_SUBTRACT( + "-", + SimpleOperationPrecedence::ADDITION_SUBTRACTION, + [](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue + { + if (operand1.m_type == SimpleExpressionValue::Type::DOUBLE) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(operand1.m_double_value - operand2.m_double_value); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_double_value - static_cast(operand2.m_int_value)); + } + else if (operand1.m_type == SimpleExpressionValue::Type::INT) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(static_cast(operand1.m_int_value) - operand2.m_double_value); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_int_value - operand2.m_int_value); + } + + return SimpleExpressionValue(0); + } +); + +const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_MULTIPLY( + "*", + SimpleOperationPrecedence::MULTIPLICATION_DIVISION_REMAINDER, + [](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue + { + if (operand1.m_type == SimpleExpressionValue::Type::DOUBLE) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(operand1.m_double_value * operand2.m_double_value); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_double_value * static_cast(operand2.m_int_value)); + } + else if (operand1.m_type == SimpleExpressionValue::Type::INT) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(static_cast(operand1.m_int_value) * operand2.m_double_value); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_int_value * operand2.m_int_value); + } + + return SimpleExpressionValue(0); + } +); + +const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_DIVIDE( + "/", + SimpleOperationPrecedence::MULTIPLICATION_DIVISION_REMAINDER, + [](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue + { + if (operand1.m_type == SimpleExpressionValue::Type::DOUBLE) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(operand1.m_double_value / operand2.m_double_value); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_double_value / static_cast(operand2.m_int_value)); + } + else if (operand1.m_type == SimpleExpressionValue::Type::INT) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(static_cast(operand1.m_int_value) / operand2.m_double_value); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_int_value / operand2.m_int_value); + } + + return SimpleExpressionValue(0); + } +); + +const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_REMAINDER( + "%", + SimpleOperationPrecedence::MULTIPLICATION_DIVISION_REMAINDER, + [](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue + { + if (operand1.m_type == SimpleExpressionValue::Type::INT && operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_int_value % operand2.m_int_value); + + return SimpleExpressionValue(0); + } +); + +const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_BITWISE_AND( + "&", + SimpleOperationPrecedence::BITWISE_AND, + [](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue + { + if (operand1.m_type == SimpleExpressionValue::Type::INT && operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_int_value & operand2.m_int_value); + + return SimpleExpressionValue(0); + } +); + +const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_BITWISE_OR( + "|", + SimpleOperationPrecedence::BITWISE_OR, + [](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue + { + if (operand1.m_type == SimpleExpressionValue::Type::INT && operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_int_value | operand2.m_int_value); + + return SimpleExpressionValue(0); + } +); + +const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_SHIFT_LEFT( + "<<", + SimpleOperationPrecedence::BITWISE_SHIFT, + [](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue + { + if (operand1.m_type == SimpleExpressionValue::Type::INT && operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_int_value << operand2.m_int_value); + + return SimpleExpressionValue(0); + } +); + +const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_SHIFT_RIGHT( + ">>", + SimpleOperationPrecedence::BITWISE_SHIFT, + [](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue + { + if (operand1.m_type == SimpleExpressionValue::Type::INT && operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_int_value >> operand2.m_int_value); + + return SimpleExpressionValue(0); + } +); + +const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_GREATER_THAN( + ">", + SimpleOperationPrecedence::RELATIONAL_GREATER_LESS_THAN, + [](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue + { + if (operand1.m_type == SimpleExpressionValue::Type::STRING || operand2.m_type == SimpleExpressionValue::Type::STRING) + return SimpleExpressionValue(operand1.IsTruthy() > operand2.IsTruthy()); + + if (operand1.m_type == SimpleExpressionValue::Type::DOUBLE) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(operand1.m_double_value > operand2.m_double_value); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_double_value > operand2.m_int_value); + } + else if (operand1.m_type == SimpleExpressionValue::Type::INT) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(operand1.m_int_value > operand2.m_double_value); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_int_value > operand2.m_int_value); + } + + return SimpleExpressionValue(0); + } +); + +const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_GREATER_EQUAL_THAN( + ">=", + SimpleOperationPrecedence::RELATIONAL_GREATER_LESS_THAN, + [](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue + { + if (operand1.m_type == SimpleExpressionValue::Type::STRING || operand2.m_type == SimpleExpressionValue::Type::STRING) + return SimpleExpressionValue(operand1.IsTruthy() >= operand2.IsTruthy()); + + if (operand1.m_type == SimpleExpressionValue::Type::DOUBLE) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(operand1.m_double_value >= operand2.m_double_value); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_double_value >= operand2.m_int_value); + } + else if (operand1.m_type == SimpleExpressionValue::Type::INT) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(operand1.m_int_value >= operand2.m_double_value); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_int_value >= operand2.m_int_value); + } + + return SimpleExpressionValue(0); + } +); + +const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_LESS_THAN( + "<", + SimpleOperationPrecedence::RELATIONAL_GREATER_LESS_THAN, + [](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue + { + if (operand1.m_type == SimpleExpressionValue::Type::STRING || operand2.m_type == SimpleExpressionValue::Type::STRING) + return SimpleExpressionValue(operand1.IsTruthy() < operand2.IsTruthy()); + + if (operand1.m_type == SimpleExpressionValue::Type::DOUBLE) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(operand1.m_double_value < operand2.m_double_value); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_double_value < operand2.m_int_value); + } + else if (operand1.m_type == SimpleExpressionValue::Type::INT) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(operand1.m_int_value < operand2.m_double_value); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_int_value < operand2.m_int_value); + } + + return SimpleExpressionValue(0); + } +); + +const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_LESS_EQUAL_THAN( + "<=", + SimpleOperationPrecedence::RELATIONAL_GREATER_LESS_THAN, + [](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue + { + if (operand1.m_type == SimpleExpressionValue::Type::STRING || operand2.m_type == SimpleExpressionValue::Type::STRING) + return SimpleExpressionValue(operand1.IsTruthy() <= operand2.IsTruthy()); + + if (operand1.m_type == SimpleExpressionValue::Type::DOUBLE) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(operand1.m_double_value <= operand2.m_double_value); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_double_value <= operand2.m_int_value); + } + else if (operand1.m_type == SimpleExpressionValue::Type::INT) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(operand1.m_int_value <= operand2.m_double_value); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_int_value <= operand2.m_int_value); + } + + return SimpleExpressionValue(0); + } +); + +const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_EQUALS( + "==", + SimpleOperationPrecedence::RELATIONAL_EQUALS, + [](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue + { + if (operand1.m_type == SimpleExpressionValue::Type::DOUBLE) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(std::fpclassify(operand1.m_double_value - operand2.m_double_value) == FP_ZERO); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(std::fpclassify(operand1.m_double_value - static_cast(operand2.m_int_value)) == FP_ZERO); + + return SimpleExpressionValue(0); + } + + if (operand1.m_type == SimpleExpressionValue::Type::INT) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(std::fpclassify(operand1.m_double_value - operand2.m_double_value) == FP_ZERO); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_int_value == operand2.m_int_value); + + return SimpleExpressionValue(0); + } + + if (operand1.m_type == SimpleExpressionValue::Type::STRING) + { + if (operand2.m_type == SimpleExpressionValue::Type::STRING) + return SimpleExpressionValue(*operand1.m_string_value == *operand2.m_string_value); + + return SimpleExpressionValue(0); + } + + return SimpleExpressionValue(0); + } +); + +const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_NOT_EQUAL( + "!=", + SimpleOperationPrecedence::RELATIONAL_EQUALS, + [](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue + { + if (operand1.m_type == SimpleExpressionValue::Type::DOUBLE) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(std::fpclassify(operand1.m_double_value - operand2.m_double_value) != FP_ZERO); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(std::fpclassify(operand1.m_double_value - static_cast(operand2.m_int_value)) != FP_ZERO); + + return SimpleExpressionValue(0); + } + + if (operand1.m_type == SimpleExpressionValue::Type::INT) + { + if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(std::fpclassify(operand1.m_double_value - operand2.m_double_value) != FP_ZERO); + if (operand2.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(operand1.m_int_value != operand2.m_int_value); + + return SimpleExpressionValue(0); + } + + if (operand1.m_type == SimpleExpressionValue::Type::STRING) + { + if (operand2.m_type == SimpleExpressionValue::Type::STRING) + return SimpleExpressionValue(*operand1.m_string_value != *operand2.m_string_value); + + return SimpleExpressionValue(0); + } + + return SimpleExpressionValue(0); + } +); + +const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_AND( + "&&", + SimpleOperationPrecedence::LOGICAL_AND, + [](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue + { + if (operand1.IsTruthy()) + return operand2; + return operand1; + } +); + +const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_OR( + "||", + SimpleOperationPrecedence::LOGICAL_OR, + [](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue + { + if (operand1.IsTruthy()) + return operand1; + return operand2; + } +); + +const SimpleExpressionBinaryOperationType* const SimpleExpressionBinaryOperationType::ALL_OPERATION_TYPES[static_cast(SimpleBinaryOperationId::COUNT)] +{ + &OPERATION_ADD, + &OPERATION_SUBTRACT, + &OPERATION_MULTIPLY, + &OPERATION_DIVIDE, + &OPERATION_REMAINDER, + &OPERATION_BITWISE_AND, + &OPERATION_BITWISE_OR, + &OPERATION_SHIFT_LEFT, + &OPERATION_SHIFT_RIGHT, + &OPERATION_GREATER_THAN, + &OPERATION_GREATER_EQUAL_THAN, + &OPERATION_LESS_THAN, + &OPERATION_LESS_EQUAL_THAN, + &OPERATION_EQUALS, + &OPERATION_NOT_EQUAL, + &OPERATION_AND, + &OPERATION_OR +}; + +SimpleExpressionBinaryOperation::SimpleExpressionBinaryOperation(const SimpleExpressionBinaryOperationType* operationType, std::unique_ptr operand1, + std::unique_ptr operand2) + : m_operation_type(operationType), + m_operand1(std::move(operand1)), + m_operand2(std::move(operand2)) +{ +} + +bool SimpleExpressionBinaryOperation::Operand1NeedsParenthesis() const +{ + const auto* operation = dynamic_cast(m_operand1.get()); + return operation && operation->m_operation_type->m_precedence > m_operation_type->m_precedence; +} + +bool SimpleExpressionBinaryOperation::Operand2NeedsParenthesis() const +{ + const auto* operation = dynamic_cast(m_operand2.get()); + return operation && operation->m_operation_type->m_precedence > m_operation_type->m_precedence; +} + +bool SimpleExpressionBinaryOperation::IsStatic() +{ + assert(m_operand1 && m_operand2); + + return m_operand1->IsStatic() && m_operand2->IsStatic(); +} + +SimpleExpressionValue SimpleExpressionBinaryOperation::Evaluate() +{ + return m_operation_type->m_evaluation_function(m_operand1->Evaluate(), m_operand2->Evaluate()); +} diff --git a/src/Parser/Parsing/Simple/Expression/SimpleExpressionBinaryOperation.h b/src/Parser/Parsing/Simple/Expression/SimpleExpressionBinaryOperation.h new file mode 100644 index 00000000..90eefe1f --- /dev/null +++ b/src/Parser/Parsing/Simple/Expression/SimpleExpressionBinaryOperation.h @@ -0,0 +1,97 @@ +#pragma once + +#include +#include +#include + +#include "ISimpleExpression.h" +#include "SimpleExpressionValue.h" + +// https://en.cppreference.com/w/cpp/language/operator_precedence +enum class SimpleOperationPrecedence +{ + MULTIPLICATION_DIVISION_REMAINDER = 1, + ADDITION_SUBTRACTION = 2, + BITWISE_SHIFT = 3, + RELATIONAL_GREATER_LESS_THAN = 4, + RELATIONAL_EQUALS = 5, + BITWISE_AND = 6, + BITWISE_OR = 8, + LOGICAL_AND = 9, + LOGICAL_OR = 10 +}; + +enum class SimpleBinaryOperationId +{ + ADD, + SUBTRACT, + MULTIPLY, + DIVIDE, + REMAINDER, + BITWISE_AND, + BITWISE_OR, + SHIFT_LEFT, + SHIFT_RIGHT, + GREATER_THAN, + GREATER_EQUAL_THAN, + LESS_THAN, + LESS_EQUAL_THAN, + EQUALS, + NOT_EQUAL, + AND, + OR, + + COUNT +}; + +class SimpleExpressionBinaryOperationType +{ +public: + using evaluation_function_t = std::function; + + std::string m_syntax; + SimpleOperationPrecedence m_precedence; + evaluation_function_t m_evaluation_function; + +private: + SimpleExpressionBinaryOperationType(std::string syntax, SimpleOperationPrecedence precedence, evaluation_function_t evaluationFunction); + +public: + static const SimpleExpressionBinaryOperationType OPERATION_ADD; + static const SimpleExpressionBinaryOperationType OPERATION_SUBTRACT; + static const SimpleExpressionBinaryOperationType OPERATION_MULTIPLY; + static const SimpleExpressionBinaryOperationType OPERATION_DIVIDE; + static const SimpleExpressionBinaryOperationType OPERATION_REMAINDER; + static const SimpleExpressionBinaryOperationType OPERATION_BITWISE_AND; + static const SimpleExpressionBinaryOperationType OPERATION_BITWISE_OR; + static const SimpleExpressionBinaryOperationType OPERATION_SHIFT_LEFT; + static const SimpleExpressionBinaryOperationType OPERATION_SHIFT_RIGHT; + static const SimpleExpressionBinaryOperationType OPERATION_GREATER_THAN; + static const SimpleExpressionBinaryOperationType OPERATION_GREATER_EQUAL_THAN; + static const SimpleExpressionBinaryOperationType OPERATION_LESS_THAN; + static const SimpleExpressionBinaryOperationType OPERATION_LESS_EQUAL_THAN; + static const SimpleExpressionBinaryOperationType OPERATION_EQUALS; + static const SimpleExpressionBinaryOperationType OPERATION_NOT_EQUAL; + static const SimpleExpressionBinaryOperationType OPERATION_AND; + static const SimpleExpressionBinaryOperationType OPERATION_OR; + + static const SimpleExpressionBinaryOperationType* const ALL_OPERATION_TYPES[static_cast(SimpleBinaryOperationId::COUNT)]; +}; + +class SimpleExpressionBinaryOperation final : public ISimpleExpression +{ +public: + const SimpleExpressionBinaryOperationType* m_operation_type; + std::unique_ptr m_operand1; + std::unique_ptr m_operand2; + + SimpleExpressionBinaryOperation(const SimpleExpressionBinaryOperationType* operationType, + std::unique_ptr operand1, + std::unique_ptr operand2); + + _NODISCARD bool Operand1NeedsParenthesis() const; + _NODISCARD bool Operand2NeedsParenthesis() const; + + bool IsStatic() override; + SimpleExpressionValue Evaluate() override; +}; diff --git a/src/Parser/Parsing/Simple/Expression/SimpleExpressionUnaryOperation.cpp b/src/Parser/Parsing/Simple/Expression/SimpleExpressionUnaryOperation.cpp new file mode 100644 index 00000000..05ece031 --- /dev/null +++ b/src/Parser/Parsing/Simple/Expression/SimpleExpressionUnaryOperation.cpp @@ -0,0 +1,73 @@ +#include "SimpleExpressionUnaryOperation.h" + +#include + +#include "SimpleExpressionBinaryOperation.h" + +SimpleExpressionUnaryOperationType::SimpleExpressionUnaryOperationType(std::string syntax, evaluation_function_t evaluationFunction) + : m_syntax(std::move(syntax)), + m_evaluation_function(std::move(evaluationFunction)) +{ +} + +const SimpleExpressionUnaryOperationType SimpleExpressionUnaryOperationType::OPERATION_NOT( + "!", + [](const SimpleExpressionValue& operand) -> SimpleExpressionValue + { + return SimpleExpressionValue(!operand.IsTruthy()); + } +); + +const SimpleExpressionUnaryOperationType SimpleExpressionUnaryOperationType::OPERATION_BITWISE_NOT( + "~", + [](const SimpleExpressionValue& operand) -> SimpleExpressionValue + { + if(operand.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(~operand.m_int_value); + + return SimpleExpressionValue(0); + } +); + +const SimpleExpressionUnaryOperationType SimpleExpressionUnaryOperationType::OPERATION_NEGATIVE( + "-", + [](const SimpleExpressionValue& operand) -> SimpleExpressionValue + { + if(operand.m_type == SimpleExpressionValue::Type::INT) + return SimpleExpressionValue(-operand.m_int_value); + if (operand.m_type == SimpleExpressionValue::Type::DOUBLE) + return SimpleExpressionValue(-operand.m_double_value); + + return SimpleExpressionValue(0); + } +); + +const SimpleExpressionUnaryOperationType* const SimpleExpressionUnaryOperationType::ALL_OPERATION_TYPES[static_cast(SimpleUnaryOperationId::COUNT)] +{ + &OPERATION_NOT, + &OPERATION_BITWISE_NOT, + &OPERATION_NEGATIVE, +}; + +SimpleExpressionUnaryOperation::SimpleExpressionUnaryOperation(const SimpleExpressionUnaryOperationType* operationType, std::unique_ptr operand) + : m_operation_type(operationType), + m_operand(std::move(operand)) +{ +} + +bool SimpleExpressionUnaryOperation::OperandNeedsParenthesis() const +{ + return dynamic_cast(m_operand.get()) != nullptr; +} + +bool SimpleExpressionUnaryOperation::IsStatic() +{ + assert(m_operand); + + return m_operand->IsStatic(); +} + +SimpleExpressionValue SimpleExpressionUnaryOperation::Evaluate() +{ + return m_operation_type->m_evaluation_function(m_operand->Evaluate()); +} diff --git a/src/Parser/Parsing/Simple/Expression/SimpleExpressionUnaryOperation.h b/src/Parser/Parsing/Simple/Expression/SimpleExpressionUnaryOperation.h new file mode 100644 index 00000000..771a7e0d --- /dev/null +++ b/src/Parser/Parsing/Simple/Expression/SimpleExpressionUnaryOperation.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include +#include + +#include "ISimpleExpression.h" +#include "SimpleExpressionValue.h" + +enum class SimpleUnaryOperationId +{ + NOT, + BITWISE_NOT, + NEGATIVE, + + COUNT +}; + +class SimpleExpressionUnaryOperationType +{ +public: + using evaluation_function_t = std::function; + + std::string m_syntax; + evaluation_function_t m_evaluation_function; + +private: + SimpleExpressionUnaryOperationType(std::string syntax, evaluation_function_t evaluationFunction); + +public: + static const SimpleExpressionUnaryOperationType OPERATION_NOT; + static const SimpleExpressionUnaryOperationType OPERATION_BITWISE_NOT; + static const SimpleExpressionUnaryOperationType OPERATION_NEGATIVE; + + static const SimpleExpressionUnaryOperationType* const ALL_OPERATION_TYPES[static_cast(SimpleUnaryOperationId::COUNT)]; +}; + +class SimpleExpressionUnaryOperation final : public ISimpleExpression +{ +public: + const SimpleExpressionUnaryOperationType* m_operation_type; + std::unique_ptr m_operand; + + SimpleExpressionUnaryOperation(const SimpleExpressionUnaryOperationType* operationType, std::unique_ptr operand); + + _NODISCARD bool OperandNeedsParenthesis() const; + + bool IsStatic() override; + SimpleExpressionValue Evaluate() override; +}; diff --git a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionValue.cpp b/src/Parser/Parsing/Simple/Expression/SimpleExpressionValue.cpp similarity index 63% rename from src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionValue.cpp rename to src/Parser/Parsing/Simple/Expression/SimpleExpressionValue.cpp index b0735886..212b1b49 100644 --- a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionValue.cpp +++ b/src/Parser/Parsing/Simple/Expression/SimpleExpressionValue.cpp @@ -1,10 +1,8 @@ -#include "CommonExpressionValue.h" +#include "SimpleExpressionValue.h" #include -using namespace menu; - -CommonExpressionValue::CommonExpressionValue(std::string stringValue) +SimpleExpressionValue::SimpleExpressionValue(std::string stringValue) : m_type(Type::STRING), m_string_value(std::make_shared(std::move(stringValue))) { @@ -12,31 +10,31 @@ CommonExpressionValue::CommonExpressionValue(std::string stringValue) m_int_value = 0; } -CommonExpressionValue::CommonExpressionValue(const double doubleValue) +SimpleExpressionValue::SimpleExpressionValue(const double doubleValue) : m_type(Type::DOUBLE) { m_int_value = 0; m_double_value = doubleValue; } -CommonExpressionValue::CommonExpressionValue(const int intValue) +SimpleExpressionValue::SimpleExpressionValue(const int intValue) : m_type(Type::INT) { m_double_value = 0; m_int_value = intValue; } -bool CommonExpressionValue::IsStatic() +bool SimpleExpressionValue::IsStatic() { return true; } -CommonExpressionValue CommonExpressionValue::Evaluate() +SimpleExpressionValue SimpleExpressionValue::Evaluate() { return *this; } -bool CommonExpressionValue::IsTruthy() const +bool SimpleExpressionValue::IsTruthy() const { if (m_type == Type::DOUBLE) return std::fpclassify(m_double_value) != FP_ZERO; diff --git a/src/Parser/Parsing/Simple/Expression/SimpleExpressionValue.h b/src/Parser/Parsing/Simple/Expression/SimpleExpressionValue.h new file mode 100644 index 00000000..d0608cf2 --- /dev/null +++ b/src/Parser/Parsing/Simple/Expression/SimpleExpressionValue.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +#include "ISimpleExpression.h" +#include "Utils/ClassUtils.h" + +class ISimpleExpression; +class SimpleExpressionValue final : public ISimpleExpression +{ +public: + enum class Type + { + STRING, + DOUBLE, + INT + }; + + Type m_type; + std::shared_ptr m_string_value; + union + { + double m_double_value; + int m_int_value; + }; + + explicit SimpleExpressionValue(std::string stringValue); + explicit SimpleExpressionValue(double doubleValue); + explicit SimpleExpressionValue(int intValue); + + bool IsStatic() override; + SimpleExpressionValue Evaluate() override; + _NODISCARD bool IsTruthy() const; +}; diff --git a/test/ObjLoadingTests/Parsing/Menu/Sequence/EventHandlerSetScopeSequencesTests.cpp b/test/ObjLoadingTests/Parsing/Menu/Sequence/EventHandlerSetScopeSequencesTests.cpp index 51f284d8..90d5b3e9 100644 --- a/test/ObjLoadingTests/Parsing/Menu/Sequence/EventHandlerSetScopeSequencesTests.cpp +++ b/test/ObjLoadingTests/Parsing/Menu/Sequence/EventHandlerSetScopeSequencesTests.cpp @@ -986,7 +986,7 @@ namespace test::parsing::menu::sequence::event_handler_set REQUIRE(conditionElement->m_condition != nullptr); REQUIRE(conditionElement->m_condition->IsStatic()); const auto staticValue = conditionElement->m_condition->Evaluate(); - REQUIRE(staticValue.m_type == CommonExpressionValue::Type::INT); + REQUIRE(staticValue.m_type == SimpleExpressionValue::Type::INT); REQUIRE(staticValue.m_int_value == 1337); REQUIRE(conditionElement->m_condition_elements); @@ -1079,7 +1079,7 @@ namespace test::parsing::menu::sequence::event_handler_set REQUIRE(conditionElement->m_condition != nullptr); REQUIRE(conditionElement->m_condition->IsStatic()); const auto staticValue = conditionElement->m_condition->Evaluate(); - REQUIRE(staticValue.m_type == CommonExpressionValue::Type::INT); + REQUIRE(staticValue.m_type == SimpleExpressionValue::Type::INT); REQUIRE(staticValue.m_int_value == 1337); REQUIRE(conditionElement->m_condition_elements);