mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-05-11 06:54:56 +00:00
Move common expression classes to simple parsing setup
This commit is contained in:
parent
5baa311025
commit
4f2a8454a6
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include "CommonMenuTypes.h"
|
#include "CommonMenuTypes.h"
|
||||||
#include "EventHandler/CommonEventHandlerSet.h"
|
#include "EventHandler/CommonEventHandlerSet.h"
|
||||||
#include "Expression/ICommonExpression.h"
|
#include "Parsing/Simple/Expression/ISimpleExpression.h"
|
||||||
|
|
||||||
namespace menu
|
namespace menu
|
||||||
{
|
{
|
||||||
@ -82,11 +82,11 @@ namespace menu
|
|||||||
class ColorExpressions
|
class ColorExpressions
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::unique_ptr<ICommonExpression> m_r_exp;
|
std::unique_ptr<ISimpleExpression> m_r_exp;
|
||||||
std::unique_ptr<ICommonExpression> m_g_exp;
|
std::unique_ptr<ISimpleExpression> m_g_exp;
|
||||||
std::unique_ptr<ICommonExpression> m_b_exp;
|
std::unique_ptr<ISimpleExpression> m_b_exp;
|
||||||
std::unique_ptr<ICommonExpression> m_a_exp;
|
std::unique_ptr<ISimpleExpression> m_a_exp;
|
||||||
std::unique_ptr<ICommonExpression> m_rgb_exp;
|
std::unique_ptr<ISimpleExpression> m_rgb_exp;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
@ -133,14 +133,14 @@ namespace menu
|
|||||||
int m_fx_decay_start_time;
|
int m_fx_decay_start_time;
|
||||||
int m_fx_decay_duration;
|
int m_fx_decay_duration;
|
||||||
|
|
||||||
std::unique_ptr<ICommonExpression> m_visible_expression;
|
std::unique_ptr<ISimpleExpression> m_visible_expression;
|
||||||
std::unique_ptr<ICommonExpression> m_disabled_expression;
|
std::unique_ptr<ISimpleExpression> m_disabled_expression;
|
||||||
std::unique_ptr<ICommonExpression> m_text_expression;
|
std::unique_ptr<ISimpleExpression> m_text_expression;
|
||||||
std::unique_ptr<ICommonExpression> m_material_expression;
|
std::unique_ptr<ISimpleExpression> m_material_expression;
|
||||||
std::unique_ptr<ICommonExpression> m_rect_x_exp;
|
std::unique_ptr<ISimpleExpression> m_rect_x_exp;
|
||||||
std::unique_ptr<ICommonExpression> m_rect_y_exp;
|
std::unique_ptr<ISimpleExpression> m_rect_y_exp;
|
||||||
std::unique_ptr<ICommonExpression> m_rect_w_exp;
|
std::unique_ptr<ISimpleExpression> m_rect_w_exp;
|
||||||
std::unique_ptr<ICommonExpression> m_rect_h_exp;
|
std::unique_ptr<ISimpleExpression> m_rect_h_exp;
|
||||||
ColorExpressions m_forecolor_expressions;
|
ColorExpressions m_forecolor_expressions;
|
||||||
ColorExpressions m_glowcolor_expressions;
|
ColorExpressions m_glowcolor_expressions;
|
||||||
ColorExpressions m_backcolor_expressions;
|
ColorExpressions m_backcolor_expressions;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "CommonItemDef.h"
|
#include "CommonItemDef.h"
|
||||||
#include "CommonMenuTypes.h"
|
#include "CommonMenuTypes.h"
|
||||||
#include "EventHandler/CommonEventHandlerSet.h"
|
#include "EventHandler/CommonEventHandlerSet.h"
|
||||||
#include "Expression/ICommonExpression.h"
|
#include "Parsing/Simple/Expression/ISimpleExpression.h"
|
||||||
|
|
||||||
namespace menu
|
namespace menu
|
||||||
{
|
{
|
||||||
@ -34,13 +34,13 @@ namespace menu
|
|||||||
double m_fade_in_amount;
|
double m_fade_in_amount;
|
||||||
double m_blur_radius;
|
double m_blur_radius;
|
||||||
std::string m_allowed_binding;
|
std::string m_allowed_binding;
|
||||||
std::unique_ptr<ICommonExpression> m_visible_expression;
|
std::unique_ptr<ISimpleExpression> m_visible_expression;
|
||||||
std::unique_ptr<ICommonExpression> m_rect_x_exp;
|
std::unique_ptr<ISimpleExpression> m_rect_x_exp;
|
||||||
std::unique_ptr<ICommonExpression> m_rect_y_exp;
|
std::unique_ptr<ISimpleExpression> m_rect_y_exp;
|
||||||
std::unique_ptr<ICommonExpression> m_rect_w_exp;
|
std::unique_ptr<ISimpleExpression> m_rect_w_exp;
|
||||||
std::unique_ptr<ICommonExpression> m_rect_h_exp;
|
std::unique_ptr<ISimpleExpression> m_rect_h_exp;
|
||||||
std::unique_ptr<ICommonExpression> m_open_sound_exp;
|
std::unique_ptr<ISimpleExpression> m_open_sound_exp;
|
||||||
std::unique_ptr<ICommonExpression> m_close_sound_exp;
|
std::unique_ptr<ISimpleExpression> m_close_sound_exp;
|
||||||
std::unique_ptr<CommonEventHandlerSet> m_on_open;
|
std::unique_ptr<CommonEventHandlerSet> m_on_open;
|
||||||
std::unique_ptr<CommonEventHandlerSet> m_on_close;
|
std::unique_ptr<CommonEventHandlerSet> m_on_close;
|
||||||
std::unique_ptr<CommonEventHandlerSet> m_on_request_close;
|
std::unique_ptr<CommonEventHandlerSet> m_on_request_close;
|
||||||
|
@ -5,7 +5,7 @@ using namespace menu;
|
|||||||
CommonEventHandlerCondition::CommonEventHandlerCondition()
|
CommonEventHandlerCondition::CommonEventHandlerCondition()
|
||||||
= default;
|
= default;
|
||||||
|
|
||||||
CommonEventHandlerCondition::CommonEventHandlerCondition(std::unique_ptr<ICommonExpression> condition, std::unique_ptr<CommonEventHandlerSet> conditionElements,
|
CommonEventHandlerCondition::CommonEventHandlerCondition(std::unique_ptr<ISimpleExpression> condition, std::unique_ptr<CommonEventHandlerSet> conditionElements,
|
||||||
std::unique_ptr<CommonEventHandlerSet> elseElements)
|
std::unique_ptr<CommonEventHandlerSet> elseElements)
|
||||||
: m_condition(std::move(condition)),
|
: m_condition(std::move(condition)),
|
||||||
m_condition_elements(std::move(conditionElements)),
|
m_condition_elements(std::move(conditionElements)),
|
||||||
|
@ -4,19 +4,19 @@
|
|||||||
|
|
||||||
#include "CommonEventHandlerSet.h"
|
#include "CommonEventHandlerSet.h"
|
||||||
#include "ICommonEventHandlerElement.h"
|
#include "ICommonEventHandlerElement.h"
|
||||||
#include "Parsing/Menu/Domain/Expression/ICommonExpression.h"
|
#include "Parsing/Simple/Expression/ISimpleExpression.h"
|
||||||
|
|
||||||
namespace menu
|
namespace menu
|
||||||
{
|
{
|
||||||
class CommonEventHandlerCondition final : public ICommonEventHandlerElement
|
class CommonEventHandlerCondition final : public ICommonEventHandlerElement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::unique_ptr<ICommonExpression> m_condition;
|
std::unique_ptr<ISimpleExpression> m_condition;
|
||||||
std::unique_ptr<CommonEventHandlerSet> m_condition_elements;
|
std::unique_ptr<CommonEventHandlerSet> m_condition_elements;
|
||||||
std::unique_ptr<CommonEventHandlerSet> m_else_elements;
|
std::unique_ptr<CommonEventHandlerSet> m_else_elements;
|
||||||
|
|
||||||
CommonEventHandlerCondition();
|
CommonEventHandlerCondition();
|
||||||
CommonEventHandlerCondition(std::unique_ptr<ICommonExpression> condition, std::unique_ptr<CommonEventHandlerSet> conditionElements,
|
CommonEventHandlerCondition(std::unique_ptr<ISimpleExpression> condition, std::unique_ptr<CommonEventHandlerSet> conditionElements,
|
||||||
std::unique_ptr<CommonEventHandlerSet> elseElements);
|
std::unique_ptr<CommonEventHandlerSet> elseElements);
|
||||||
|
|
||||||
_NODISCARD CommonEventHandlerElementType GetType() const override;
|
_NODISCARD CommonEventHandlerElementType GetType() const override;
|
||||||
|
@ -7,7 +7,7 @@ CommonEventHandlerSetLocalVar::CommonEventHandlerSetLocalVar()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CommonEventHandlerSetLocalVar::CommonEventHandlerSetLocalVar(SetLocalVarType type, std::string varName, std::unique_ptr<ICommonExpression> value)
|
CommonEventHandlerSetLocalVar::CommonEventHandlerSetLocalVar(SetLocalVarType type, std::string varName, std::unique_ptr<ISimpleExpression> value)
|
||||||
: m_type(type),
|
: m_type(type),
|
||||||
m_var_name(std::move(varName)),
|
m_var_name(std::move(varName)),
|
||||||
m_value(std::move(value))
|
m_value(std::move(value))
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "ICommonEventHandlerElement.h"
|
#include "ICommonEventHandlerElement.h"
|
||||||
#include "Parsing/Menu/Domain/Expression/ICommonExpression.h"
|
#include "Parsing/Simple/Expression/ISimpleExpression.h"
|
||||||
|
|
||||||
namespace menu
|
namespace menu
|
||||||
{
|
{
|
||||||
@ -21,10 +21,10 @@ namespace menu
|
|||||||
public:
|
public:
|
||||||
SetLocalVarType m_type;
|
SetLocalVarType m_type;
|
||||||
std::string m_var_name;
|
std::string m_var_name;
|
||||||
std::unique_ptr<ICommonExpression> m_value;
|
std::unique_ptr<ISimpleExpression> m_value;
|
||||||
|
|
||||||
CommonEventHandlerSetLocalVar();
|
CommonEventHandlerSetLocalVar();
|
||||||
CommonEventHandlerSetLocalVar(SetLocalVarType type, std::string varName, std::unique_ptr<ICommonExpression> value);
|
CommonEventHandlerSetLocalVar(SetLocalVarType type, std::string varName, std::unique_ptr<ISimpleExpression> value);
|
||||||
|
|
||||||
_NODISCARD CommonEventHandlerElementType GetType() const override;
|
_NODISCARD CommonEventHandlerElementType GetType() const override;
|
||||||
};
|
};
|
||||||
|
@ -1,439 +0,0 @@
|
|||||||
#include "CommonExpressionBinaryOperation.h"
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
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<double>(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<double>(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<double>(operand2.m_int_value));
|
|
||||||
}
|
|
||||||
else if (operand1.m_type == CommonExpressionValue::Type::INT)
|
|
||||||
{
|
|
||||||
if (operand2.m_type == CommonExpressionValue::Type::DOUBLE)
|
|
||||||
return CommonExpressionValue(static_cast<double>(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<double>(operand2.m_int_value));
|
|
||||||
}
|
|
||||||
else if (operand1.m_type == CommonExpressionValue::Type::INT)
|
|
||||||
{
|
|
||||||
if (operand2.m_type == CommonExpressionValue::Type::DOUBLE)
|
|
||||||
return CommonExpressionValue(static_cast<double>(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<double>(operand2.m_int_value));
|
|
||||||
}
|
|
||||||
else if (operand1.m_type == CommonExpressionValue::Type::INT)
|
|
||||||
{
|
|
||||||
if (operand2.m_type == CommonExpressionValue::Type::DOUBLE)
|
|
||||||
return CommonExpressionValue(static_cast<double>(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<double>(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<double>(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<int>(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<ICommonExpression> operand1,
|
|
||||||
std::unique_ptr<ICommonExpression> operand2)
|
|
||||||
: m_operation_type(operationType),
|
|
||||||
m_operand1(std::move(operand1)),
|
|
||||||
m_operand2(std::move(operand2))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CommonExpressionBinaryOperation::Operand1NeedsParenthesis() const
|
|
||||||
{
|
|
||||||
const auto* operation = dynamic_cast<const CommonExpressionBinaryOperation*>(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<const CommonExpressionBinaryOperation*>(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());
|
|
||||||
}
|
|
@ -1,100 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <memory>
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#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<CommonExpressionValue(const CommonExpressionValue& operand1, const CommonExpressionValue& operand2)>;
|
|
||||||
|
|
||||||
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<int>(BinaryOperationId::COUNT)];
|
|
||||||
};
|
|
||||||
|
|
||||||
class CommonExpressionBinaryOperation final : public ICommonExpression
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
const CommonExpressionBinaryOperationType* m_operation_type;
|
|
||||||
std::unique_ptr<ICommonExpression> m_operand1;
|
|
||||||
std::unique_ptr<ICommonExpression> m_operand2;
|
|
||||||
|
|
||||||
CommonExpressionBinaryOperation(const CommonExpressionBinaryOperationType* operationType,
|
|
||||||
std::unique_ptr<ICommonExpression> operand1,
|
|
||||||
std::unique_ptr<ICommonExpression> operand2);
|
|
||||||
|
|
||||||
_NODISCARD bool Operand1NeedsParenthesis() const;
|
|
||||||
_NODISCARD bool Operand2NeedsParenthesis() const;
|
|
||||||
|
|
||||||
bool IsStatic() override;
|
|
||||||
CommonExpressionValue Evaluate() override;
|
|
||||||
};
|
|
||||||
}
|
|
@ -12,7 +12,7 @@ bool CommonExpressionFunctionCall::IsStatic()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommonExpressionValue CommonExpressionFunctionCall::Evaluate()
|
SimpleExpressionValue CommonExpressionFunctionCall::Evaluate()
|
||||||
{
|
{
|
||||||
return CommonExpressionValue(0);
|
return SimpleExpressionValue(0);
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "ICommonExpression.h"
|
#include "Parsing/Simple/Expression/ISimpleExpression.h"
|
||||||
|
|
||||||
namespace menu
|
namespace menu
|
||||||
{
|
{
|
||||||
class CommonExpressionFunctionCall final : public ICommonExpression
|
class CommonExpressionFunctionCall final : public ISimpleExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string m_function_name;
|
std::string m_function_name;
|
||||||
std::vector<std::unique_ptr<ICommonExpression>> m_args;
|
std::vector<std::unique_ptr<ISimpleExpression>> m_args;
|
||||||
|
|
||||||
explicit CommonExpressionFunctionCall(std::string functionName);
|
explicit CommonExpressionFunctionCall(std::string functionName);
|
||||||
|
|
||||||
bool IsStatic() override;
|
bool IsStatic() override;
|
||||||
CommonExpressionValue Evaluate() override;
|
SimpleExpressionValue Evaluate() override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,75 +0,0 @@
|
|||||||
#include "CommonExpressionUnaryOperation.h"
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#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<int>(UnaryOperationId::COUNT)]
|
|
||||||
{
|
|
||||||
&OPERATION_NOT,
|
|
||||||
&OPERATION_BITWISE_NOT,
|
|
||||||
&OPERATION_NEGATIVE,
|
|
||||||
};
|
|
||||||
|
|
||||||
CommonExpressionUnaryOperation::CommonExpressionUnaryOperation(const CommonExpressionUnaryOperationType* operationType, std::unique_ptr<ICommonExpression> operand)
|
|
||||||
: m_operation_type(operationType),
|
|
||||||
m_operand(std::move(operand))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CommonExpressionUnaryOperation::OperandNeedsParenthesis() const
|
|
||||||
{
|
|
||||||
return dynamic_cast<const CommonExpressionBinaryOperation*>(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());
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <memory>
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#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<CommonExpressionValue(const CommonExpressionValue& operand)>;
|
|
||||||
|
|
||||||
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<int>(UnaryOperationId::COUNT)];
|
|
||||||
};
|
|
||||||
|
|
||||||
class CommonExpressionUnaryOperation final : public ICommonExpression
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
const CommonExpressionUnaryOperationType* m_operation_type;
|
|
||||||
std::unique_ptr<ICommonExpression> m_operand;
|
|
||||||
|
|
||||||
CommonExpressionUnaryOperation(const CommonExpressionUnaryOperationType* operationType, std::unique_ptr<ICommonExpression> operand);
|
|
||||||
|
|
||||||
_NODISCARD bool OperandNeedsParenthesis() const;
|
|
||||||
|
|
||||||
bool IsStatic() override;
|
|
||||||
CommonExpressionValue Evaluate() override;
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#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<std::string> 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;
|
|
||||||
};
|
|
||||||
}
|
|
@ -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"
|
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
#include "MenuMatcherFactory.h"
|
#include "MenuMatcherFactory.h"
|
||||||
#include "Parsing/Menu/MenuFileLexing.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/CommonExpressionFunctionCall.h"
|
||||||
#include "Parsing/Menu/Domain/Expression/CommonExpressionUnaryOperation.h"
|
#include "Parsing/Simple/Expression/SimpleExpressionUnaryOperation.h"
|
||||||
|
|
||||||
using namespace menu;
|
using namespace menu;
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ static constexpr int CAPTURE_UNARY_OPERATION_TYPE = std::numeric_limits<int>::ma
|
|||||||
static constexpr int CAPTURE_BINARY_OPERATION_TYPE = std::numeric_limits<int>::max() - 3;
|
static constexpr int CAPTURE_BINARY_OPERATION_TYPE = std::numeric_limits<int>::max() - 3;
|
||||||
static constexpr int CAPTURE_FUNCTION_NAME = std::numeric_limits<int>::max() - 4;
|
static constexpr int CAPTURE_FUNCTION_NAME = std::numeric_limits<int>::max() - 4;
|
||||||
|
|
||||||
std::unique_ptr<ICommonExpression> MenuCommonMatchers::ProcessExpressionInParenthesis(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result)
|
std::unique_ptr<ISimpleExpression> MenuCommonMatchers::ProcessExpressionInParenthesis(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result)
|
||||||
{
|
{
|
||||||
auto processedEvaluation = ProcessExpression(state, result);
|
auto processedEvaluation = ProcessExpression(state, result);
|
||||||
|
|
||||||
@ -34,26 +34,26 @@ std::unique_ptr<ICommonExpression> MenuCommonMatchers::ProcessExpressionInParent
|
|||||||
return processedEvaluation;
|
return processedEvaluation;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ICommonExpression> MenuCommonMatchers::ProcessOperand(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result)
|
std::unique_ptr<ISimpleExpression> MenuCommonMatchers::ProcessOperand(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result)
|
||||||
{
|
{
|
||||||
const auto& operandToken = result.NextCapture(CAPTURE_OPERAND);
|
const auto& operandToken = result.NextCapture(CAPTURE_OPERAND);
|
||||||
|
|
||||||
switch (operandToken.m_type)
|
switch (operandToken.m_type)
|
||||||
{
|
{
|
||||||
case SimpleParserValueType::INTEGER:
|
case SimpleParserValueType::INTEGER:
|
||||||
return std::make_unique<CommonExpressionValue>(operandToken.IntegerValue());
|
return std::make_unique<SimpleExpressionValue>(operandToken.IntegerValue());
|
||||||
case SimpleParserValueType::FLOATING_POINT:
|
case SimpleParserValueType::FLOATING_POINT:
|
||||||
return std::make_unique<CommonExpressionValue>(operandToken.FloatingPointValue());
|
return std::make_unique<SimpleExpressionValue>(operandToken.FloatingPointValue());
|
||||||
case SimpleParserValueType::STRING:
|
case SimpleParserValueType::STRING:
|
||||||
return std::make_unique<CommonExpressionValue>(operandToken.StringValue());
|
return std::make_unique<SimpleExpressionValue>(operandToken.StringValue());
|
||||||
case SimpleParserValueType::IDENTIFIER:
|
case SimpleParserValueType::IDENTIFIER:
|
||||||
return std::make_unique<CommonExpressionValue>(operandToken.IdentifierValue());
|
return std::make_unique<SimpleExpressionValue>(operandToken.IdentifierValue());
|
||||||
default:
|
default:
|
||||||
throw ParsingException(TokenPos(), "Unknown operand type @ Operand");
|
throw ParsingException(TokenPos(), "Unknown operand type @ Operand");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ICommonExpression> MenuCommonMatchers::ProcessFunctionCall(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result)
|
std::unique_ptr<ISimpleExpression> MenuCommonMatchers::ProcessFunctionCall(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result)
|
||||||
{
|
{
|
||||||
auto functionCall = std::make_unique<CommonExpressionFunctionCall>(result.NextCapture(CAPTURE_FUNCTION_NAME).IdentifierValue());
|
auto functionCall = std::make_unique<CommonExpressionFunctionCall>(result.NextCapture(CAPTURE_FUNCTION_NAME).IdentifierValue());
|
||||||
|
|
||||||
@ -65,17 +65,17 @@ std::unique_ptr<ICommonExpression> MenuCommonMatchers::ProcessFunctionCall(MenuF
|
|||||||
return std::move(functionCall);
|
return std::move(functionCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ICommonExpression> MenuCommonMatchers::ProcessExpression(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result)
|
std::unique_ptr<ISimpleExpression> MenuCommonMatchers::ProcessExpression(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result)
|
||||||
{
|
{
|
||||||
if (result.PeekAndRemoveIfTag(TAG_EXPRESSION) != TAG_EXPRESSION)
|
if (result.PeekAndRemoveIfTag(TAG_EXPRESSION) != TAG_EXPRESSION)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<ICommonExpression>> operands;
|
std::vector<std::unique_ptr<ISimpleExpression>> operands;
|
||||||
std::list<std::pair<unsigned, const CommonExpressionBinaryOperationType*>> operators;
|
std::list<std::pair<unsigned, const SimpleExpressionBinaryOperationType*>> operators;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
std::unique_ptr<ICommonExpression> firstStatementPart;
|
std::unique_ptr<ISimpleExpression> firstStatementPart;
|
||||||
std::vector<int> unaryOperations;
|
std::vector<int> unaryOperations;
|
||||||
auto nextTag = result.NextTag();
|
auto nextTag = result.NextTag();
|
||||||
|
|
||||||
@ -106,9 +106,9 @@ std::unique_ptr<ICommonExpression> MenuCommonMatchers::ProcessExpression(MenuFil
|
|||||||
for (auto i = unaryOperations.size(); i > 0; i--)
|
for (auto i = unaryOperations.size(); i > 0; i--)
|
||||||
{
|
{
|
||||||
const auto operationIndex = unaryOperations[i - 1];
|
const auto operationIndex = unaryOperations[i - 1];
|
||||||
if (operationIndex < 0 || operationIndex >= static_cast<int>(UnaryOperationId::COUNT))
|
if (operationIndex < 0 || operationIndex >= static_cast<int>(SimpleUnaryOperationId::COUNT))
|
||||||
throw ParsingException(TokenPos(), "Invalid unary operation id @ Expression");
|
throw ParsingException(TokenPos(), "Invalid unary operation id @ Expression");
|
||||||
firstStatementPart = std::make_unique<CommonExpressionUnaryOperation>(CommonExpressionUnaryOperationType::ALL_OPERATION_TYPES[operationIndex],
|
firstStatementPart = std::make_unique<SimpleExpressionUnaryOperation>(SimpleExpressionUnaryOperationType::ALL_OPERATION_TYPES[operationIndex],
|
||||||
std::move(firstStatementPart));
|
std::move(firstStatementPart));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,10 +117,10 @@ std::unique_ptr<ICommonExpression> MenuCommonMatchers::ProcessExpression(MenuFil
|
|||||||
if (result.PeekAndRemoveIfTag(TAG_EXPRESSION_BINARY_OPERATION) == TAG_EXPRESSION_BINARY_OPERATION)
|
if (result.PeekAndRemoveIfTag(TAG_EXPRESSION_BINARY_OPERATION) == TAG_EXPRESSION_BINARY_OPERATION)
|
||||||
{
|
{
|
||||||
const auto operationIndex = result.NextCapture(CAPTURE_BINARY_OPERATION_TYPE).IntegerValue();
|
const auto operationIndex = result.NextCapture(CAPTURE_BINARY_OPERATION_TYPE).IntegerValue();
|
||||||
if (operationIndex < 0 || operationIndex >= static_cast<int>(BinaryOperationId::COUNT))
|
if (operationIndex < 0 || operationIndex >= static_cast<int>(SimpleBinaryOperationId::COUNT))
|
||||||
throw ParsingException(TokenPos(), "Invalid binary operation id @ Expression");
|
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
|
else
|
||||||
break;
|
break;
|
||||||
@ -129,7 +129,7 @@ std::unique_ptr<ICommonExpression> MenuCommonMatchers::ProcessExpression(MenuFil
|
|||||||
throw ParsingException(TokenPos(), "Expected EvaluationTag @ Evaluation");
|
throw ParsingException(TokenPos(), "Expected EvaluationTag @ Evaluation");
|
||||||
}
|
}
|
||||||
|
|
||||||
operators.sort([](const std::pair<unsigned, const CommonExpressionBinaryOperationType*>& p1, const std::pair<unsigned, const CommonExpressionBinaryOperationType*>& p2)
|
operators.sort([](const std::pair<unsigned, const SimpleExpressionBinaryOperationType*>& p1, const std::pair<unsigned, const SimpleExpressionBinaryOperationType*>& p2)
|
||||||
{
|
{
|
||||||
if (p1.second->m_precedence != p2.second->m_precedence)
|
if (p1.second->m_precedence != p2.second->m_precedence)
|
||||||
return p1.second->m_precedence > p2.second->m_precedence;
|
return p1.second->m_precedence > p2.second->m_precedence;
|
||||||
@ -141,7 +141,7 @@ std::unique_ptr<ICommonExpression> MenuCommonMatchers::ProcessExpression(MenuFil
|
|||||||
{
|
{
|
||||||
const auto [operatorIndex, operatorType] = operators.back();
|
const auto [operatorIndex, operatorType] = operators.back();
|
||||||
|
|
||||||
auto operation = std::make_unique<CommonExpressionBinaryOperation>(operatorType, std::move(operands[operatorIndex]), std::move(operands[operatorIndex + 1]));
|
auto operation = std::make_unique<SimpleExpressionBinaryOperation>(operatorType, std::move(operands[operatorIndex]), std::move(operands[operatorIndex + 1]));
|
||||||
operands.erase(operands.begin() + static_cast<int>(operatorIndex));
|
operands.erase(operands.begin() + static_cast<int>(operatorIndex));
|
||||||
operands[operatorIndex] = std::move(operation);
|
operands[operatorIndex] = std::move(operation);
|
||||||
|
|
||||||
@ -176,71 +176,71 @@ std::unique_ptr<MenuCommonMatchers::matcher_t> MenuCommonMatchers::ParseBinaryOp
|
|||||||
return create.Or({
|
return create.Or({
|
||||||
create.Char('+').Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.Char('+').Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(BinaryOperationId::ADD));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleBinaryOperationId::ADD));
|
||||||
}),
|
}),
|
||||||
create.Char('-').Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.Char('-').Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(BinaryOperationId::SUBTRACT));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleBinaryOperationId::SUBTRACT));
|
||||||
}),
|
}),
|
||||||
create.Char('*').Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.Char('*').Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(BinaryOperationId::MULTIPLY));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleBinaryOperationId::MULTIPLY));
|
||||||
}),
|
}),
|
||||||
create.Char('/').Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.Char('/').Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(BinaryOperationId::DIVIDE));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleBinaryOperationId::DIVIDE));
|
||||||
}),
|
}),
|
||||||
create.Char('%').Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.Char('%').Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(BinaryOperationId::REMAINDER));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleBinaryOperationId::REMAINDER));
|
||||||
}),
|
}),
|
||||||
create.Char('&').Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.Char('&').Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(BinaryOperationId::BITWISE_AND));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleBinaryOperationId::BITWISE_AND));
|
||||||
}),
|
}),
|
||||||
create.Char('|').Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.Char('|').Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(BinaryOperationId::BITWISE_OR));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleBinaryOperationId::BITWISE_OR));
|
||||||
}),
|
}),
|
||||||
create.MultiChar(static_cast<int>(MenuFileLexing::MultiChar::SHIFT_LEFT)).Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.MultiChar(static_cast<int>(MenuFileLexing::MultiChar::SHIFT_LEFT)).Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(BinaryOperationId::SHIFT_LEFT));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleBinaryOperationId::SHIFT_LEFT));
|
||||||
}),
|
}),
|
||||||
create.MultiChar(static_cast<int>(MenuFileLexing::MultiChar::SHIFT_RIGHT)).Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.MultiChar(static_cast<int>(MenuFileLexing::MultiChar::SHIFT_RIGHT)).Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(BinaryOperationId::SHIFT_RIGHT));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleBinaryOperationId::SHIFT_RIGHT));
|
||||||
}),
|
}),
|
||||||
create.Char('>').Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.Char('>').Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(BinaryOperationId::GREATER_THAN));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleBinaryOperationId::GREATER_THAN));
|
||||||
}),
|
}),
|
||||||
create.MultiChar(static_cast<int>(MenuFileLexing::MultiChar::GREATER_EQUAL)).Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.MultiChar(static_cast<int>(MenuFileLexing::MultiChar::GREATER_EQUAL)).Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(BinaryOperationId::GREATER_EQUAL_THAN));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleBinaryOperationId::GREATER_EQUAL_THAN));
|
||||||
}),
|
}),
|
||||||
create.Char('<').Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.Char('<').Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(BinaryOperationId::LESS_THAN));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleBinaryOperationId::LESS_THAN));
|
||||||
}),
|
}),
|
||||||
create.MultiChar(static_cast<int>(MenuFileLexing::MultiChar::LESS_EQUAL)).Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.MultiChar(static_cast<int>(MenuFileLexing::MultiChar::LESS_EQUAL)).Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(BinaryOperationId::LESS_EQUAL_THAN));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleBinaryOperationId::LESS_EQUAL_THAN));
|
||||||
}),
|
}),
|
||||||
create.MultiChar(static_cast<int>(MenuFileLexing::MultiChar::EQUALS)).Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.MultiChar(static_cast<int>(MenuFileLexing::MultiChar::EQUALS)).Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(BinaryOperationId::EQUALS));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleBinaryOperationId::EQUALS));
|
||||||
}),
|
}),
|
||||||
create.MultiChar(static_cast<int>(MenuFileLexing::MultiChar::NOT_EQUAL)).Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.MultiChar(static_cast<int>(MenuFileLexing::MultiChar::NOT_EQUAL)).Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(BinaryOperationId::NOT_EQUAL));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleBinaryOperationId::NOT_EQUAL));
|
||||||
}),
|
}),
|
||||||
create.MultiChar(static_cast<int>(MenuFileLexing::MultiChar::LOGICAL_AND)).Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.MultiChar(static_cast<int>(MenuFileLexing::MultiChar::LOGICAL_AND)).Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(BinaryOperationId::AND));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleBinaryOperationId::AND));
|
||||||
}),
|
}),
|
||||||
create.MultiChar(static_cast<int>(MenuFileLexing::MultiChar::LOGICAL_OR)).Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.MultiChar(static_cast<int>(MenuFileLexing::MultiChar::LOGICAL_OR)).Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(BinaryOperationId::OR));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleBinaryOperationId::OR));
|
||||||
}),
|
}),
|
||||||
}).Capture(CAPTURE_BINARY_OPERATION_TYPE);
|
}).Capture(CAPTURE_BINARY_OPERATION_TYPE);
|
||||||
}
|
}
|
||||||
@ -270,15 +270,15 @@ std::unique_ptr<MenuCommonMatchers::matcher_t> MenuCommonMatchers::ParseUnaryOpe
|
|||||||
return create.Or({
|
return create.Or({
|
||||||
create.Char('!').Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.Char('!').Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(UnaryOperationId::NOT));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleUnaryOperationId::NOT));
|
||||||
}),
|
}),
|
||||||
create.Char('~').Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.Char('~').Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(UnaryOperationId::BITWISE_NOT));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleUnaryOperationId::BITWISE_NOT));
|
||||||
}),
|
}),
|
||||||
create.Char('-').Transform([](const MenuMatcherFactory::token_list_t& values)
|
create.Char('-').Transform([](const MenuMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(UnaryOperationId::NEGATIVE));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(SimpleUnaryOperationId::NEGATIVE));
|
||||||
}),
|
}),
|
||||||
}).Tag(TAG_EXPRESSION_UNARY_OPERATION).Capture(CAPTURE_UNARY_OPERATION_TYPE);
|
}).Tag(TAG_EXPRESSION_UNARY_OPERATION).Capture(CAPTURE_UNARY_OPERATION_TYPE);
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "Parsing/Matcher/AbstractMatcher.h"
|
#include "Parsing/Matcher/AbstractMatcher.h"
|
||||||
#include "Parsing/Matcher/MatcherLabel.h"
|
#include "Parsing/Matcher/MatcherLabel.h"
|
||||||
#include "Parsing/Menu/MenuFileParser.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/Sequence/SequenceResult.h"
|
||||||
#include "Parsing/Simple/SimpleParserValue.h"
|
#include "Parsing/Simple/SimpleParserValue.h"
|
||||||
|
|
||||||
@ -26,12 +26,12 @@ namespace menu
|
|||||||
static std::unique_ptr<matcher_t> ParseFunctionCall(const supplier_t* labelSupplier);
|
static std::unique_ptr<matcher_t> ParseFunctionCall(const supplier_t* labelSupplier);
|
||||||
static std::unique_ptr<matcher_t> ParseUnaryOperationType(const supplier_t* labelSupplier);
|
static std::unique_ptr<matcher_t> ParseUnaryOperationType(const supplier_t* labelSupplier);
|
||||||
|
|
||||||
static std::unique_ptr<ICommonExpression> ProcessExpressionInParenthesis(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result);
|
static std::unique_ptr<ISimpleExpression> ProcessExpressionInParenthesis(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result);
|
||||||
static std::unique_ptr<ICommonExpression> ProcessOperand(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result);
|
static std::unique_ptr<ISimpleExpression> ProcessOperand(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result);
|
||||||
static std::unique_ptr<ICommonExpression> ProcessFunctionCall(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result);
|
static std::unique_ptr<ISimpleExpression> ProcessFunctionCall(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<matcher_t> Expression(const supplier_t* labelSupplier);
|
static std::unique_ptr<matcher_t> Expression(const supplier_t* labelSupplier);
|
||||||
static std::unique_ptr<ICommonExpression> ProcessExpression(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result);
|
static std::unique_ptr<ISimpleExpression> ProcessExpression(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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)
|
switch (value.m_type)
|
||||||
{
|
{
|
||||||
case CommonExpressionValue::Type::DOUBLE:
|
case SimpleExpressionValue::Type::DOUBLE:
|
||||||
state->m_current_script << value.m_double_value;
|
state->m_current_script << value.m_double_value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CommonExpressionValue::Type::INT:
|
case SimpleExpressionValue::Type::INT:
|
||||||
state->m_current_script << value.m_int_value;
|
state->m_current_script << value.m_int_value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CommonExpressionValue::Type::STRING:
|
case SimpleExpressionValue::Type::STRING:
|
||||||
state->m_current_script << *value.m_string_value;
|
state->m_current_script << *value.m_string_value;
|
||||||
break;
|
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)
|
switch (type)
|
||||||
{
|
{
|
||||||
case SetLocalVarType::BOOL:
|
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");
|
throw ParsingException(pos, "Static value must be BOOL");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SetLocalVarType::INT:
|
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");
|
throw ParsingException(pos, "Static value must be INT");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SetLocalVarType::FLOAT:
|
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");
|
throw ParsingException(pos, "Static value must be FLOAT");
|
||||||
break;
|
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<ICommonExpression> expression)
|
static void EmitStaticSetLocalVar(MenuFileParserState* state, const TokenPos& pos, const SetLocalVarType type, const std::string& varName, std::unique_ptr<ISimpleExpression> expression)
|
||||||
{
|
{
|
||||||
state->m_current_script << "\"" << ScriptKeywordForType(type) << "\" \"" << varName << "\" \"";
|
state->m_current_script << "\"" << ScriptKeywordForType(type) << "\" \"" << varName << "\" \"";
|
||||||
const auto staticValue = expression->Evaluate();
|
const auto staticValue = expression->Evaluate();
|
||||||
@ -412,7 +412,7 @@ namespace menu::event_handler_set_scope_sequences
|
|||||||
state->m_current_script << "\" ; ";
|
state->m_current_script << "\" ; ";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EmitDynamicSetLocalVar(const MenuFileParserState* state, const SetLocalVarType type, const std::string& varName, std::unique_ptr<ICommonExpression> expression)
|
static void EmitDynamicSetLocalVar(const MenuFileParserState* state, const SetLocalVarType type, const std::string& varName, std::unique_ptr<ISimpleExpression> expression)
|
||||||
{
|
{
|
||||||
state->m_current_nested_event_handler_set->m_elements.emplace_back(std::make_unique<CommonEventHandlerSetLocalVar>(type, varName, std::move(expression)));
|
state->m_current_nested_event_handler_set->m_elements.emplace_back(std::make_unique<CommonEventHandlerSetLocalVar>(type, varName, std::move(expression)));
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,14 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include "Parsing/Menu/MenuFileParser.h"
|
#include "Parsing/Menu/MenuFileParser.h"
|
||||||
#include "Parsing/Menu/Domain/Expression/ICommonExpression.h"
|
#include "Parsing/Simple/Expression/ISimpleExpression.h"
|
||||||
|
|
||||||
namespace menu
|
namespace menu
|
||||||
{
|
{
|
||||||
class GenericExpressionPropertySequence final : public MenuFileParser::sequence_t
|
class GenericExpressionPropertySequence final : public MenuFileParser::sequence_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using callback_t = std::function<void(MenuFileParserState* state, const TokenPos& pos, std::unique_ptr<ICommonExpression> value)>;
|
using callback_t = std::function<void(MenuFileParserState* state, const TokenPos& pos, std::unique_ptr<ISimpleExpression> value)>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr auto CAPTURE_FIRST_TOKEN = 1;
|
static constexpr auto CAPTURE_FIRST_TOKEN = 1;
|
||||||
|
@ -664,103 +664,103 @@ void ItemScopeSequences::AddSequences(FeatureLevel featureLevel)
|
|||||||
state->m_current_item->m_game_message_window_mode = value;
|
state->m_current_item->m_game_message_window_mode = value;
|
||||||
}));
|
}));
|
||||||
AddSequence(std::make_unique<SequenceDecodeEffect>());
|
AddSequence(std::make_unique<SequenceDecodeEffect>());
|
||||||
AddSequence(GenericExpressionPropertySequence::WithKeywordAndBool("visible", [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywordAndBool("visible", [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_visible_expression = std::move(value);
|
state->m_current_item->m_visible_expression = std::move(value);
|
||||||
}));
|
}));
|
||||||
AddSequence(GenericExpressionPropertySequence::WithKeywordAndBool("disabled", [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywordAndBool("disabled", [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_disabled_expression = std::move(value);
|
state->m_current_item->m_disabled_expression = std::move(value);
|
||||||
}));
|
}));
|
||||||
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "disabled"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "disabled"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_disabled_expression = std::move(value);
|
state->m_current_item->m_disabled_expression = std::move(value);
|
||||||
}));
|
}));
|
||||||
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "text"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "text"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_text_expression = std::move(value);
|
state->m_current_item->m_text_expression = std::move(value);
|
||||||
}));
|
}));
|
||||||
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "material"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "material"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_material_expression = std::move(value);
|
state->m_current_item->m_material_expression = std::move(value);
|
||||||
}));
|
}));
|
||||||
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "material"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "material"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_material_expression = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "X"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_rect_x_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "Y"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_rect_y_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "W"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_rect_w_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "H"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_rect_h_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "forecolor", "R"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_forecolor_expressions.m_r_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "forecolor", "G"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_forecolor_expressions.m_g_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "forecolor", "B"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_forecolor_expressions.m_b_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "forecolor", "A"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_forecolor_expressions.m_a_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "forecolor", "RGB"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_forecolor_expressions.m_rgb_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "glowcolor", "R"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_glowcolor_expressions.m_r_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "glowcolor", "G"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_glowcolor_expressions.m_g_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "glowcolor", "B"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_glowcolor_expressions.m_b_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "glowcolor", "A"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_glowcolor_expressions.m_a_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "glowcolor", "RGB"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_glowcolor_expressions.m_rgb_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "backcolor", "R"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_backcolor_expressions.m_r_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "backcolor", "G"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_backcolor_expressions.m_g_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "backcolor", "B"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_backcolor_expressions.m_b_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "backcolor", "A"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_backcolor_expressions.m_a_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "backcolor", "RGB"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_item->m_backcolor_expressions.m_rgb_exp = std::move(value);
|
state->m_current_item->m_backcolor_expressions.m_rgb_exp = std::move(value);
|
||||||
}));
|
}));
|
||||||
|
@ -323,23 +323,23 @@ void MenuScopeSequences::AddSequences(FeatureLevel featureLevel)
|
|||||||
{
|
{
|
||||||
state->m_current_menu->m_text_only_focus = true;
|
state->m_current_menu->m_text_only_focus = true;
|
||||||
}));
|
}));
|
||||||
AddSequence(GenericExpressionPropertySequence::WithKeywordAndBool("visible", [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywordAndBool("visible", [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_menu->m_visible_expression = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "X"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_menu->m_rect_x_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "Y"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_menu->m_rect_y_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "W"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_menu->m_rect_w_exp = std::move(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<ICommonExpression> value)
|
AddSequence(GenericExpressionPropertySequence::WithKeywords({"exp", "rect", "H"}, [](const MenuFileParserState* state, const TokenPos&, std::unique_ptr<ISimpleExpression> value)
|
||||||
{
|
{
|
||||||
state->m_current_menu->m_rect_h_exp = std::move(value);
|
state->m_current_menu->m_rect_h_exp = std::move(value);
|
||||||
}));
|
}));
|
||||||
|
20
src/Parser/Parsing/Simple/Expression/ISimpleExpression.h
Normal file
20
src/Parser/Parsing/Simple/Expression/ISimpleExpression.h
Normal file
@ -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"
|
@ -0,0 +1,437 @@
|
|||||||
|
#include "SimpleExpressionBinaryOperation.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
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<double>(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<double>(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<double>(operand2.m_int_value));
|
||||||
|
}
|
||||||
|
else if (operand1.m_type == SimpleExpressionValue::Type::INT)
|
||||||
|
{
|
||||||
|
if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE)
|
||||||
|
return SimpleExpressionValue(static_cast<double>(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<double>(operand2.m_int_value));
|
||||||
|
}
|
||||||
|
else if (operand1.m_type == SimpleExpressionValue::Type::INT)
|
||||||
|
{
|
||||||
|
if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE)
|
||||||
|
return SimpleExpressionValue(static_cast<double>(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<double>(operand2.m_int_value));
|
||||||
|
}
|
||||||
|
else if (operand1.m_type == SimpleExpressionValue::Type::INT)
|
||||||
|
{
|
||||||
|
if (operand2.m_type == SimpleExpressionValue::Type::DOUBLE)
|
||||||
|
return SimpleExpressionValue(static_cast<double>(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<double>(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<double>(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<int>(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<ISimpleExpression> operand1,
|
||||||
|
std::unique_ptr<ISimpleExpression> operand2)
|
||||||
|
: m_operation_type(operationType),
|
||||||
|
m_operand1(std::move(operand1)),
|
||||||
|
m_operand2(std::move(operand2))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SimpleExpressionBinaryOperation::Operand1NeedsParenthesis() const
|
||||||
|
{
|
||||||
|
const auto* operation = dynamic_cast<const SimpleExpressionBinaryOperation*>(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<const SimpleExpressionBinaryOperation*>(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());
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#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<SimpleExpressionValue(const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2)>;
|
||||||
|
|
||||||
|
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<int>(SimpleBinaryOperationId::COUNT)];
|
||||||
|
};
|
||||||
|
|
||||||
|
class SimpleExpressionBinaryOperation final : public ISimpleExpression
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const SimpleExpressionBinaryOperationType* m_operation_type;
|
||||||
|
std::unique_ptr<ISimpleExpression> m_operand1;
|
||||||
|
std::unique_ptr<ISimpleExpression> m_operand2;
|
||||||
|
|
||||||
|
SimpleExpressionBinaryOperation(const SimpleExpressionBinaryOperationType* operationType,
|
||||||
|
std::unique_ptr<ISimpleExpression> operand1,
|
||||||
|
std::unique_ptr<ISimpleExpression> operand2);
|
||||||
|
|
||||||
|
_NODISCARD bool Operand1NeedsParenthesis() const;
|
||||||
|
_NODISCARD bool Operand2NeedsParenthesis() const;
|
||||||
|
|
||||||
|
bool IsStatic() override;
|
||||||
|
SimpleExpressionValue Evaluate() override;
|
||||||
|
};
|
@ -0,0 +1,73 @@
|
|||||||
|
#include "SimpleExpressionUnaryOperation.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#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<int>(SimpleUnaryOperationId::COUNT)]
|
||||||
|
{
|
||||||
|
&OPERATION_NOT,
|
||||||
|
&OPERATION_BITWISE_NOT,
|
||||||
|
&OPERATION_NEGATIVE,
|
||||||
|
};
|
||||||
|
|
||||||
|
SimpleExpressionUnaryOperation::SimpleExpressionUnaryOperation(const SimpleExpressionUnaryOperationType* operationType, std::unique_ptr<ISimpleExpression> operand)
|
||||||
|
: m_operation_type(operationType),
|
||||||
|
m_operand(std::move(operand))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SimpleExpressionUnaryOperation::OperandNeedsParenthesis() const
|
||||||
|
{
|
||||||
|
return dynamic_cast<const SimpleExpressionBinaryOperation*>(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());
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "ISimpleExpression.h"
|
||||||
|
#include "SimpleExpressionValue.h"
|
||||||
|
|
||||||
|
enum class SimpleUnaryOperationId
|
||||||
|
{
|
||||||
|
NOT,
|
||||||
|
BITWISE_NOT,
|
||||||
|
NEGATIVE,
|
||||||
|
|
||||||
|
COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
class SimpleExpressionUnaryOperationType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using evaluation_function_t = std::function<SimpleExpressionValue(const SimpleExpressionValue& operand)>;
|
||||||
|
|
||||||
|
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<int>(SimpleUnaryOperationId::COUNT)];
|
||||||
|
};
|
||||||
|
|
||||||
|
class SimpleExpressionUnaryOperation final : public ISimpleExpression
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const SimpleExpressionUnaryOperationType* m_operation_type;
|
||||||
|
std::unique_ptr<ISimpleExpression> m_operand;
|
||||||
|
|
||||||
|
SimpleExpressionUnaryOperation(const SimpleExpressionUnaryOperationType* operationType, std::unique_ptr<ISimpleExpression> operand);
|
||||||
|
|
||||||
|
_NODISCARD bool OperandNeedsParenthesis() const;
|
||||||
|
|
||||||
|
bool IsStatic() override;
|
||||||
|
SimpleExpressionValue Evaluate() override;
|
||||||
|
};
|
@ -1,10 +1,8 @@
|
|||||||
#include "CommonExpressionValue.h"
|
#include "SimpleExpressionValue.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
using namespace menu;
|
SimpleExpressionValue::SimpleExpressionValue(std::string stringValue)
|
||||||
|
|
||||||
CommonExpressionValue::CommonExpressionValue(std::string stringValue)
|
|
||||||
: m_type(Type::STRING),
|
: m_type(Type::STRING),
|
||||||
m_string_value(std::make_shared<std::string>(std::move(stringValue)))
|
m_string_value(std::make_shared<std::string>(std::move(stringValue)))
|
||||||
{
|
{
|
||||||
@ -12,31 +10,31 @@ CommonExpressionValue::CommonExpressionValue(std::string stringValue)
|
|||||||
m_int_value = 0;
|
m_int_value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommonExpressionValue::CommonExpressionValue(const double doubleValue)
|
SimpleExpressionValue::SimpleExpressionValue(const double doubleValue)
|
||||||
: m_type(Type::DOUBLE)
|
: m_type(Type::DOUBLE)
|
||||||
{
|
{
|
||||||
m_int_value = 0;
|
m_int_value = 0;
|
||||||
m_double_value = doubleValue;
|
m_double_value = doubleValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommonExpressionValue::CommonExpressionValue(const int intValue)
|
SimpleExpressionValue::SimpleExpressionValue(const int intValue)
|
||||||
: m_type(Type::INT)
|
: m_type(Type::INT)
|
||||||
{
|
{
|
||||||
m_double_value = 0;
|
m_double_value = 0;
|
||||||
m_int_value = intValue;
|
m_int_value = intValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommonExpressionValue::IsStatic()
|
bool SimpleExpressionValue::IsStatic()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommonExpressionValue CommonExpressionValue::Evaluate()
|
SimpleExpressionValue SimpleExpressionValue::Evaluate()
|
||||||
{
|
{
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommonExpressionValue::IsTruthy() const
|
bool SimpleExpressionValue::IsTruthy() const
|
||||||
{
|
{
|
||||||
if (m_type == Type::DOUBLE)
|
if (m_type == Type::DOUBLE)
|
||||||
return std::fpclassify(m_double_value) != FP_ZERO;
|
return std::fpclassify(m_double_value) != FP_ZERO;
|
35
src/Parser/Parsing/Simple/Expression/SimpleExpressionValue.h
Normal file
35
src/Parser/Parsing/Simple/Expression/SimpleExpressionValue.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#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<std::string> 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;
|
||||||
|
};
|
@ -986,7 +986,7 @@ namespace test::parsing::menu::sequence::event_handler_set
|
|||||||
REQUIRE(conditionElement->m_condition != nullptr);
|
REQUIRE(conditionElement->m_condition != nullptr);
|
||||||
REQUIRE(conditionElement->m_condition->IsStatic());
|
REQUIRE(conditionElement->m_condition->IsStatic());
|
||||||
const auto staticValue = conditionElement->m_condition->Evaluate();
|
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(staticValue.m_int_value == 1337);
|
||||||
|
|
||||||
REQUIRE(conditionElement->m_condition_elements);
|
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 != nullptr);
|
||||||
REQUIRE(conditionElement->m_condition->IsStatic());
|
REQUIRE(conditionElement->m_condition->IsStatic());
|
||||||
const auto staticValue = conditionElement->m_condition->Evaluate();
|
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(staticValue.m_int_value == 1337);
|
||||||
|
|
||||||
REQUIRE(conditionElement->m_condition_elements);
|
REQUIRE(conditionElement->m_condition_elements);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user