diff --git a/src/language/ASTNodeListAffectationExpressionBuilder.cpp b/src/language/ASTNodeListAffectationExpressionBuilder.cpp index 2218ae86475df86aa3ac8d95f32864d2126d46b5..624bddbcbfbc183cddf9beffc8fdf65f88908cbf 100644 --- a/src/language/ASTNodeListAffectationExpressionBuilder.cpp +++ b/src/language/ASTNodeListAffectationExpressionBuilder.cpp @@ -96,10 +96,33 @@ ASTNodeListAffectationExpressionBuilder::_buildAffectationProcessor( case ASTNodeDataType::string_t: { list_affectation_processor->template add<std::string, std::string>(value_node); break; + } + case ASTNodeDataType::vector_t: { + switch (node_sub_data_type.m_data_type.dimension()) { + case 1: { + list_affectation_processor->template add<std::string, TinyVector<1>>(value_node); + break; + } + case 2: { + list_affectation_processor->template add<std::string, TinyVector<2>>(value_node); + break; + } + case 3: { + list_affectation_processor->template add<std::string, TinyVector<3>>(value_node); + break; + } + // LCOV_EXCL_START + default: { + throw parse_error("unexpected error: invalid vector dimension", + std::vector{node_sub_data_type.m_parent_node.begin()}); + } + // LCOV_EXCL_STOP + } + break; } // LCOV_EXCL_START default: { - throw parse_error("invalid operand type for string affectation", + throw parse_error("unexpected error:invalid operand type for string affectation", std::vector{node_sub_data_type.m_parent_node.begin()}); } // LCOV_EXCL_STOP diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f72040858567b81bb4ec7f9a12de2ecc85bf3594..01762e9d1ed0b211ca5e3a81a0c43609786d7e16 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -59,6 +59,7 @@ add_executable (unit_tests test_IncDecExpressionProcessor.cpp test_INodeProcessor.cpp test_ItemType.cpp + test_ListAffectationProcessor.cpp test_NameProcessor.cpp test_OStreamProcessor.cpp test_PCG.cpp diff --git a/tests/test_ListAffectationProcessor.cpp b/tests/test_ListAffectationProcessor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eb86bdb66ab45bb10049e758eb7738946474f204 --- /dev/null +++ b/tests/test_ListAffectationProcessor.cpp @@ -0,0 +1,111 @@ +#include <catch2/catch.hpp> + +#include <ASTBuilder.hpp> +#include <ASTNodeDataTypeBuilder.hpp> + +#include <ASTNodeDeclarationToAffectationConverter.hpp> +#include <ASTNodeTypeCleaner.hpp> + +#include <ASTNodeExpressionBuilder.hpp> + +#include <ASTNodeAffectationExpressionBuilder.hpp> + +#include <ASTSymbolTableBuilder.hpp> + +#include <ASTPrinter.hpp> + +#include <Demangle.hpp> + +#include <PEGGrammar.hpp> + +#include <sstream> + +#define CHECK_AFFECTATION_RESULT(data, variable_name, expected_value) \ + { \ + string_input input{data, "test.pgs"}; \ + auto ast = ASTBuilder::build(input); \ + \ + ASTSymbolTableBuilder{*ast}; \ + ASTNodeDataTypeBuilder{*ast}; \ + \ + ASTNodeDeclarationToAffectationConverter{*ast}; \ + ASTNodeTypeCleaner<language::declaration>{*ast}; \ + \ + ASTNodeExpressionBuilder{*ast}; \ + ExecutionPolicy exec_policy; \ + ast->execute(exec_policy); \ + \ + auto symbol_table = ast->m_symbol_table; \ + \ + using namespace TAO_PEGTL_NAMESPACE; \ + position use_position{internal::iterator{"fixture"}, "fixture"}; \ + use_position.byte = 10000; \ + auto [symbol, found] = symbol_table->find(variable_name, use_position); \ + \ + auto attributes = symbol->attributes(); \ + auto value = std::get<decltype(expected_value)>(attributes.value()); \ + \ + REQUIRE(value == expected_value); \ + } + +#define CHECK_AFFECTATION_THROWS(data) \ + { \ + string_input input{data, "test.pgs"}; \ + auto ast = ASTBuilder::build(input); \ + \ + ASTSymbolTableBuilder{*ast}; \ + ASTNodeDataTypeBuilder{*ast}; \ + \ + ASTNodeDeclarationToAffectationConverter{*ast}; \ + ASTNodeTypeCleaner<language::declaration>{*ast}; \ + \ + REQUIRE_THROWS(ASTNodeExpressionBuilder{*ast}, \ + 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("ListAffectationProcessor", "[language]") +{ + SECTION("ListAffectations") + { + SECTION("R*R^2*string") + { + CHECK_AFFECTATION_RESULT(R"(R*R^2*string (x,u,s) = (1.2, (2,3), "foo");)", "x", double{1.2}); + CHECK_AFFECTATION_RESULT(R"(R*R^2*string (x,u,s) = (1.2, (2,3), "foo");)", "u", (TinyVector<2>{2, 3})); + CHECK_AFFECTATION_RESULT(R"(R*R^2*string (x,u,s) = (1.2, (2,3), "foo");)", "s", std::string{"foo"}); + } + + SECTION("compound with string conversion") + { + CHECK_AFFECTATION_RESULT(R"(R z = 3; R*R^2*string (x,u,s) = (1.2, (2,3), z);)", "s", std::to_string(double{3})); + { + std::ostringstream os; + os << TinyVector<1>{7} << std::ends; + CHECK_AFFECTATION_RESULT(R"(R^1 v = 7; R*R^2*string (x,u,s) = (1.2, (2,3), v);)", "s", os.str()); + } + { + std::ostringstream os; + os << TinyVector<2>{6, 3} << std::ends; + CHECK_AFFECTATION_RESULT(R"(R^2 v = (6,3); R*R^2*string (x,u,s) = (1.2, (2,3), v);)", "s", os.str()); + } + { + std::ostringstream os; + os << TinyVector<3>{1, 2, 3} << std::ends; + CHECK_AFFECTATION_RESULT(R"(R^3 v = (1,2,3); R*R^2*string (x,u,s) = (1.2, (2,3), v);)", "s", os.str()); + } + } + } +}