From 2c98418e80a72f0905e1d678864805839eeff09c Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Mon, 28 Oct 2024 22:24:35 +0100 Subject: [PATCH] Add parsing of R^d and R^dxd tuple arguments which were missing Also add corresponding unit tests --- ...STNodeBuiltinFunctionExpressionBuilder.cpp | 39 +++- ...STNodeBuiltinFunctionExpressionBuilder.cpp | 104 +++++++++- tests/test_BuiltinFunctionEmbedder.cpp | 194 ++++++++++++++++++ tests/test_BuiltinFunctionRegister.hpp | 27 +++ 4 files changed, 362 insertions(+), 2 deletions(-) diff --git a/src/language/ast/ASTNodeBuiltinFunctionExpressionBuilder.cpp b/src/language/ast/ASTNodeBuiltinFunctionExpressionBuilder.cpp index 169540df2..1a1e23785 100644 --- a/src/language/ast/ASTNodeBuiltinFunctionExpressionBuilder.cpp +++ b/src/language/ast/ASTNodeBuiltinFunctionExpressionBuilder.cpp @@ -204,6 +204,43 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData case ASTNodeDataType::double_t: { return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, double>>(argument_number); } + case ASTNodeDataType::vector_t: { + switch (tuple_content_type.dimension()) { + case 1: { + return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, TinyVector<1>>>(argument_number); + } + case 2: { + return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, TinyVector<2>>>(argument_number); + } + case 3: { + return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, TinyVector<3>>>(argument_number); + } + // LCOV_EXCL_START + default: { + throw UnexpectedError(dataTypeName(tuple_content_type) + " unexpected dimension of vector"); + } + // LCOV_EXCL_STOP + } + } + case ASTNodeDataType::matrix_t: { + Assert(tuple_content_type.numberOfRows() == tuple_content_type.numberOfColumns()); + switch (tuple_content_type.numberOfRows()) { + case 1: { + return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, TinyMatrix<1>>>(argument_number); + } + case 2: { + return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, TinyMatrix<2>>>(argument_number); + } + case 3: { + return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, TinyMatrix<3>>>(argument_number); + } + // LCOV_EXCL_START + default: { + throw UnexpectedError(dataTypeName(tuple_content_type) + " unexpected dimension of matrix"); + } + // LCOV_EXCL_STOP + } + } case ASTNodeDataType::string_t: { return std::make_unique<FunctionTupleArgumentConverter<ParameterContentT, std::string>>(argument_number); } @@ -281,7 +318,7 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData } // LCOV_EXCL_START default: { - throw UnexpectedError(dataTypeName(arg_data_type) + " unexpected dimension of vector"); + throw UnexpectedError(dataTypeName(arg_data_type) + " unexpected dimension of matrix"); } // LCOV_EXCL_STOP } diff --git a/tests/test_ASTNodeBuiltinFunctionExpressionBuilder.cpp b/tests/test_ASTNodeBuiltinFunctionExpressionBuilder.cpp index 05b64ce51..09b2a05f2 100644 --- a/tests/test_ASTNodeBuiltinFunctionExpressionBuilder.cpp +++ b/tests/test_ASTNodeBuiltinFunctionExpressionBuilder.cpp @@ -1201,7 +1201,7 @@ tuple_RtoB(1.2); CHECK_AST(data, result); } - SECTION("tuple(R) -> tuple(R)") + SECTION("tuple(R) -> B") { std::string_view data = R"( let t:(R), t = (1,2,4,6); @@ -1218,6 +1218,108 @@ tuple_RtoB(t); CHECK_AST(data, result); } + SECTION("tuple(R^1) -> B") + { + std::string_view data = R"( +let t:(R^1), t = ([1],[2],[4]); +tuple_R1toB(t); +)"; + + std::string_view result = R"( +(root:ASTNodeListProcessor) + `-(language::function_evaluation:BuiltinFunctionProcessor) + +-(language::name:tuple_R1toB:FakeProcessor) + `-(language::name:t:NameProcessor) +)"; + + CHECK_AST(data, result); + } + + SECTION("tuple(R^2) -> B") + { + std::string_view data = R"( +let t:(R^2), t = ([1,1],[2,2],[4,3]); +tuple_R2toB(t); +)"; + + std::string_view result = R"( +(root:ASTNodeListProcessor) + `-(language::function_evaluation:BuiltinFunctionProcessor) + +-(language::name:tuple_R2toB:FakeProcessor) + `-(language::name:t:NameProcessor) +)"; + + CHECK_AST(data, result); + } + + SECTION("tuple(R^3) -> B") + { + std::string_view data = R"( +let t:(R^3), t = ([1,1,2],[2,3,2],[4,3.2,2]); +tuple_R3toB(t); +)"; + + std::string_view result = R"( +(root:ASTNodeListProcessor) + `-(language::function_evaluation:BuiltinFunctionProcessor) + +-(language::name:tuple_R3toB:FakeProcessor) + `-(language::name:t:NameProcessor) +)"; + + CHECK_AST(data, result); + } + + SECTION("tuple(R^1x1) -> B") + { + std::string_view data = R"( +let t:(R^1x1), t = ([[1]],[[2]],[[4]]); +tuple_R11toB(t); +)"; + + std::string_view result = R"( +(root:ASTNodeListProcessor) + `-(language::function_evaluation:BuiltinFunctionProcessor) + +-(language::name:tuple_R11toB:FakeProcessor) + `-(language::name:t:NameProcessor) +)"; + + CHECK_AST(data, result); + } + + SECTION("tuple(R^2x2) -> B") + { + std::string_view data = R"( +let t:(R^2x2), t = ([[1,2],[3,4]],[[2,4],[1,3]]); +tuple_R22toB(t); +)"; + + std::string_view result = R"( +(root:ASTNodeListProcessor) + `-(language::function_evaluation:BuiltinFunctionProcessor) + +-(language::name:tuple_R22toB:FakeProcessor) + `-(language::name:t:NameProcessor) +)"; + + CHECK_AST(data, result); + } + + SECTION("tuple(R^3x3) -> B") + { + std::string_view data = R"( +let t:(R^3x3), t = ([[1,2,3],[5,6,7],[8,9,10]],[[2,4,8],[1,3,2],[3,1,6]]); +tuple_R33toB(t); +)"; + + std::string_view result = R"( +(root:ASTNodeListProcessor) + `-(language::function_evaluation:BuiltinFunctionProcessor) + +-(language::name:tuple_R33toB:FakeProcessor) + `-(language::name:t:NameProcessor) +)"; + + CHECK_AST(data, result); + } + SECTION("list -> tuple(R)") { std::string_view data = R"( diff --git a/tests/test_BuiltinFunctionEmbedder.cpp b/tests/test_BuiltinFunctionEmbedder.cpp index be28e7d75..62c5129cd 100644 --- a/tests/test_BuiltinFunctionEmbedder.cpp +++ b/tests/test_BuiltinFunctionEmbedder.cpp @@ -231,6 +231,200 @@ TEST_CASE("BuiltinFunctionEmbedder", "[language]") demangle<std::vector<EmbeddedData>>() + "\" to \"" + demangle<std::vector<uint64_t>>() + '"'); } + SECTION("int64_t(std::vector<int64_t>) BuiltinFunctionEmbedder") + { + std::function sum = [&](const std::vector<int64_t>& x) -> int64_t { + int64_t s = 0; + for (size_t i = 0; i < x.size(); ++i) { + s += x[i]; + } + return s; + }; + + std::unique_ptr<IBuiltinFunctionEmbedder> i_embedded_c = + std::make_unique<BuiltinFunctionEmbedder<int64_t(const std::vector<int64_t>&)>>(sum); + + REQUIRE(i_embedded_c->numberOfParameters() == 1); + REQUIRE(i_embedded_c->getParameterDataTypes().size() == 1); + REQUIRE(i_embedded_c->getParameterDataTypes()[0] == ASTNodeDataType::tuple_t); + REQUIRE(i_embedded_c->getReturnDataType() == ASTNodeDataType::int_t); + + REQUIRE(std::get<int64_t>(i_embedded_c->apply({std::vector{1l, -2l, 3l}})) == 2); + REQUIRE(std::get<int64_t>(i_embedded_c->apply({std::vector{-1l, -2l, 3l, 4l}})) == 4); + + REQUIRE_THROWS_WITH(i_embedded_c->apply({std::vector{1.2, 2.3, 3.1, 4.4}}), + "unexpected error: unexpected argument types while casting \"" + + demangle<std::vector<double>>() + "\" to \"" + demangle<std::vector<int64_t>>() + '"'); + + REQUIRE_THROWS_WITH(i_embedded_c->apply({std::vector<EmbeddedData>{}}), + "unexpected error: unexpected argument types while casting \"" + + demangle<std::vector<EmbeddedData>>() + "\" to \"" + demangle<std::vector<int64_t>>() + '"'); + } + + SECTION("double(std::vector<double>) BuiltinFunctionEmbedder") + { + std::function sum = [&](const std::vector<double>& x) -> double { + double s = 0; + for (size_t i = 0; i < x.size(); ++i) { + s += x[i]; + } + return s; + }; + + std::unique_ptr<IBuiltinFunctionEmbedder> i_embedded_c = + std::make_unique<BuiltinFunctionEmbedder<double(const std::vector<double>&)>>(sum); + + REQUIRE(i_embedded_c->numberOfParameters() == 1); + REQUIRE(i_embedded_c->getParameterDataTypes().size() == 1); + REQUIRE(i_embedded_c->getParameterDataTypes()[0] == ASTNodeDataType::tuple_t); + REQUIRE(i_embedded_c->getReturnDataType() == ASTNodeDataType::double_t); + + REQUIRE(std::get<double>(i_embedded_c->apply({std::vector<double>{1.2, -2.2, 3.1}})) == 1.2 - 2.2 + 3.1); + } + + SECTION("TinyVector<1>(std::vector<TinyVector<1>>) BuiltinFunctionEmbedder") + { + using Rd = TinyVector<1>; + std::function sum = [&](const std::vector<Rd>& x) -> Rd { + Rd s = zero; + for (size_t i = 0; i < x.size(); ++i) { + s += x[i]; + } + return s; + }; + + std::unique_ptr<IBuiltinFunctionEmbedder> i_embedded_c = + std::make_unique<BuiltinFunctionEmbedder<Rd(const std::vector<Rd>&)>>(sum); + + REQUIRE(i_embedded_c->numberOfParameters() == 1); + REQUIRE(i_embedded_c->getParameterDataTypes().size() == 1); + REQUIRE(i_embedded_c->getParameterDataTypes()[0] == ASTNodeDataType::tuple_t); + REQUIRE(i_embedded_c->getReturnDataType() == ast_node_data_type_from<Rd>); + + REQUIRE(std::get<Rd>(i_embedded_c->apply({std::vector<Rd>{Rd{1.2}, Rd{-2.2}, Rd{3.1}}})) == + Rd{1.2} - Rd{2.2} + Rd{3.1}); + } + + SECTION("TinyVector<2>(std::vector<TinyVector<2>>) BuiltinFunctionEmbedder") + { + using Rd = TinyVector<2>; + std::function sum = [&](const std::vector<Rd>& x) -> Rd { + Rd s = zero; + for (size_t i = 0; i < x.size(); ++i) { + s += x[i]; + } + return s; + }; + + std::unique_ptr<IBuiltinFunctionEmbedder> i_embedded_c = + std::make_unique<BuiltinFunctionEmbedder<Rd(const std::vector<Rd>&)>>(sum); + + REQUIRE(i_embedded_c->numberOfParameters() == 1); + REQUIRE(i_embedded_c->getParameterDataTypes().size() == 1); + REQUIRE(i_embedded_c->getParameterDataTypes()[0] == ASTNodeDataType::tuple_t); + REQUIRE(i_embedded_c->getReturnDataType() == ast_node_data_type_from<Rd>); + + REQUIRE(std::get<Rd>(i_embedded_c->apply({std::vector<Rd>{Rd{1.2, 1}, Rd{-2.2, 0.7}, Rd{3.1, 1.2}}})) == + Rd{1.2, 1} + Rd{-2.2, 0.7} + Rd{3.1, 1.2}); + } + + SECTION("TinyVector<3>(std::vector<TinyVector<3>>) BuiltinFunctionEmbedder") + { + using Rd = TinyVector<3>; + std::function sum = [&](const std::vector<Rd>& x) -> Rd { + Rd s = zero; + for (size_t i = 0; i < x.size(); ++i) { + s += x[i]; + } + return s; + }; + + std::unique_ptr<IBuiltinFunctionEmbedder> i_embedded_c = + std::make_unique<BuiltinFunctionEmbedder<Rd(const std::vector<Rd>&)>>(sum); + + REQUIRE(i_embedded_c->numberOfParameters() == 1); + REQUIRE(i_embedded_c->getParameterDataTypes().size() == 1); + REQUIRE(i_embedded_c->getParameterDataTypes()[0] == ASTNodeDataType::tuple_t); + REQUIRE(i_embedded_c->getReturnDataType() == ast_node_data_type_from<Rd>); + + REQUIRE( + std::get<Rd>(i_embedded_c->apply({std::vector<Rd>{Rd{1.2, 1, -2}, Rd{-2.2, 0.7, 0.6}, Rd{3.1, 1.2, 2.1}}})) == + Rd{1.2, 1, -2} + Rd{-2.2, 0.7, 0.6} + Rd{3.1, 1.2, 2.1}); + } + + SECTION("TinyMatrix<1>(std::vector<TinyMatrix<1>>) BuiltinFunctionEmbedder") + { + using Rdxd = TinyMatrix<1>; + std::function sum = [&](const std::vector<Rdxd>& x) -> Rdxd { + Rdxd s = zero; + for (size_t i = 0; i < x.size(); ++i) { + s += x[i]; + } + return s; + }; + + std::unique_ptr<IBuiltinFunctionEmbedder> i_embedded_c = + std::make_unique<BuiltinFunctionEmbedder<Rdxd(const std::vector<Rdxd>&)>>(sum); + + REQUIRE(i_embedded_c->numberOfParameters() == 1); + REQUIRE(i_embedded_c->getParameterDataTypes().size() == 1); + REQUIRE(i_embedded_c->getParameterDataTypes()[0] == ASTNodeDataType::tuple_t); + REQUIRE(i_embedded_c->getReturnDataType() == ast_node_data_type_from<Rdxd>); + + REQUIRE(std::get<Rdxd>(i_embedded_c->apply({std::vector<Rdxd>{Rdxd{1.2}, Rdxd{-2.2}, Rdxd{3.1}}})) == + Rdxd{1.2} - Rdxd{2.2} + Rdxd{3.1}); + } + + SECTION("TinyMatrix<2>(std::vector<TinyMatrix<2>>) BuiltinFunctionEmbedder") + { + using Rdxd = TinyMatrix<2>; + std::function sum = [&](const std::vector<Rdxd>& x) -> Rdxd { + Rdxd s = zero; + for (size_t i = 0; i < x.size(); ++i) { + s += x[i]; + } + return s; + }; + + std::unique_ptr<IBuiltinFunctionEmbedder> i_embedded_c = + std::make_unique<BuiltinFunctionEmbedder<Rdxd(const std::vector<Rdxd>&)>>(sum); + + REQUIRE(i_embedded_c->numberOfParameters() == 1); + REQUIRE(i_embedded_c->getParameterDataTypes().size() == 1); + REQUIRE(i_embedded_c->getParameterDataTypes()[0] == ASTNodeDataType::tuple_t); + REQUIRE(i_embedded_c->getReturnDataType() == ast_node_data_type_from<Rdxd>); + + REQUIRE(std::get<Rdxd>(i_embedded_c->apply( + {std::vector<Rdxd>{Rdxd{1.2, 1, -1, 3}, Rdxd{-2.2, 3, -2, 6}, Rdxd{3.1, 2, -1, 3}}})) == + Rdxd{1.2, 1, -1, 3} + Rdxd{-2.2, 3, -2, 6} + Rdxd{3.1, 2, -1, 3}); + } + + SECTION("TinyMatrix<3>(std::vector<TinyMatrix<3>>) BuiltinFunctionEmbedder") + { + using Rdxd = TinyMatrix<3>; + std::function sum = [&](const std::vector<Rdxd>& x) -> Rdxd { + Rdxd s = zero; + for (size_t i = 0; i < x.size(); ++i) { + s += x[i]; + } + return s; + }; + + std::unique_ptr<IBuiltinFunctionEmbedder> i_embedded_c = + std::make_unique<BuiltinFunctionEmbedder<Rdxd(const std::vector<Rdxd>&)>>(sum); + + REQUIRE(i_embedded_c->numberOfParameters() == 1); + REQUIRE(i_embedded_c->getParameterDataTypes().size() == 1); + REQUIRE(i_embedded_c->getParameterDataTypes()[0] == ASTNodeDataType::tuple_t); + REQUIRE(i_embedded_c->getReturnDataType() == ast_node_data_type_from<Rdxd>); + + REQUIRE(std::get<Rdxd>(i_embedded_c->apply( + {std::vector<Rdxd>{Rdxd{1.2, 1, -1, 3, 1, 2, 5, 6, -3}, Rdxd{-2.2, 3, -2, 6, 1.2, 2, 1.3, -6, 7}, + Rdxd{3.1, 2, -1, 3, 2, 3.2, 2, 6, -7}}})) == + Rdxd{1.2, 1, -1, 3, 1, 2, 5, 6, -3} + Rdxd{-2.2, 3, -2, 6, 1.2, 2, 1.3, -6, 7} + + Rdxd{3.1, 2, -1, 3, 2, 3.2, 2, 6, -7}); + } + SECTION("uint64_t(std::vector<EmbeddedData>) BuiltinFunctionEmbedder") { std::function sum = [&](const std::vector<std::shared_ptr<const uint64_t>>& x) -> uint64_t { diff --git a/tests/test_BuiltinFunctionRegister.hpp b/tests/test_BuiltinFunctionRegister.hpp index dfc7da319..f763301a1 100644 --- a/tests/test_BuiltinFunctionRegister.hpp +++ b/tests/test_BuiltinFunctionRegister.hpp @@ -137,6 +137,33 @@ class test_BuiltinFunctionRegister std::make_pair("tuple_RtoB:(R)", std::make_shared<BuiltinFunctionEmbedder<bool(std::vector<double>)>>( [](const std::vector<double>&) -> bool { return false; }))); + m_name_builtin_function_map.insert( + std::make_pair("tuple_R1toB:(R^1)", std::make_shared<BuiltinFunctionEmbedder<bool(std::vector<TinyVector<1>>)>>( + [](const std::vector<TinyVector<1>>&) -> bool { return false; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_R2toB:(R^2)", std::make_shared<BuiltinFunctionEmbedder<bool(std::vector<TinyVector<2>>)>>( + [](const std::vector<TinyVector<2>>&) -> bool { return false; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_R3toB:(R^3)", std::make_shared<BuiltinFunctionEmbedder<bool(std::vector<TinyVector<3>>)>>( + [](const std::vector<TinyVector<3>>&) -> bool { return false; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_R11toB:(R^1x1)", + std::make_shared<BuiltinFunctionEmbedder<bool(std::vector<TinyMatrix<1>>)>>( + [](const std::vector<TinyMatrix<1>>&) -> bool { return false; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_R22toB:(R^2x2)", + std::make_shared<BuiltinFunctionEmbedder<bool(std::vector<TinyMatrix<2>>)>>( + [](const std::vector<TinyMatrix<2>>&) -> bool { return false; }))); + + m_name_builtin_function_map.insert( + std::make_pair("tuple_R33toB:(R^3x3)", + std::make_shared<BuiltinFunctionEmbedder<bool(std::vector<TinyMatrix<3>>)>>( + [](const std::vector<TinyMatrix<3>>&) -> bool { return false; }))); + m_name_builtin_function_map.insert( std::make_pair("tuple_stringtoB:(string)", std::make_shared<BuiltinFunctionEmbedder<bool(std::vector<std::string>)>>( -- GitLab