diff --git a/src/language/ASTNodeAffectationExpressionBuilder.cpp b/src/language/ASTNodeAffectationExpressionBuilder.cpp index 3475e2c00ab64eab3edde8e2b6b8a97d3a08bcb5..2b037d9ed94830e5ab1199f8e722925f3fbf4027 100644 --- a/src/language/ASTNodeAffectationExpressionBuilder.cpp +++ b/src/language/ASTNodeAffectationExpressionBuilder.cpp @@ -1,6 +1,8 @@ #include <ASTNodeAffectationExpressionBuilder.hpp> #include <PEGGrammar.hpp> +#include <ASTNodeNaturalConversionChecker.hpp> + #include <node_processor/AffectationProcessor.hpp> ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode& n) @@ -9,6 +11,7 @@ ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode auto set_affectation_processor_for_data = [&](const auto& value, const ASTNodeDataType& data_type) { using OperatorT = std::decay_t<decltype(operator_v)>; using ValueT = std::decay_t<decltype(value)>; + switch (data_type) { case ASTNodeDataType::bool_t: { n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, bool>>(n); @@ -70,6 +73,9 @@ ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode auto set_affectation_processor_for_value = [&](const ASTNodeDataType& value_type) { const ASTNodeDataType data_type = n.children[1]->m_data_type; + + ASTNodeNaturalConversionChecker{n, data_type, value_type}; + switch (value_type) { case ASTNodeDataType::bool_t: { set_affectation_processor_for_data(bool{}, data_type); diff --git a/src/language/ASTNodeDataType.cpp b/src/language/ASTNodeDataType.cpp index bd935e1fcaff79be6b648da5c452441e8a7a026d..b1e9a64d738ee819cd476f4a45cad2238cafa742 100644 --- a/src/language/ASTNodeDataType.cpp +++ b/src/language/ASTNodeDataType.cpp @@ -54,3 +54,24 @@ dataTypePromotion(const ASTNodeDataType& data_type_1, const ASTNodeDataType& dat return ASTNodeDataType::undefined_t; } } + +bool +isNaturalConversion(const ASTNodeDataType& data_type, const ASTNodeDataType& target_data_type) +{ + if (target_data_type == data_type) { + return true; + } else if (target_data_type == ASTNodeDataType::bool_t) { + return false; + } else if (target_data_type == ASTNodeDataType::unsigned_int_t) { + return ((data_type == ASTNodeDataType::int_t) or (data_type == ASTNodeDataType::bool_t)); + } else if (target_data_type == ASTNodeDataType::int_t) { + return ((data_type == ASTNodeDataType::unsigned_int_t) or (data_type == ASTNodeDataType::bool_t)); + } else if (target_data_type == ASTNodeDataType::double_t) { + return ((data_type == ASTNodeDataType::unsigned_int_t) or (data_type == ASTNodeDataType::int_t) or + (data_type == ASTNodeDataType::bool_t)); + } else if (target_data_type == ASTNodeDataType::string_t) { + return ((data_type == ASTNodeDataType::double_t) or (data_type == ASTNodeDataType::unsigned_int_t) or + (data_type == ASTNodeDataType::int_t) or (data_type == ASTNodeDataType::bool_t)); + } + return false; +} diff --git a/src/language/ASTNodeDataType.hpp b/src/language/ASTNodeDataType.hpp index 4bdfd707541f30672e0932e58e71e3bc7c9f5c78..5b0b87071e6517320f459cd83ee8910276a84301 100644 --- a/src/language/ASTNodeDataType.hpp +++ b/src/language/ASTNodeDataType.hpp @@ -4,6 +4,8 @@ #include <limits> #include <string> +class ASTNode; + enum class ASTNodeDataType : int32_t { undefined_t = -1, @@ -22,6 +24,8 @@ std::string dataTypeName(const ASTNodeDataType& data_type); ASTNodeDataType dataTypePromotion(const ASTNodeDataType& data_type_1, const ASTNodeDataType& data_type_2); +bool isNaturalConversion(const ASTNodeDataType& data_type, const ASTNodeDataType& target_data_type); + // Traits ast_node_data_type_from_pod template <typename T> diff --git a/src/language/ASTNodeNaturalConversionChecker.cpp b/src/language/ASTNodeNaturalConversionChecker.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d625d639bfe607d3b6aa0ff4a597361ddc7d6e3b --- /dev/null +++ b/src/language/ASTNodeNaturalConversionChecker.cpp @@ -0,0 +1,13 @@ +#include <ASTNodeNaturalConversionChecker.hpp> + +ASTNodeNaturalConversionChecker::ASTNodeNaturalConversionChecker(const ASTNode& node, + const ASTNodeDataType& data_type, + const ASTNodeDataType& target_data_type) +{ + if (not isNaturalConversion(data_type, target_data_type)) { + std::ostringstream error_message; + error_message << "invalid implicit conversion: " << dataTypeName(data_type) << " -> " + << dataTypeName(target_data_type); + throw parse_error(error_message.str(), node.begin()); + } +} diff --git a/src/language/ASTNodeNaturalConversionChecker.hpp b/src/language/ASTNodeNaturalConversionChecker.hpp new file mode 100644 index 0000000000000000000000000000000000000000..fb2391895148780ff8b0b9bc7a7af6e269b66744 --- /dev/null +++ b/src/language/ASTNodeNaturalConversionChecker.hpp @@ -0,0 +1,15 @@ +#ifndef AST_NODE_NATURAL_CONVERSION_CHECKER_HPP +#define AST_NODE_NATURAL_CONVERSION_CHECKER_HPP + +#include <ASTNode.hpp> +#include <ASTNodeDataType.hpp> + +class ASTNodeNaturalConversionChecker +{ + public: + ASTNodeNaturalConversionChecker(const ASTNode& ast_node, + const ASTNodeDataType& data_type, + const ASTNodeDataType& target_data_type); +}; + +#endif // AST_NODE_NATURAL_CONVERSION_CHECKER_HPP diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt index ee0333d3c48ecfe7233d7eb810959277ba3daaf1..368fa5a9f98c7220da7c3441569722a57ead1868 100644 --- a/src/language/CMakeLists.txt +++ b/src/language/CMakeLists.txt @@ -25,6 +25,7 @@ add_library( ASTNodeIncDecExpressionBuilder.cpp ASTNodeJumpPlacementChecker.cpp ASTNodeListAffectationExpressionBuilder.cpp + ASTNodeNaturalConversionChecker.cpp ASTNodeUnaryOperatorExpressionBuilder.cpp ASTPrinter.cpp ASTSymbolTableBuilder.cpp diff --git a/src/language/node_processor/AffectationProcessor.hpp b/src/language/node_processor/AffectationProcessor.hpp index ef58ef32e01ab36037554ef703254bbfc0c12c16..0c9b751ea2c053c2fa8152613ee98ea40c30e59f 100644 --- a/src/language/node_processor/AffectationProcessor.hpp +++ b/src/language/node_processor/AffectationProcessor.hpp @@ -77,9 +77,11 @@ class AffectationExecutor final : public IAffectationExecutor public: AffectationExecutor(ASTNode& node, DataVariant* lhs) : m_lhs(lhs) { + // LCOV_EXCL_START if constexpr (not _is_defined) { - throw parse_error("invalid operands to affectation expression", std::vector{node.begin()}); + throw parse_error("unexpected error: invalid operands to affectation expression", std::vector{node.begin()}); } + // LCOV_EXCL_STOP } PUGS_INLINE void diff --git a/tests/test_ASTNodeAffectationExpressionBuilder.cpp b/tests/test_ASTNodeAffectationExpressionBuilder.cpp index 4883f0995d4c214f79c9bcbbf24146da3a517404..483a805956061b3a16a16cd7226e1f2d0a45b95a 100644 --- a/tests/test_ASTNodeAffectationExpressionBuilder.cpp +++ b/tests/test_ASTNodeAffectationExpressionBuilder.cpp @@ -64,54 +64,6 @@ B b=true; CHECK_AST(data, result); } - - SECTION("B <- N") - { - std::string_view data = R"( -N n; B b=n; -)"; - - std::string_view result = R"( -(root:ASTNodeListProcessor) - `-(language::eq_op:AffectationProcessor<language::eq_op, bool, unsigned long>) - +-(language::name:b:NameProcessor) - `-(language::name:n:NameProcessor) -)"; - - CHECK_AST(data, result); - } - - SECTION("B <- Z") - { - std::string_view data = R"( -Z z; B b=z; -)"; - - std::string_view result = R"( -(root:ASTNodeListProcessor) - `-(language::eq_op:AffectationProcessor<language::eq_op, bool, long>) - +-(language::name:b:NameProcessor) - `-(language::name:z:NameProcessor) -)"; - - CHECK_AST(data, result); - } - - SECTION("B <- R") - { - std::string_view data = R"( -R r; B b=r; -)"; - - std::string_view result = R"( -(root:ASTNodeListProcessor) - `-(language::eq_op:AffectationProcessor<language::eq_op, bool, double>) - +-(language::name:b:NameProcessor) - `-(language::name:r:NameProcessor) -)"; - - CHECK_AST(data, result); - } } SECTION("unsigned integer affectation") @@ -163,40 +115,6 @@ Z z; N n=z; CHECK_AST(data, result); } - - SECTION("N <- R") - { - std::string_view data = R"( -R r; N n=r; -)"; - - std::string_view result = R"( -(root:ASTNodeListProcessor) - `-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, double>) - +-(language::name:n:NameProcessor) - `-(language::name:r:NameProcessor) -)"; - - CHECK_AST(data, result); - } - - SECTION("N <- string (invalid)") - { - std::string_view data = R"( -N n="foo"; -)"; - - string_input input{data, "test.pgs"}; - auto ast = ASTBuilder::build(input); - - ASTSymbolTableBuilder{*ast}; - ASTNodeDataTypeBuilder{*ast}; - - ASTNodeDeclarationToAffectationConverter{*ast}; - ASTNodeTypeCleaner<language::declaration>{*ast}; - - REQUIRE_THROWS_AS(ASTNodeExpressionBuilder{*ast}, parse_error); - } } SECTION("integer affectation") @@ -248,40 +166,6 @@ Z q; Z z=q; CHECK_AST(data, result); } - - SECTION("B <- R") - { - std::string_view data = R"( -R r; Z z=r; -)"; - - std::string_view result = R"( -(root:ASTNodeListProcessor) - `-(language::eq_op:AffectationProcessor<language::eq_op, long, double>) - +-(language::name:z:NameProcessor) - `-(language::name:r:NameProcessor) -)"; - - CHECK_AST(data, result); - } - - SECTION("Z <- string (invalid)") - { - std::string_view data = R"( -Z z="foo"; -)"; - - string_input input{data, "test.pgs"}; - auto ast = ASTBuilder::build(input); - - ASTSymbolTableBuilder{*ast}; - ASTNodeDataTypeBuilder{*ast}; - - ASTNodeDeclarationToAffectationConverter{*ast}; - ASTNodeTypeCleaner<language::declaration>{*ast}; - - REQUIRE_THROWS_AS(ASTNodeExpressionBuilder{*ast}, parse_error); - } } SECTION("double affectation") @@ -349,24 +233,6 @@ R s; R r=s; CHECK_AST(data, result); } - - SECTION("R <- string (invalid)") - { - std::string_view data = R"( -R r="foo"; -)"; - - string_input input{data, "test.pgs"}; - auto ast = ASTBuilder::build(input); - - ASTSymbolTableBuilder{*ast}; - ASTNodeDataTypeBuilder{*ast}; - - ASTNodeDeclarationToAffectationConverter{*ast}; - ASTNodeTypeCleaner<language::declaration>{*ast}; - - REQUIRE_THROWS_AS(ASTNodeExpressionBuilder{*ast}, parse_error); - } } SECTION("string affectation") @@ -727,8 +593,7 @@ string s="foo"; s/="bar"; ast->children.emplace_back(std::make_unique<ASTNode>()); ast->children.emplace_back(std::make_unique<ASTNode>()); - REQUIRE_THROWS_WITH(ASTNodeAffectationExpressionBuilder{*ast}, - "unexpected error: undefined operand type for affectation"); + REQUIRE_THROWS_WITH(ASTNodeAffectationExpressionBuilder{*ast}, "invalid implicit conversion: undefined -> Z"); } SECTION("Invalid string rhs") @@ -740,7 +605,7 @@ string s="foo"; s/="bar"; ast->children.emplace_back(std::make_unique<ASTNode>()); ast->children.emplace_back(std::make_unique<ASTNode>()); REQUIRE_THROWS_WITH(ASTNodeAffectationExpressionBuilder{*ast}, - "unexpected error: undefined operand type for string affectation"); + "invalid implicit conversion: undefined -> string"); } } } diff --git a/tests/test_ASTNodeExpressionBuilder.cpp b/tests/test_ASTNodeExpressionBuilder.cpp index 53b7b963f955df386eef108c3e408865e8ad33ef..9c764a0bcd0d2ad8050d56f540c649d750edd756 100644 --- a/tests/test_ASTNodeExpressionBuilder.cpp +++ b/tests/test_ASTNodeExpressionBuilder.cpp @@ -219,7 +219,7 @@ x /= 2; { std::string_view data = R"( N i = 1; -i += 3.; +i += 3; )"; std::string result = R"( @@ -227,9 +227,9 @@ i += 3.; +-(language::eq_op:AffectationProcessor<language::eq_op, unsigned long, long>) | +-(language::name:i:NameProcessor) | `-(language::integer:1:ValueProcessor) - `-(language::pluseq_op:AffectationProcessor<language::pluseq_op, unsigned long, double>) + `-(language::pluseq_op:AffectationProcessor<language::pluseq_op, unsigned long, long>) +-(language::name:i:NameProcessor) - `-(language::real:3.:ValueProcessor) + `-(language::integer:3:ValueProcessor) )"; CHECK_AST(data, result); diff --git a/tests/test_AffectationProcessor.cpp b/tests/test_AffectationProcessor.cpp index b37a47c7174110aa42056d6a34724f2569acae0b..bbbccadda20615efdd174c42bd61346390ee621d 100644 --- a/tests/test_AffectationProcessor.cpp +++ b/tests/test_AffectationProcessor.cpp @@ -63,6 +63,20 @@ Catch::Matchers::Contains("invalid operands to affectation expression")); \ } +#define CHECK_AFFECTATION_THROWS_WITH(data, error_message) \ + { \ + string_input input{data, "test.pgs"}; \ + auto ast = ASTBuilder::build(input); \ + \ + ASTSymbolTableBuilder{*ast}; \ + ASTNodeDataTypeBuilder{*ast}; \ + \ + ASTNodeDeclarationToAffectationConverter{*ast}; \ + ASTNodeTypeCleaner<language::declaration>{*ast}; \ + \ + REQUIRE_THROWS_WITH(ASTNodeExpressionBuilder{*ast}, error_message); \ + } + TEST_CASE("AffectationProcessor", "[language]") { SECTION("Affectations") @@ -70,9 +84,6 @@ TEST_CASE("AffectationProcessor", "[language]") SECTION("B") { CHECK_AFFECTATION_RESULT("B b; b = true;", "b", true); - CHECK_AFFECTATION_RESULT("N n = 1; B b; b = n;", "b", true); - CHECK_AFFECTATION_RESULT("B b; b = 1;", "b", true); - CHECK_AFFECTATION_RESULT("B b; b = 2.3;", "b", true); } SECTION("N") @@ -81,7 +92,6 @@ TEST_CASE("AffectationProcessor", "[language]") CHECK_AFFECTATION_RESULT("N m = 2; N n = m;", "n", 2ul); CHECK_AFFECTATION_RESULT("N n = true;", "n", 1ul); CHECK_AFFECTATION_RESULT("N n = false;", "n", 0ul); - CHECK_AFFECTATION_RESULT("N n = 2.3;", "n", 2ul); } SECTION("Z") @@ -89,7 +99,6 @@ TEST_CASE("AffectationProcessor", "[language]") CHECK_AFFECTATION_RESULT("Z z = -1;", "z", -1l); CHECK_AFFECTATION_RESULT("Z z = true;", "z", 1l); CHECK_AFFECTATION_RESULT("Z z = false;", "z", 0l); - CHECK_AFFECTATION_RESULT("Z z = -2.3;", "z", -2l); } SECTION("R") @@ -109,7 +118,6 @@ TEST_CASE("AffectationProcessor", "[language]") CHECK_AFFECTATION_RESULT("N m = 2; N n = 1; n += m;", "n", 3ul); CHECK_AFFECTATION_RESULT("N n = 1; n += true;", "n", 2ul); CHECK_AFFECTATION_RESULT("N n = 3; n += false;", "n", 3ul); - CHECK_AFFECTATION_RESULT("N n = 2; n += 1.1;", "n", 3ul); } SECTION("Z") @@ -118,7 +126,6 @@ TEST_CASE("AffectationProcessor", "[language]") CHECK_AFFECTATION_RESULT("N m = 2; Z z = 1; z += m;", "z", 3l); CHECK_AFFECTATION_RESULT("Z z = 1; z += true;", "z", 2l); CHECK_AFFECTATION_RESULT("Z z = 3; z += false;", "z", 3l); - CHECK_AFFECTATION_RESULT("Z z = 2; z += 1.1;", "z", 3l); } SECTION("R") @@ -139,7 +146,6 @@ TEST_CASE("AffectationProcessor", "[language]") CHECK_AFFECTATION_RESULT("N m = 2; N n = 4; n -= m;", "n", 2ul); CHECK_AFFECTATION_RESULT("N n = 1; n -= true;", "n", 0ul); CHECK_AFFECTATION_RESULT("N n = 3; n -= false;", "n", 3ul); - CHECK_AFFECTATION_RESULT("N n = 2; n -= 1.1;", "n", 0ul); } SECTION("Z") @@ -148,7 +154,6 @@ TEST_CASE("AffectationProcessor", "[language]") CHECK_AFFECTATION_RESULT("N m = 2; Z z = 1; z -= m;", "z", -1l); CHECK_AFFECTATION_RESULT("Z z = 1; z -= true;", "z", 0l); CHECK_AFFECTATION_RESULT("Z z = 3; z -= false;", "z", 3l); - CHECK_AFFECTATION_RESULT("Z z = 2; z -= 2.1;", "z", 0l); } SECTION("R") @@ -169,7 +174,6 @@ TEST_CASE("AffectationProcessor", "[language]") CHECK_AFFECTATION_RESULT("N m = 2; N n = 4; n *= m;", "n", 8ul); CHECK_AFFECTATION_RESULT("N n = 1; n *= true;", "n", 1ul); CHECK_AFFECTATION_RESULT("N n = 3; n *= false;", "n", 0ul); - CHECK_AFFECTATION_RESULT("N n = 2; n *= 2.51;", "n", 5ul); } SECTION("Z") @@ -178,7 +182,6 @@ TEST_CASE("AffectationProcessor", "[language]") CHECK_AFFECTATION_RESULT("N m = 2; Z z = -2; z *= m;", "z", -4l); CHECK_AFFECTATION_RESULT("Z z = 1; z *= true;", "z", 1l); CHECK_AFFECTATION_RESULT("Z z = 3; z *= false;", "z", 0l); - CHECK_AFFECTATION_RESULT("Z z = 2; z *= -2.51;", "z", -5l); } SECTION("R") @@ -198,7 +201,6 @@ TEST_CASE("AffectationProcessor", "[language]") CHECK_AFFECTATION_RESULT("N n = 4; n /= 2;", "n", 2ul); CHECK_AFFECTATION_RESULT("N m = 2; N n = 6; n /= m;", "n", 3ul); CHECK_AFFECTATION_RESULT("N n = 1; n /= true;", "n", 1ul); - CHECK_AFFECTATION_RESULT("N n = 2; n /= 2.51;", "n", 0ul); } SECTION("Z") @@ -206,7 +208,6 @@ TEST_CASE("AffectationProcessor", "[language]") CHECK_AFFECTATION_RESULT("Z z = 7; z /= -3;", "z", -2l); CHECK_AFFECTATION_RESULT("N m = 3; Z z = 6; z /= m;", "z", 2l); CHECK_AFFECTATION_RESULT("Z z = 6; z /= true;", "z", 6l); - CHECK_AFFECTATION_RESULT("Z z = 4; z /= -2.;", "z", -2l); } SECTION("R") @@ -220,9 +221,68 @@ TEST_CASE("AffectationProcessor", "[language]") SECTION("errors") { - CHECK_AFFECTATION_THROWS("B b = true; b += 1;"); - CHECK_AFFECTATION_THROWS("B b = true; b *= 1;"); - CHECK_AFFECTATION_THROWS("B b = true; b -= 1;"); - CHECK_AFFECTATION_THROWS("B b = true; b /= 1;"); + SECTION("invalid B affections") + { + CHECK_AFFECTATION_THROWS("B b = true; b += 1;"); + CHECK_AFFECTATION_THROWS("B b = true; b *= 1;"); + CHECK_AFFECTATION_THROWS("B b = true; b -= 1;"); + CHECK_AFFECTATION_THROWS("B b = true; b /= 1;"); + } + + SECTION("invalid implicit conversions") + { + SECTION("-> B") + { + CHECK_AFFECTATION_THROWS_WITH("N n = 1; B b; b = n;", "invalid implicit conversion: N -> B"); + CHECK_AFFECTATION_THROWS_WITH("B b; b = 1;", "invalid implicit conversion: Z -> B"); + CHECK_AFFECTATION_THROWS_WITH("B b; b = 2.3;", "invalid implicit conversion: R -> B"); + CHECK_AFFECTATION_THROWS_WITH("B b; b = \"foo\";", "invalid implicit conversion: string -> B"); + } + + SECTION("-> N") + { + CHECK_AFFECTATION_THROWS_WITH("N n = 2.3;", "invalid implicit conversion: R -> N"); + CHECK_AFFECTATION_THROWS_WITH("N n = \"bar\";", "invalid implicit conversion: string -> N"); + + CHECK_AFFECTATION_THROWS_WITH("N n = 2; n += 1.1;", "invalid implicit conversion: R -> N"); + CHECK_AFFECTATION_THROWS_WITH("N n = 2; n += \"foo\";", "invalid implicit conversion: string -> N"); + + CHECK_AFFECTATION_THROWS_WITH("N n = 2; n -= 1.1;", "invalid implicit conversion: R -> N"); + CHECK_AFFECTATION_THROWS_WITH("N n = 2; n -= \"bar\";", "invalid implicit conversion: string -> N"); + + CHECK_AFFECTATION_THROWS_WITH("N n = 2; n *= 2.51;", "invalid implicit conversion: R -> N"); + CHECK_AFFECTATION_THROWS_WITH("N n = 2; n *= \"foobar\";", "invalid implicit conversion: string -> N"); + + CHECK_AFFECTATION_THROWS_WITH("N n = 2; n /= 2.51;", "invalid implicit conversion: R -> N"); + CHECK_AFFECTATION_THROWS_WITH("N n = 2; n /= \"foo\";", "invalid implicit conversion: string -> N"); + } + + SECTION("-> Z") + { + CHECK_AFFECTATION_THROWS_WITH("Z z = -2.3;", "invalid implicit conversion: R -> Z"); + CHECK_AFFECTATION_THROWS_WITH("Z z = \"foobar\";", "invalid implicit conversion: string -> Z"); + + CHECK_AFFECTATION_THROWS_WITH("Z z = 2; z += 1.1;", "invalid implicit conversion: R -> Z"); + CHECK_AFFECTATION_THROWS_WITH("Z z = 2; z += \"foo\";", "invalid implicit conversion: string -> Z"); + + CHECK_AFFECTATION_THROWS_WITH("Z z = 2; z -= 2.1;", "invalid implicit conversion: R -> Z"); + CHECK_AFFECTATION_THROWS_WITH("Z z = 2; z -= \"bar\";", "invalid implicit conversion: string -> Z"); + + CHECK_AFFECTATION_THROWS_WITH("Z z = 2; z *= -2.51;", "invalid implicit conversion: R -> Z"); + CHECK_AFFECTATION_THROWS_WITH("Z z = 2; z *= \"foobar\";", "invalid implicit conversion: string -> Z"); + + CHECK_AFFECTATION_THROWS_WITH("Z z = 4; z /= -2.;", "invalid implicit conversion: R -> Z"); + CHECK_AFFECTATION_THROWS_WITH("Z z = 2; z /= \"foo\";", "invalid implicit conversion: string -> Z"); + } + + SECTION("-> R") + { + CHECK_AFFECTATION_THROWS_WITH("R x = \"foobar\";", "invalid implicit conversion: string -> R"); + CHECK_AFFECTATION_THROWS_WITH("R x = 2.3; x += \"foo\";", "invalid implicit conversion: string -> R"); + CHECK_AFFECTATION_THROWS_WITH("R x = 2.1; x -= \"bar\";", "invalid implicit conversion: string -> R"); + CHECK_AFFECTATION_THROWS_WITH("R x = 1.2; x *= \"foobar\";", "invalid implicit conversion: string -> R"); + CHECK_AFFECTATION_THROWS_WITH("R x =-2.3; x /= \"foo\";", "invalid implicit conversion: string -> R"); + } + } } } diff --git a/tests/test_BinaryExpressionProcessor_arithmetic.cpp b/tests/test_BinaryExpressionProcessor_arithmetic.cpp index edfd50dfff4b72e81b374bb092fbc6fe9edd44c3..9c229c5d5fb9f1b22e8e0fc3b645f0547d31944d 100644 --- a/tests/test_BinaryExpressionProcessor_arithmetic.cpp +++ b/tests/test_BinaryExpressionProcessor_arithmetic.cpp @@ -23,7 +23,7 @@ TEST_CASE("BinaryExpressionProcessor arithmetic", "[language]") CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 1; n = n + true;)", "n", 2ul); CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 4; N m = 2; n = n + m;)", "n", 6ul); CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 4; Z z = -1; n = n + z;)", "n", 3ul); - CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 1 + 2.3;)", "n", 3ul); + CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 1; R x = n + 2.3;)", "x", 3.3); } SECTION("lhs is Z") @@ -32,7 +32,7 @@ TEST_CASE("BinaryExpressionProcessor arithmetic", "[language]") CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 4; Z z = -3 + n;)", "z", 1l); CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 2; Z z = -3 + n;)", "z", -1l); CHECK_BINARY_EXPRESSION_RESULT(R"(Z z = 1 + 2;)", "z", 3l); - CHECK_BINARY_EXPRESSION_RESULT(R"(Z z = 3 + 2.5;)", "z", 5l); + CHECK_BINARY_EXPRESSION_RESULT(R"(R x = 3 + 2.5;)", "x", 5.5); } SECTION("lhs is R") @@ -59,7 +59,7 @@ TEST_CASE("BinaryExpressionProcessor arithmetic", "[language]") CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 3; n = n - true;)", "n", 2ul); CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 4; N m = 2; n = n - m;)", "n", 2ul); CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 5; n = n - 4;)", "n", 1ul); - CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 3 - 2.3;)", "n", 0ul); + CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 3; R x = n - 2.3;)", "x", double{3ul - 2.3}); } SECTION("lhs is Z") @@ -67,7 +67,7 @@ TEST_CASE("BinaryExpressionProcessor arithmetic", "[language]") CHECK_BINARY_EXPRESSION_RESULT(R"(Z z = -1 - true;)", "z", -2l); CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 4; Z z = 3 - n;)", "z", -1l); CHECK_BINARY_EXPRESSION_RESULT(R"(Z z = 7 - 2;)", "z", 5l); - CHECK_BINARY_EXPRESSION_RESULT(R"(Z z = 4 - 2.5;)", "z", 1l); + CHECK_BINARY_EXPRESSION_RESULT(R"(R x = 4 - 2.5;)", "x", 1.5); } SECTION("lhs is R") @@ -94,8 +94,7 @@ TEST_CASE("BinaryExpressionProcessor arithmetic", "[language]") CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 3; n = n * true;)", "n", 3ul); CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 4; N m = 2; n = n * m;)", "n", 8ul); CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 5; n = n * 4;)", "n", 20ul); - CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 3 * 2.3;)", "n", 6ul); - CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 3 * 2.5;)", "n", 7ul); + CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 3; R x = n * 2.3;)", "x", double{3ul * 2.3}); } SECTION("lhs is Z") @@ -103,7 +102,7 @@ TEST_CASE("BinaryExpressionProcessor arithmetic", "[language]") CHECK_BINARY_EXPRESSION_RESULT(R"(Z z = -1 * true;)", "z", -1l); CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 4; Z z = 3 * n;)", "z", 12l); CHECK_BINARY_EXPRESSION_RESULT(R"(Z z = 7 * 2;)", "z", 14l); - CHECK_BINARY_EXPRESSION_RESULT(R"(Z z = 4 * 2.4;)", "z", 9l); + CHECK_BINARY_EXPRESSION_RESULT(R"(R x = 4 * 2.4;)", "x", double{4l * 2.4}); } SECTION("lhs is R") @@ -130,7 +129,7 @@ TEST_CASE("BinaryExpressionProcessor arithmetic", "[language]") CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 3; n = n / true;)", "n", 3ul); CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 4; N m = 2; n = n / m;)", "n", 2ul); CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 5; n = n / 4;)", "n", 1ul); - CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 3 / 2.3;)", "n", 1ul); + CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 3; R x = n / 2.3;)", "x", double{3ul / 2.3}); } SECTION("lhs is Z") @@ -138,7 +137,7 @@ TEST_CASE("BinaryExpressionProcessor arithmetic", "[language]") CHECK_BINARY_EXPRESSION_RESULT(R"(Z z = -1 / true;)", "z", -1l); CHECK_BINARY_EXPRESSION_RESULT(R"(N n = 4; Z z = 3 / n;)", "z", 0l); CHECK_BINARY_EXPRESSION_RESULT(R"(Z z = 7 / 2;)", "z", 3l); - CHECK_BINARY_EXPRESSION_RESULT(R"(Z z = 4 / 2.4;)", "z", 1l); + CHECK_BINARY_EXPRESSION_RESULT(R"(R x = 4 / 2.4;)", "x", double{4l / 2.4}); } SECTION("lhs is R")