mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 08:05:45 +00:00
Add conditional operator to simple expressions
This commit is contained in:
parent
5b087e0d31
commit
2a4768e5b0
@ -12,7 +12,7 @@ static constexpr int CAPTURE_FUNCTION_NAME = SimpleExpressionMatchers::CAPTURE_O
|
|||||||
|
|
||||||
|
|
||||||
MenuExpressionMatchers::MenuExpressionMatchers()
|
MenuExpressionMatchers::MenuExpressionMatchers()
|
||||||
: SimpleExpressionMatchers(true, true, true, true)
|
: SimpleExpressionMatchers(true, true, true, true, true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ DefinesIfExpressionMatchers::DefinesIfExpressionMatchers()
|
|||||||
}
|
}
|
||||||
|
|
||||||
DefinesIfExpressionMatchers::DefinesIfExpressionMatchers(const DefinesIfDirectiveParsingState* state)
|
DefinesIfExpressionMatchers::DefinesIfExpressionMatchers(const DefinesIfDirectiveParsingState* state)
|
||||||
: SimpleExpressionMatchers(false, false, true, true),
|
: SimpleExpressionMatchers(false, false, true, true, false),
|
||||||
m_state(state)
|
m_state(state)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
#include "SimpleExpressionConditionalOperator.h"
|
||||||
|
|
||||||
|
SimpleExpressionConditionalOperator::SimpleExpressionConditionalOperator()
|
||||||
|
= default;
|
||||||
|
|
||||||
|
SimpleExpressionConditionalOperator::SimpleExpressionConditionalOperator(std::unique_ptr<ISimpleExpression> condition, std::unique_ptr<ISimpleExpression> trueExpression,
|
||||||
|
std::unique_ptr<ISimpleExpression> falseExpression)
|
||||||
|
: m_condition(std::move(condition)),
|
||||||
|
m_true_value(std::move(trueExpression)),
|
||||||
|
m_false_value(std::move(falseExpression))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SimpleExpressionConditionalOperator::IsStatic()
|
||||||
|
{
|
||||||
|
return m_condition->IsStatic() && m_true_value->IsStatic() && m_false_value->IsStatic();
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleExpressionValue SimpleExpressionConditionalOperator::Evaluate()
|
||||||
|
{
|
||||||
|
return m_condition->Evaluate().IsTruthy() ? m_true_value->Evaluate() : m_false_value->Evaluate();
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "ISimpleExpression.h"
|
||||||
|
|
||||||
|
class SimpleExpressionConditionalOperator final : public ISimpleExpression
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::unique_ptr<ISimpleExpression> m_condition;
|
||||||
|
std::unique_ptr<ISimpleExpression> m_true_value;
|
||||||
|
std::unique_ptr<ISimpleExpression> m_false_value;
|
||||||
|
|
||||||
|
bool IsStatic() override;
|
||||||
|
SimpleExpressionValue Evaluate() override;
|
||||||
|
|
||||||
|
SimpleExpressionConditionalOperator();
|
||||||
|
SimpleExpressionConditionalOperator(std::unique_ptr<ISimpleExpression> condition, std::unique_ptr<ISimpleExpression> trueExpression, std::unique_ptr<ISimpleExpression> falseExpression);
|
||||||
|
};
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
|
#include "SimpleExpressionConditionalOperator.h"
|
||||||
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
|
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
|
||||||
#include "Parsing/Simple/Expression/SimpleExpressionBinaryOperation.h"
|
#include "Parsing/Simple/Expression/SimpleExpressionBinaryOperation.h"
|
||||||
#include "Parsing/Simple/Expression/SimpleExpressionUnaryOperation.h"
|
#include "Parsing/Simple/Expression/SimpleExpressionUnaryOperation.h"
|
||||||
@ -14,21 +15,26 @@ static constexpr int TAG_PARENTHESIS_END = SimpleExpressionMatchers::TAG_OFFSET_
|
|||||||
static constexpr int TAG_BINARY_OPERATION = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 6;
|
static constexpr int TAG_BINARY_OPERATION = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 6;
|
||||||
static constexpr int TAG_OPERAND_EXT = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 7;
|
static constexpr int TAG_OPERAND_EXT = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 7;
|
||||||
static constexpr int TAG_OPERAND_EXT_END = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 8;
|
static constexpr int TAG_OPERAND_EXT_END = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 8;
|
||||||
|
static constexpr int TAG_CONDITIONAL_OPERATOR = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 9;
|
||||||
|
static constexpr int TAG_CONDITIONAL_OPERATOR_SEPARATOR = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 10;
|
||||||
|
static constexpr int TAG_CONDITIONAL_OPERATOR_END = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 11;
|
||||||
|
|
||||||
static constexpr int CAPTURE_OPERAND = SimpleExpressionMatchers::CAPTURE_OFFSET_EXPRESSION + 1;
|
static constexpr int CAPTURE_OPERAND = SimpleExpressionMatchers::CAPTURE_OFFSET_EXPRESSION + 1;
|
||||||
static constexpr int CAPTURE_UNARY_OPERATION_TYPE = SimpleExpressionMatchers::CAPTURE_OFFSET_EXPRESSION + 2;
|
static constexpr int CAPTURE_UNARY_OPERATION_TYPE = SimpleExpressionMatchers::CAPTURE_OFFSET_EXPRESSION + 2;
|
||||||
static constexpr int CAPTURE_BINARY_OPERATION_TYPE = SimpleExpressionMatchers::CAPTURE_OFFSET_EXPRESSION + 3;
|
static constexpr int CAPTURE_BINARY_OPERATION_TYPE = SimpleExpressionMatchers::CAPTURE_OFFSET_EXPRESSION + 3;
|
||||||
|
|
||||||
SimpleExpressionMatchers::SimpleExpressionMatchers()
|
SimpleExpressionMatchers::SimpleExpressionMatchers()
|
||||||
: SimpleExpressionMatchers(true, true, true, true)
|
: SimpleExpressionMatchers(true, true, true, true, false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleExpressionMatchers::SimpleExpressionMatchers(const bool enableStringOperands, const bool enableIdentifierOperands, const bool enableFloatingPointOperands, const bool enableIntOperands)
|
SimpleExpressionMatchers::SimpleExpressionMatchers(const bool enableStringOperands, const bool enableIdentifierOperands, const bool enableFloatingPointOperands, const bool enableIntOperands,
|
||||||
|
const bool enableConditionalOperator)
|
||||||
: m_enable_string_operands(enableStringOperands),
|
: m_enable_string_operands(enableStringOperands),
|
||||||
m_enable_identifier_operands(enableIdentifierOperands),
|
m_enable_identifier_operands(enableIdentifierOperands),
|
||||||
m_enable_floating_point_operands(enableFloatingPointOperands),
|
m_enable_floating_point_operands(enableFloatingPointOperands),
|
||||||
m_enable_int_operands(enableIntOperands)
|
m_enable_int_operands(enableIntOperands),
|
||||||
|
m_enable_conditional_operator(enableConditionalOperator)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,6 +82,21 @@ std::unique_ptr<ISimpleExpression> SimpleExpressionMatchers::ProcessExpressionIn
|
|||||||
return processedEvaluation;
|
return processedEvaluation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ISimpleExpression> SimpleExpressionMatchers::ProcessConditionalOperation(std::unique_ptr<ISimpleExpression> condition, SequenceResult<SimpleParserValue>& result) const
|
||||||
|
{
|
||||||
|
auto trueExpression = ProcessExpression(result);
|
||||||
|
|
||||||
|
if (result.PeekAndRemoveIfTag(TAG_CONDITIONAL_OPERATOR_SEPARATOR) != TAG_CONDITIONAL_OPERATOR_SEPARATOR)
|
||||||
|
throw ParsingException(TokenPos(), "Expected conditional separator tag @ ProcessConditionalOperation");
|
||||||
|
|
||||||
|
auto falseExpression = ProcessExpression(result);
|
||||||
|
|
||||||
|
if (result.PeekAndRemoveIfTag(TAG_CONDITIONAL_OPERATOR_END) != TAG_CONDITIONAL_OPERATOR_END)
|
||||||
|
throw ParsingException(TokenPos(), "Expected conditional end tag @ ProcessConditionalOperation");
|
||||||
|
|
||||||
|
return std::make_unique<SimpleExpressionConditionalOperator>(std::move(condition), std::move(trueExpression), std::move(falseExpression));
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<ISimpleExpression> SimpleExpressionMatchers::ProcessOperand(SequenceResult<SimpleParserValue>& result) const
|
std::unique_ptr<ISimpleExpression> SimpleExpressionMatchers::ProcessOperand(SequenceResult<SimpleParserValue>& result) const
|
||||||
{
|
{
|
||||||
const auto& operandToken = result.NextCapture(CAPTURE_OPERAND);
|
const auto& operandToken = result.NextCapture(CAPTURE_OPERAND);
|
||||||
@ -149,6 +170,12 @@ std::unique_ptr<ISimpleExpression> SimpleExpressionMatchers::ProcessExpression(S
|
|||||||
std::move(firstStatementPart));
|
std::move(firstStatementPart));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result.PeekAndRemoveIfTag(TAG_CONDITIONAL_OPERATOR) == TAG_CONDITIONAL_OPERATOR)
|
||||||
|
{
|
||||||
|
operands.emplace_back(ProcessConditionalOperation(std::move(firstStatementPart), result));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
operands.emplace_back(std::move(firstStatementPart));
|
operands.emplace_back(std::move(firstStatementPart));
|
||||||
|
|
||||||
if (result.PeekAndRemoveIfTag(TAG_BINARY_OPERATION) == TAG_BINARY_OPERATION)
|
if (result.PeekAndRemoveIfTag(TAG_BINARY_OPERATION) == TAG_BINARY_OPERATION)
|
||||||
@ -270,25 +297,41 @@ std::unique_ptr<SimpleExpressionMatchers::matcher_t> SimpleExpressionMatchers::P
|
|||||||
{
|
{
|
||||||
unaryOperationsMatchers.emplace_back(
|
unaryOperationsMatchers.emplace_back(
|
||||||
create.MultiChar(MULTI_TOKEN_OFFSET_UNARY + static_cast<int>(enabledUnaryOperation->m_id))
|
create.MultiChar(MULTI_TOKEN_OFFSET_UNARY + static_cast<int>(enabledUnaryOperation->m_id))
|
||||||
.Transform([enabledUnaryOperation](const SimpleMatcherFactory::token_list_t& values)
|
.Transform([enabledUnaryOperation](const SimpleMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(enabledUnaryOperation->m_id));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(enabledUnaryOperation->m_id));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
else if (!enabledUnaryOperation->m_syntax.empty())
|
else if (!enabledUnaryOperation->m_syntax.empty())
|
||||||
{
|
{
|
||||||
unaryOperationsMatchers.emplace_back(
|
unaryOperationsMatchers.emplace_back(
|
||||||
create.Char(enabledUnaryOperation->m_syntax[0])
|
create.Char(enabledUnaryOperation->m_syntax[0])
|
||||||
.Transform([enabledUnaryOperation](const SimpleMatcherFactory::token_list_t& values)
|
.Transform([enabledUnaryOperation](const SimpleMatcherFactory::token_list_t& values)
|
||||||
{
|
{
|
||||||
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(enabledUnaryOperation->m_id));
|
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(enabledUnaryOperation->m_id));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return create.Or(std::move(unaryOperationsMatchers)).Tag(TAG_UNARY_OPERATION).Capture(CAPTURE_UNARY_OPERATION_TYPE);
|
return create.Or(std::move(unaryOperationsMatchers)).Tag(TAG_UNARY_OPERATION).Capture(CAPTURE_UNARY_OPERATION_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<SimpleExpressionMatchers::matcher_t> SimpleExpressionMatchers::ParseConditionalOperator(const supplier_t* labelSupplier) const
|
||||||
|
{
|
||||||
|
const SimpleMatcherFactory create(labelSupplier);
|
||||||
|
|
||||||
|
if (!m_enable_conditional_operator)
|
||||||
|
return create.False();
|
||||||
|
|
||||||
|
return create.And({
|
||||||
|
create.Char('?').Tag(TAG_CONDITIONAL_OPERATOR),
|
||||||
|
create.Label(LABEL_EXPRESSION),
|
||||||
|
create.Char(':').Tag(TAG_CONDITIONAL_OPERATOR_SEPARATOR),
|
||||||
|
create.Label(LABEL_EXPRESSION),
|
||||||
|
create.True().Tag(TAG_CONDITIONAL_OPERATOR_END)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<SimpleExpressionMatchers::matcher_t> SimpleExpressionMatchers::Expression(const supplier_t* labelSupplier) const
|
std::unique_ptr<SimpleExpressionMatchers::matcher_t> SimpleExpressionMatchers::Expression(const supplier_t* labelSupplier) const
|
||||||
{
|
{
|
||||||
const SimpleMatcherFactory create(labelSupplier);
|
const SimpleMatcherFactory create(labelSupplier);
|
||||||
@ -308,9 +351,12 @@ std::unique_ptr<SimpleExpressionMatchers::matcher_t> SimpleExpressionMatchers::E
|
|||||||
}),
|
}),
|
||||||
ParseOperand(labelSupplier)
|
ParseOperand(labelSupplier)
|
||||||
}),
|
}),
|
||||||
create.Optional(create.And({
|
create.Optional(create.Or({
|
||||||
ParseBinaryOperationType(labelSupplier),
|
ParseConditionalOperator(labelSupplier),
|
||||||
create.Label(LABEL_EXPRESSION)
|
create.And({
|
||||||
}).Tag(TAG_BINARY_OPERATION))
|
ParseBinaryOperationType(labelSupplier),
|
||||||
|
create.Label(LABEL_EXPRESSION)
|
||||||
|
}).Tag(TAG_BINARY_OPERATION)
|
||||||
|
}))
|
||||||
}).Tag(TAG_EXPRESSION);
|
}).Tag(TAG_EXPRESSION);
|
||||||
}
|
}
|
||||||
|
@ -31,10 +31,11 @@ private:
|
|||||||
bool m_enable_identifier_operands;
|
bool m_enable_identifier_operands;
|
||||||
bool m_enable_floating_point_operands;
|
bool m_enable_floating_point_operands;
|
||||||
bool m_enable_int_operands;
|
bool m_enable_int_operands;
|
||||||
|
bool m_enable_conditional_operator;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SimpleExpressionMatchers();
|
SimpleExpressionMatchers();
|
||||||
SimpleExpressionMatchers(bool enableStringOperands, bool enableIdentifierOperands, bool enableFloatingPointOperands, bool enableIntOperands);
|
SimpleExpressionMatchers(bool enableStringOperands, bool enableIdentifierOperands, bool enableFloatingPointOperands, bool enableIntOperands, bool enableConditionalOperator);
|
||||||
virtual ~SimpleExpressionMatchers();
|
virtual ~SimpleExpressionMatchers();
|
||||||
SimpleExpressionMatchers(const SimpleExpressionMatchers& other) = default;
|
SimpleExpressionMatchers(const SimpleExpressionMatchers& other) = default;
|
||||||
SimpleExpressionMatchers(SimpleExpressionMatchers&& other) noexcept = default;
|
SimpleExpressionMatchers(SimpleExpressionMatchers&& other) noexcept = default;
|
||||||
@ -52,8 +53,10 @@ private:
|
|||||||
std::unique_ptr<matcher_t> ParseBinaryOperationType(const supplier_t* labelSupplier) const;
|
std::unique_ptr<matcher_t> ParseBinaryOperationType(const supplier_t* labelSupplier) const;
|
||||||
std::unique_ptr<matcher_t> ParseOperand(const supplier_t* labelSupplier) const;
|
std::unique_ptr<matcher_t> ParseOperand(const supplier_t* labelSupplier) const;
|
||||||
std::unique_ptr<matcher_t> ParseUnaryOperationType(const supplier_t* labelSupplier) const;
|
std::unique_ptr<matcher_t> ParseUnaryOperationType(const supplier_t* labelSupplier) const;
|
||||||
|
std::unique_ptr<matcher_t> ParseConditionalOperator(const supplier_t* labelSupplier) const;
|
||||||
|
|
||||||
std::unique_ptr<ISimpleExpression> ProcessExpressionInParenthesis(SequenceResult<SimpleParserValue>& result) const;
|
std::unique_ptr<ISimpleExpression> ProcessExpressionInParenthesis(SequenceResult<SimpleParserValue>& result) const;
|
||||||
|
std::unique_ptr<ISimpleExpression> ProcessConditionalOperation(std::unique_ptr<ISimpleExpression> condition, SequenceResult<SimpleParserValue>& result) const;
|
||||||
std::unique_ptr<ISimpleExpression> ProcessOperand(SequenceResult<SimpleParserValue>& result) const;
|
std::unique_ptr<ISimpleExpression> ProcessOperand(SequenceResult<SimpleParserValue>& result) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -22,7 +22,7 @@ namespace test::parsing::simple::expression
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
SimpleExpressionSequence()
|
SimpleExpressionSequence()
|
||||||
: m_expression_matchers(true, true, true, true)
|
: m_expression_matchers(true, true, true, true, true)
|
||||||
{
|
{
|
||||||
const SimpleMatcherFactory create(this);
|
const SimpleMatcherFactory create(this);
|
||||||
|
|
||||||
@ -494,7 +494,7 @@ namespace test::parsing::simple::expression
|
|||||||
SimpleParserValue::Character(pos, '+'),
|
SimpleParserValue::Character(pos, '+'),
|
||||||
SimpleParserValue::Integer(pos, 220),
|
SimpleParserValue::Integer(pos, 220),
|
||||||
SimpleParserValue::EndOfFile(pos)
|
SimpleParserValue::EndOfFile(pos)
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto result = helper.PerformTest();
|
const auto result = helper.PerformTest();
|
||||||
|
|
||||||
@ -522,7 +522,7 @@ namespace test::parsing::simple::expression
|
|||||||
SimpleParserValue::Character(pos, '*'),
|
SimpleParserValue::Character(pos, '*'),
|
||||||
SimpleParserValue::Integer(pos, 10),
|
SimpleParserValue::Integer(pos, 10),
|
||||||
SimpleParserValue::EndOfFile(pos)
|
SimpleParserValue::EndOfFile(pos)
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto result = helper.PerformTest();
|
const auto result = helper.PerformTest();
|
||||||
|
|
||||||
@ -536,4 +536,206 @@ namespace test::parsing::simple::expression
|
|||||||
REQUIRE(value.m_type == SimpleExpressionValue::Type::INT);
|
REQUIRE(value.m_type == SimpleExpressionValue::Type::INT);
|
||||||
REQUIRE(value.m_int_value == 420);
|
REQUIRE(value.m_int_value == 420);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("SimpleExpressions: Simple conditional operator can be used with true value", "[parsing][simple][expression]")
|
||||||
|
{
|
||||||
|
SimpleExpressionTestsHelper helper;
|
||||||
|
const TokenPos pos;
|
||||||
|
helper.Tokens({
|
||||||
|
SimpleParserValue::Integer(pos, 1),
|
||||||
|
SimpleParserValue::Character(pos, '?'),
|
||||||
|
SimpleParserValue::Integer(pos, 420),
|
||||||
|
SimpleParserValue::Character(pos, ':'),
|
||||||
|
SimpleParserValue::Integer(pos, 1337),
|
||||||
|
SimpleParserValue::EndOfFile(pos)
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto result = helper.PerformTest();
|
||||||
|
|
||||||
|
REQUIRE(result);
|
||||||
|
REQUIRE(helper.m_consumed_token_count == 5);
|
||||||
|
|
||||||
|
const auto& expression = helper.m_state->m_expression;
|
||||||
|
REQUIRE(expression->IsStatic());
|
||||||
|
|
||||||
|
const auto value = expression->Evaluate();
|
||||||
|
REQUIRE(value.m_type == SimpleExpressionValue::Type::INT);
|
||||||
|
REQUIRE(value.m_int_value == 420);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("SimpleExpressions: Simple conditional operator can be used with false value", "[parsing][simple][expression]")
|
||||||
|
{
|
||||||
|
SimpleExpressionTestsHelper helper;
|
||||||
|
const TokenPos pos;
|
||||||
|
helper.Tokens({
|
||||||
|
SimpleParserValue::Integer(pos, 0),
|
||||||
|
SimpleParserValue::Character(pos, '?'),
|
||||||
|
SimpleParserValue::Integer(pos, 420),
|
||||||
|
SimpleParserValue::Character(pos, ':'),
|
||||||
|
SimpleParserValue::Integer(pos, 1337),
|
||||||
|
SimpleParserValue::EndOfFile(pos)
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto result = helper.PerformTest();
|
||||||
|
|
||||||
|
REQUIRE(result);
|
||||||
|
REQUIRE(helper.m_consumed_token_count == 5);
|
||||||
|
|
||||||
|
const auto& expression = helper.m_state->m_expression;
|
||||||
|
REQUIRE(expression->IsStatic());
|
||||||
|
|
||||||
|
const auto value = expression->Evaluate();
|
||||||
|
REQUIRE(value.m_type == SimpleExpressionValue::Type::INT);
|
||||||
|
REQUIRE(value.m_int_value == 1337);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("SimpleExpressions: Simple conditional operator can be used within parenthesis with true value", "[parsing][simple][expression]")
|
||||||
|
{
|
||||||
|
SimpleExpressionTestsHelper helper;
|
||||||
|
const TokenPos pos;
|
||||||
|
helper.Tokens({
|
||||||
|
SimpleParserValue::Character(pos, '('),
|
||||||
|
SimpleParserValue::Integer(pos, 1),
|
||||||
|
SimpleParserValue::Character(pos, '?'),
|
||||||
|
SimpleParserValue::Integer(pos, 420),
|
||||||
|
SimpleParserValue::Character(pos, ':'),
|
||||||
|
SimpleParserValue::Integer(pos, 1337),
|
||||||
|
SimpleParserValue::Character(pos, ')'),
|
||||||
|
SimpleParserValue::Character(pos, '+'),
|
||||||
|
SimpleParserValue::Integer(pos, 1),
|
||||||
|
SimpleParserValue::EndOfFile(pos)
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto result = helper.PerformTest();
|
||||||
|
|
||||||
|
REQUIRE(result);
|
||||||
|
REQUIRE(helper.m_consumed_token_count == 9);
|
||||||
|
|
||||||
|
const auto& expression = helper.m_state->m_expression;
|
||||||
|
REQUIRE(expression->IsStatic());
|
||||||
|
|
||||||
|
const auto value = expression->Evaluate();
|
||||||
|
REQUIRE(value.m_type == SimpleExpressionValue::Type::INT);
|
||||||
|
REQUIRE(value.m_int_value == 421);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("SimpleExpressions: Simple conditional operator can be used within parenthesis with false value", "[parsing][simple][expression]")
|
||||||
|
{
|
||||||
|
SimpleExpressionTestsHelper helper;
|
||||||
|
const TokenPos pos;
|
||||||
|
helper.Tokens({
|
||||||
|
SimpleParserValue::Character(pos, '('),
|
||||||
|
SimpleParserValue::Integer(pos, 0),
|
||||||
|
SimpleParserValue::Character(pos, '?'),
|
||||||
|
SimpleParserValue::Integer(pos, 420),
|
||||||
|
SimpleParserValue::Character(pos, ':'),
|
||||||
|
SimpleParserValue::Integer(pos, 1337),
|
||||||
|
SimpleParserValue::Character(pos, ')'),
|
||||||
|
SimpleParserValue::Character(pos, '+'),
|
||||||
|
SimpleParserValue::Integer(pos, 1),
|
||||||
|
SimpleParserValue::EndOfFile(pos)
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto result = helper.PerformTest();
|
||||||
|
|
||||||
|
REQUIRE(result);
|
||||||
|
REQUIRE(helper.m_consumed_token_count == 9);
|
||||||
|
|
||||||
|
const auto& expression = helper.m_state->m_expression;
|
||||||
|
REQUIRE(expression->IsStatic());
|
||||||
|
|
||||||
|
const auto value = expression->Evaluate();
|
||||||
|
REQUIRE(value.m_type == SimpleExpressionValue::Type::INT);
|
||||||
|
REQUIRE(value.m_int_value == 1338);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("SimpleExpressions: Simple conditional operator can have an expression as condition", "[parsing][simple][expression]")
|
||||||
|
{
|
||||||
|
SimpleExpressionTestsHelper helper;
|
||||||
|
const TokenPos pos;
|
||||||
|
helper.Tokens({
|
||||||
|
SimpleParserValue::Character(pos, '('),
|
||||||
|
SimpleParserValue::Integer(pos, -1),
|
||||||
|
SimpleParserValue::Character(pos, '+'),
|
||||||
|
SimpleParserValue::Integer(pos, 2),
|
||||||
|
SimpleParserValue::Character(pos, ')'),
|
||||||
|
SimpleParserValue::Character(pos, '?'),
|
||||||
|
SimpleParserValue::Integer(pos, 420),
|
||||||
|
SimpleParserValue::Character(pos, ':'),
|
||||||
|
SimpleParserValue::Integer(pos, 1337),
|
||||||
|
SimpleParserValue::EndOfFile(pos)
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto result = helper.PerformTest();
|
||||||
|
|
||||||
|
REQUIRE(result);
|
||||||
|
REQUIRE(helper.m_consumed_token_count == 9);
|
||||||
|
|
||||||
|
const auto& expression = helper.m_state->m_expression;
|
||||||
|
REQUIRE(expression->IsStatic());
|
||||||
|
|
||||||
|
const auto value = expression->Evaluate();
|
||||||
|
REQUIRE(value.m_type == SimpleExpressionValue::Type::INT);
|
||||||
|
REQUIRE(value.m_int_value == 420);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("SimpleExpressions: Simple conditional operator can have an expression as true value", "[parsing][simple][expression]")
|
||||||
|
{
|
||||||
|
SimpleExpressionTestsHelper helper;
|
||||||
|
const TokenPos pos;
|
||||||
|
helper.Tokens({
|
||||||
|
SimpleParserValue::Integer(pos, 1),
|
||||||
|
SimpleParserValue::Character(pos, '?'),
|
||||||
|
SimpleParserValue::Character(pos, '('),
|
||||||
|
SimpleParserValue::Integer(pos, 210),
|
||||||
|
SimpleParserValue::Character(pos, '*'),
|
||||||
|
SimpleParserValue::Integer(pos, 2),
|
||||||
|
SimpleParserValue::Character(pos, ')'),
|
||||||
|
SimpleParserValue::Character(pos, ':'),
|
||||||
|
SimpleParserValue::Integer(pos, 1337),
|
||||||
|
SimpleParserValue::EndOfFile(pos)
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto result = helper.PerformTest();
|
||||||
|
|
||||||
|
REQUIRE(result);
|
||||||
|
REQUIRE(helper.m_consumed_token_count == 9);
|
||||||
|
|
||||||
|
const auto& expression = helper.m_state->m_expression;
|
||||||
|
REQUIRE(expression->IsStatic());
|
||||||
|
|
||||||
|
const auto value = expression->Evaluate();
|
||||||
|
REQUIRE(value.m_type == SimpleExpressionValue::Type::INT);
|
||||||
|
REQUIRE(value.m_int_value == 420);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("SimpleExpressions: Simple conditional operator can have an expression as false value", "[parsing][simple][expression]")
|
||||||
|
{
|
||||||
|
SimpleExpressionTestsHelper helper;
|
||||||
|
const TokenPos pos;
|
||||||
|
helper.Tokens({
|
||||||
|
SimpleParserValue::Integer(pos, 0),
|
||||||
|
SimpleParserValue::Character(pos, '?'),
|
||||||
|
SimpleParserValue::Integer(pos, 420),
|
||||||
|
SimpleParserValue::Character(pos, ':'),
|
||||||
|
SimpleParserValue::Character(pos, '('),
|
||||||
|
SimpleParserValue::Integer(pos, 1336),
|
||||||
|
SimpleParserValue::Character(pos, '+'),
|
||||||
|
SimpleParserValue::Integer(pos, 1),
|
||||||
|
SimpleParserValue::Character(pos, ')'),
|
||||||
|
SimpleParserValue::EndOfFile(pos)
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto result = helper.PerformTest();
|
||||||
|
|
||||||
|
REQUIRE(result);
|
||||||
|
REQUIRE(helper.m_consumed_token_count == 9);
|
||||||
|
|
||||||
|
const auto& expression = helper.m_state->m_expression;
|
||||||
|
REQUIRE(expression->IsStatic());
|
||||||
|
|
||||||
|
const auto value = expression->Evaluate();
|
||||||
|
REQUIRE(value.m_type == SimpleExpressionValue::Type::INT);
|
||||||
|
REQUIRE(value.m_int_value == 1337);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user