mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-06-11 15:28:11 -05:00
Move common expression classes to simple parsing setup
This commit is contained in:
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;
|
||||
};
|
@ -0,0 +1,46 @@
|
||||
#include "SimpleExpressionValue.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
SimpleExpressionValue::SimpleExpressionValue(std::string stringValue)
|
||||
: m_type(Type::STRING),
|
||||
m_string_value(std::make_shared<std::string>(std::move(stringValue)))
|
||||
{
|
||||
m_double_value = 0;
|
||||
m_int_value = 0;
|
||||
}
|
||||
|
||||
SimpleExpressionValue::SimpleExpressionValue(const double doubleValue)
|
||||
: m_type(Type::DOUBLE)
|
||||
{
|
||||
m_int_value = 0;
|
||||
m_double_value = doubleValue;
|
||||
}
|
||||
|
||||
SimpleExpressionValue::SimpleExpressionValue(const int intValue)
|
||||
: m_type(Type::INT)
|
||||
{
|
||||
m_double_value = 0;
|
||||
m_int_value = intValue;
|
||||
}
|
||||
|
||||
bool SimpleExpressionValue::IsStatic()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
SimpleExpressionValue SimpleExpressionValue::Evaluate()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool SimpleExpressionValue::IsTruthy() const
|
||||
{
|
||||
if (m_type == Type::DOUBLE)
|
||||
return std::fpclassify(m_double_value) != FP_ZERO;
|
||||
if (m_type == Type::INT)
|
||||
return m_int_value != 0;
|
||||
if (m_type == Type::STRING)
|
||||
return m_string_value && !m_string_value->empty();
|
||||
return false;
|
||||
}
|
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;
|
||||
};
|
Reference in New Issue
Block a user