#include <catch2/catch.hpp> #include <language/ast/ASTBuilder.hpp> #include <language/ast/ASTNodeAffectationExpressionBuilder.hpp> #include <language/ast/ASTNodeDataTypeBuilder.hpp> #include <language/ast/ASTNodeDeclarationToAffectationConverter.hpp> #include <language/ast/ASTNodeExpressionBuilder.hpp> #include <language/ast/ASTNodeTypeCleaner.hpp> #include <language/ast/ASTSymbolTableBuilder.hpp> #include <language/utils/ASTPrinter.hpp> #include <utils/Demangle.hpp> #include <pegtl/string_input.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::var_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); \ } // clazy:excludeall=non-pod-global-static TEST_CASE("ASTAffectationToTupleProcessor", "[language]") { SECTION("Affectations from value") { CHECK_AFFECTATION_RESULT(R"( let s :(R); s = 2.; )", "s", (std::vector<double>{2.})); CHECK_AFFECTATION_RESULT(R"( let s :(R); s = 2; )", "s", (std::vector<double>{2})); CHECK_AFFECTATION_RESULT(R"( let s :(string); s = 2.; )", "s", (std::vector<std::string>{std::to_string(2.)})); const std::string x_string = []() -> std::string { std::ostringstream os; os << TinyVector<3, double>{1, 2, 3} << std::ends; return os.str(); }(); CHECK_AFFECTATION_RESULT(R"( let x :R^3, x = (1,2,3); let s :(string); s = x; )", "s", (std::vector<std::string>{x_string})); CHECK_AFFECTATION_RESULT(R"( let s :(R^1); s = 1.3; )", "s", (std::vector<TinyVector<1>>{TinyVector<1>{1.3}})); } SECTION("Affectations from list") { CHECK_AFFECTATION_RESULT(R"( let t :(R); t = (2.,3); )", "t", (std::vector<double>{2., 3})); CHECK_AFFECTATION_RESULT(R"( let s :(string); s = (2.,3); )", "s", (std::vector<std::string>{std::to_string(2.), std::to_string(3)})); CHECK_AFFECTATION_RESULT(R"( let s :(string); s = (2.,3,"foo"); )", "s", (std::vector<std::string>{std::to_string(2.), std::to_string(3), std::string{"foo"}})); const std::string x_string = []() -> std::string { std::ostringstream os; os << TinyVector<2, double>{1, 2} << std::ends; return os.str(); }(); CHECK_AFFECTATION_RESULT(R"( let x : R^2, x = (1,2); let s : (string); s = (2.,3, x); )", "s", (std::vector<std::string>{std::to_string(2.), std::to_string(3), x_string})); CHECK_AFFECTATION_RESULT(R"( let x : R^2, x = (1,2); let t :(R^2); t = (x,0); )", "t", (std::vector<TinyVector<2>>{TinyVector<2>{1, 2}, TinyVector<2>{0, 0}})); CHECK_AFFECTATION_RESULT(R"( let t :(R^2); t = ((1,2),0); )", "t", (std::vector<TinyVector<2>>{TinyVector<2>{1, 2}, TinyVector<2>{0, 0}})); CHECK_AFFECTATION_RESULT(R"( let t :(R^2); t = (0); )", "t", (std::vector<TinyVector<2>>{TinyVector<2>{0, 0}})); CHECK_AFFECTATION_RESULT(R"( let t :(R^3); t = (0); )", "t", (std::vector<TinyVector<3>>{TinyVector<3>{0, 0, 0}})); CHECK_AFFECTATION_RESULT(R"( let x : R^1, x = 1; let t :(R^1); t = (x,2); )", "t", (std::vector<TinyVector<1>>{TinyVector<1>{1}, TinyVector<1>{2}})); } SECTION("Affectations from tuple") { const std::string x_string = []() -> std::string { std::ostringstream os; os << TinyVector<3, double>{1, 2, 3} << std::ends; return os.str(); }(); CHECK_AFFECTATION_RESULT(R"( let x :(R^3), x = ((1,2,3)); let s :(string); s = x; )", "s", (std::vector<std::string>{x_string})); CHECK_AFFECTATION_RESULT(R"( let x :(R), x = (1,2,3); let s :(string); s = x; )", "s", (std::vector<std::string>{std::to_string(1.), std::to_string(2.), std::to_string(3.)})); CHECK_AFFECTATION_RESULT(R"( let n :(N), n = (1,2,3); let t :(R); t = n; )", "t", (std::vector<double>{1, 2, 3})); CHECK_AFFECTATION_RESULT(R"( let s :(N), s = (1,2,3); let t :(N); t = s; )", "t", (std::vector<uint64_t>{1, 2, 3})); } }