#include <catch2/catch_test_macros.hpp> #include <catch2/matchers/catch_matchers_all.hpp> #include <language/ast/ASTBuilder.hpp> #include <language/ast/ASTExecutionStack.hpp> #include <language/ast/ASTModulesImporter.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/node_processor/ConcatExpressionProcessor.hpp> #include <language/utils/ASTPrinter.hpp> #include <utils/Demangle.hpp> #include <utils/Stringify.hpp> #include <pegtl/string_input.hpp> #include <sstream> #define CHECK_CONCAT_EXPRESSION_RESULT(data, variable_name, expected_value) \ { \ TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"}; \ auto ast = ASTBuilder::build(input); \ \ ASTExecutionStack::create(); \ \ ASTModulesImporter{*ast}; \ ASTNodeTypeCleaner<language::import_instruction>{*ast}; \ \ 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{10000, 1000, 10, "fixture"}; \ auto [symbol, found] = symbol_table->find(variable_name, use_position); \ \ auto attributes = symbol->attributes(); \ auto value = std::get<decltype(expected_value)>(attributes.value()); \ \ ASTExecutionStack::destroy(); \ \ REQUIRE(value == expected_value); \ ast->m_symbol_table->clearValues(); \ } // clazy:excludeall=non-pod-global-static TEST_CASE("ConcatExpressionProcessor", "[language]") { SECTION("string + string") { CHECK_CONCAT_EXPRESSION_RESULT(R"(let s:string, s = "foo"; s = s+"bar";)", "s", std::string{"foobar"}); } SECTION("string + N") { CHECK_CONCAT_EXPRESSION_RESULT(R"(let n:N, n = 1; let s:string, s = "foo_"; s = s+n;)", "s", std::string{"foo_1"}); } SECTION("N + string") { CHECK_CONCAT_EXPRESSION_RESULT(R"(let n:N, n = 1; let s:string, s = "_foo"; s = n+s;)", "s", std::string{"1_foo"}); } SECTION("string + Z") { CHECK_CONCAT_EXPRESSION_RESULT(R"(let s:string, s = "foo_"; s = s+2;)", "s", std::string{"foo_2"}); } SECTION("Z + string") { CHECK_CONCAT_EXPRESSION_RESULT(R"(let s:string, s = "_foo"; s = 2+s;)", "s", std::string{"2_foo"}); } SECTION("string + R") { CHECK_CONCAT_EXPRESSION_RESULT(R"(let s:string, s = "foo_"; s = s+2.4;)", "s", std::string{"foo_"} + stringify(2.4)); } SECTION("R + string") { CHECK_CONCAT_EXPRESSION_RESULT(R"(let s:string, s = "_foo"; s = 2.4+s;)", "s", stringify(2.4) + std::string{"_foo"}); } SECTION("string + B") { CHECK_CONCAT_EXPRESSION_RESULT(R"(let s:string, s = "foo_"; s = s+(2>1);)", "s", std::string{"foo_true"}); CHECK_CONCAT_EXPRESSION_RESULT(R"(let s:string, s = "foo_"; s = s+(1>2);)", "s", std::string{"foo_false"}); } SECTION("B + string") { CHECK_CONCAT_EXPRESSION_RESULT(R"(let s:string, s = "_foo"; s = (2>1)+s;)", "s", std::string{"true_foo"}); CHECK_CONCAT_EXPRESSION_RESULT(R"(let s:string, s = "_foo"; s = (1>2)+s;)", "s", std::string{"false_foo"}); } SECTION("string + R^1") { std::ostringstream os; os << "foo_" << TinyVector<1>{1}; CHECK_CONCAT_EXPRESSION_RESULT(R"(let x:R^1, x = 1; let s:string, s = "foo_"; s = s+x;)", "s", os.str()); } SECTION("R^1 + string") { std::ostringstream os; os << TinyVector<1>{1} << "_foo"; CHECK_CONCAT_EXPRESSION_RESULT(R"(let x:R^1, x = 1; let s:string, s = "_foo"; s = x+s;)", "s", os.str()); } SECTION("string + R^2") { std::ostringstream os; os << "foo_" << TinyVector<2>{1, 2}; CHECK_CONCAT_EXPRESSION_RESULT(R"(let x:R^2, x = [1,2]; let s:string, s = "foo_"; s = s+x;)", "s", os.str()); } SECTION(" R^2 + string") { std::ostringstream os; os << TinyVector<2>{1, 2} << "_foo"; CHECK_CONCAT_EXPRESSION_RESULT(R"(let x:R^2, x = [1,2]; let s:string, s = "_foo"; s = x+s;)", "s", os.str()); } SECTION("string + R^3") { std::ostringstream os; os << "foo_" << TinyVector<3>{1, 2, 3}; CHECK_CONCAT_EXPRESSION_RESULT(R"(let s:string, s = "foo_"; s = s+[1,2,3];)", "s", os.str()); } SECTION("R^3 + string") { std::ostringstream os; os << TinyVector<3>{1, 2, 3} << "_foo"; CHECK_CONCAT_EXPRESSION_RESULT(R"(let x:R^3, x = [1,2,3]; let s:string, s = "_foo"; s = x+s;)", "s", os.str()); } SECTION("string + R^1x1") { std::ostringstream os; os << "foo_" << TinyMatrix<1>{1}; CHECK_CONCAT_EXPRESSION_RESULT(R"(let x:R^1x1, x = 1; let s:string, s = "foo_"; s = s+x;)", "s", os.str()); } SECTION("R^1x1 + string") { std::ostringstream os; os << TinyMatrix<1>{1} << "_foo"; CHECK_CONCAT_EXPRESSION_RESULT(R"(let x:R^1x1, x = 1; let s:string, s = "_foo"; s = x+s;)", "s", os.str()); } SECTION("string + R^2x2") { std::ostringstream os; os << "foo_" << TinyMatrix<2>{1, 2, 3, 4}; CHECK_CONCAT_EXPRESSION_RESULT(R"(let x:R^2x2, x = [[1,2],[3,4]]; let s:string, s = "foo_"; s = s+x;)", "s", os.str()); } SECTION(" R^2x2 + string") { std::ostringstream os; os << TinyMatrix<2>{1, 2, 3, 4} << "_foo"; CHECK_CONCAT_EXPRESSION_RESULT(R"(let x:R^2x2, x = [[1,2],[3,4]]; let s:string, s = "_foo"; s = x+s;)", "s", os.str()); } SECTION("string + R^3x3") { std::ostringstream os; os << "foo_" << TinyMatrix<3>{1, 2, 3, 4, 5, 6, 7, 8, 9}; CHECK_CONCAT_EXPRESSION_RESULT(R"(let x:R^3x3, x = [[1,2,3],[4,5,6],[7,8,9]]; let s:string, s = "foo_"; s = s+x;)", "s", os.str()); } SECTION("R^3x3 + string") { std::ostringstream os; os << TinyMatrix<3>{1, 2, 3, 4, 5, 6, 7, 8, 9} << "_foo"; CHECK_CONCAT_EXPRESSION_RESULT(R"(let x:R^3x3, x = [[1,2,3],[4,5,6],[7,8,9]]; let s:string, s = "_foo"; s = x+s;)", "s", os.str()); } SECTION("expression type") { ASTNode node; REQUIRE(ConcatExpressionProcessor<std::string, std::string>{node}.type() == INodeProcessor::Type::concat_expression_processor); } }