From c1967c2336e73744bf9807ed1ffe701f0911b799 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com>
Date: Thu, 24 Mar 2022 18:45:18 +0100
Subject: [PATCH] Fix tuple outputs

---
 .../BinaryExpressionProcessor.hpp             |  4 +-
 .../utils/BinaryOperatorRegisterForB.cpp      |  4 +
 .../utils/BinaryOperatorRegisterForN.cpp      |  4 +
 .../utils/BinaryOperatorRegisterForR.cpp      |  4 +
 .../utils/BinaryOperatorRegisterForRn.cpp     |  4 +
 .../utils/BinaryOperatorRegisterForRnxn.cpp   |  4 +
 .../utils/BinaryOperatorRegisterForString.cpp |  4 +
 .../utils/BinaryOperatorRegisterForZ.cpp      |  4 +
 src/language/utils/DataVariant.cpp            |  3 +
 .../test_BinaryExpressionProcessor_shift.cpp  | 78 ++++++++++++++++++-
 10 files changed, 108 insertions(+), 5 deletions(-)

diff --git a/src/language/node_processor/BinaryExpressionProcessor.hpp b/src/language/node_processor/BinaryExpressionProcessor.hpp
index 7f278d4c7..a2111464c 100644
--- a/src/language/node_processor/BinaryExpressionProcessor.hpp
+++ b/src/language/node_processor/BinaryExpressionProcessor.hpp
@@ -314,8 +314,8 @@ struct BinaryExpressionProcessor<BinaryOpT, std::shared_ptr<ValueT>, std::shared
   PUGS_INLINE DataVariant
   _eval(const DataVariant& a, const DataVariant& b)
   {
-    if constexpr ((std::is_arithmetic_v<B_DataT>) or (is_tiny_matrix_v<B_DataT>) or (is_tiny_vector_v<B_DataT>) or
-                  (std::is_same_v<std::string, B_DataT>)) {
+    if constexpr (std::is_arithmetic_v<B_DataT> or is_tiny_matrix_v<B_DataT> or is_tiny_vector_v<B_DataT> or
+                  std::is_same_v<std::string, B_DataT> or is_std_vector_v<B_DataT>) {
       const auto& embedded_a = std::get<EmbeddedData>(a);
       const auto& b_value    = std::get<B_DataT>(b);
 
diff --git a/src/language/utils/BinaryOperatorRegisterForB.cpp b/src/language/utils/BinaryOperatorRegisterForB.cpp
index dc228471d..7145ebab7 100644
--- a/src/language/utils/BinaryOperatorRegisterForB.cpp
+++ b/src/language/utils/BinaryOperatorRegisterForB.cpp
@@ -12,6 +12,10 @@ BinaryOperatorRegisterForB::_register_ostream()
   repository.addBinaryOperator<language::shift_left_op>(
     std::make_shared<BinaryOperatorProcessorBuilder<language::shift_left_op, std::shared_ptr<const OStream>,
                                                     std::shared_ptr<const OStream>, bool>>());
+
+  repository.addBinaryOperator<language::shift_left_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::shift_left_op, std::shared_ptr<const OStream>,
+                                                    std::shared_ptr<const OStream>, std::vector<bool>>>());
 }
 
 void
diff --git a/src/language/utils/BinaryOperatorRegisterForN.cpp b/src/language/utils/BinaryOperatorRegisterForN.cpp
index e32e2b53a..9d77d842e 100644
--- a/src/language/utils/BinaryOperatorRegisterForN.cpp
+++ b/src/language/utils/BinaryOperatorRegisterForN.cpp
@@ -12,6 +12,10 @@ BinaryOperatorRegisterForN::_register_ostream()
   repository.addBinaryOperator<language::shift_left_op>(
     std::make_shared<BinaryOperatorProcessorBuilder<language::shift_left_op, std::shared_ptr<const OStream>,
                                                     std::shared_ptr<const OStream>, uint64_t>>());
+
+  repository.addBinaryOperator<language::shift_left_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::shift_left_op, std::shared_ptr<const OStream>,
+                                                    std::shared_ptr<const OStream>, std::vector<uint64_t>>>());
 }
 
 void
diff --git a/src/language/utils/BinaryOperatorRegisterForR.cpp b/src/language/utils/BinaryOperatorRegisterForR.cpp
index cc8ba8a79..8f5d51275 100644
--- a/src/language/utils/BinaryOperatorRegisterForR.cpp
+++ b/src/language/utils/BinaryOperatorRegisterForR.cpp
@@ -12,6 +12,10 @@ BinaryOperatorRegisterForR::_register_ostream()
   repository.addBinaryOperator<language::shift_left_op>(
     std::make_shared<BinaryOperatorProcessorBuilder<language::shift_left_op, std::shared_ptr<const OStream>,
                                                     std::shared_ptr<const OStream>, double>>());
+
+  repository.addBinaryOperator<language::shift_left_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::shift_left_op, std::shared_ptr<const OStream>,
+                                                    std::shared_ptr<const OStream>, std::vector<double>>>());
 }
 
 void
diff --git a/src/language/utils/BinaryOperatorRegisterForRn.cpp b/src/language/utils/BinaryOperatorRegisterForRn.cpp
index 6e900d036..81e1d539d 100644
--- a/src/language/utils/BinaryOperatorRegisterForRn.cpp
+++ b/src/language/utils/BinaryOperatorRegisterForRn.cpp
@@ -16,6 +16,10 @@ BinaryOperatorRegisterForRn<Dimension>::_register_ostream()
   repository.addBinaryOperator<language::shift_left_op>(
     std::make_shared<BinaryOperatorProcessorBuilder<language::shift_left_op, std::shared_ptr<const OStream>,
                                                     std::shared_ptr<const OStream>, Rn>>());
+
+  repository.addBinaryOperator<language::shift_left_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::shift_left_op, std::shared_ptr<const OStream>,
+                                                    std::shared_ptr<const OStream>, std::vector<Rn>>>());
 }
 
 template <size_t Dimension>
diff --git a/src/language/utils/BinaryOperatorRegisterForRnxn.cpp b/src/language/utils/BinaryOperatorRegisterForRnxn.cpp
index f164203dd..4970fe434 100644
--- a/src/language/utils/BinaryOperatorRegisterForRnxn.cpp
+++ b/src/language/utils/BinaryOperatorRegisterForRnxn.cpp
@@ -16,6 +16,10 @@ BinaryOperatorRegisterForRnxn<Dimension>::_register_ostream()
   repository.addBinaryOperator<language::shift_left_op>(
     std::make_shared<BinaryOperatorProcessorBuilder<language::shift_left_op, std::shared_ptr<const OStream>,
                                                     std::shared_ptr<const OStream>, Rnxn>>());
+
+  repository.addBinaryOperator<language::shift_left_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::shift_left_op, std::shared_ptr<const OStream>,
+                                                    std::shared_ptr<const OStream>, std::vector<Rnxn>>>());
 }
 
 template <size_t Dimension>
diff --git a/src/language/utils/BinaryOperatorRegisterForString.cpp b/src/language/utils/BinaryOperatorRegisterForString.cpp
index 999950cf1..cae341bf9 100644
--- a/src/language/utils/BinaryOperatorRegisterForString.cpp
+++ b/src/language/utils/BinaryOperatorRegisterForString.cpp
@@ -14,6 +14,10 @@ BinaryOperatorRegisterForString::_register_ostream()
   repository.addBinaryOperator<language::shift_left_op>(
     std::make_shared<BinaryOperatorProcessorBuilder<language::shift_left_op, std::shared_ptr<const OStream>,
                                                     std::shared_ptr<const OStream>, std::string>>());
+
+  repository.addBinaryOperator<language::shift_left_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::shift_left_op, std::shared_ptr<const OStream>,
+                                                    std::shared_ptr<const OStream>, std::vector<std::string>>>());
 }
 
 void
diff --git a/src/language/utils/BinaryOperatorRegisterForZ.cpp b/src/language/utils/BinaryOperatorRegisterForZ.cpp
index 1d3188502..8174f3f49 100644
--- a/src/language/utils/BinaryOperatorRegisterForZ.cpp
+++ b/src/language/utils/BinaryOperatorRegisterForZ.cpp
@@ -12,6 +12,10 @@ BinaryOperatorRegisterForZ::_register_ostream()
   repository.addBinaryOperator<language::shift_left_op>(
     std::make_shared<BinaryOperatorProcessorBuilder<language::shift_left_op, std::shared_ptr<const OStream>,
                                                     std::shared_ptr<const OStream>, int64_t>>());
+
+  repository.addBinaryOperator<language::shift_left_op>(
+    std::make_shared<BinaryOperatorProcessorBuilder<language::shift_left_op, std::shared_ptr<const OStream>,
+                                                    std::shared_ptr<const OStream>, std::vector<int64_t>>>());
 }
 
 void
diff --git a/src/language/utils/DataVariant.cpp b/src/language/utils/DataVariant.cpp
index fc82eec7b..005dda6f1 100644
--- a/src/language/utils/DataVariant.cpp
+++ b/src/language/utils/DataVariant.cpp
@@ -13,6 +13,9 @@ operator<<(std::ostream& os, const DataVariant& v)
         os << "--";
       } else if constexpr (is_std_vector_v<ValueT>) {
         os << '(';
+        if constexpr (std::is_same_v<bool, typename ValueT::value_type>) {
+          os << std::boolalpha;
+        }
         if (v.size() > 0) {
           os << v[0];
         }
diff --git a/tests/test_BinaryExpressionProcessor_shift.cpp b/tests/test_BinaryExpressionProcessor_shift.cpp
index c1892a2ff..127e90161 100644
--- a/tests/test_BinaryExpressionProcessor_shift.cpp
+++ b/tests/test_BinaryExpressionProcessor_shift.cpp
@@ -6,6 +6,7 @@
 
 #include <fstream>
 #include <netdb.h>
+#include <regex>
 #include <unistd.h>
 
 // clazy:excludeall=non-pod-global-static
@@ -24,8 +25,29 @@ TEST_CASE("BinaryExpressionProcessor shift", "[language]")
       data << R"(import socket;)";
       data << "let fout:ostream, fout = ofstream(\"" << path.string() << "\");\n";
       data << R"(fout << 2 << " " << true << " " << 2 + 3 << "\n";
-fout << createSocketServer(0);)";
-
+fout << createSocketServer(0) << "\n";)";
+      data << "let b:(B), b = (true,false);\n";
+      data << "let n:(N), n = (1,3);\n";
+      data << "let z:(Z), z = (-1,3);\n";
+      data << "let r:(R), r = (2.3,4);\n";
+      data << "let u1:(R^1), u1 = (2.3,4);\n";
+      data << "let u2:(R^2), u2 = ((2.3,4), (3,2));\n";
+      data << "let u3:(R^3), u3 = ((2.3,4,-1), (3,2,1));\n";
+      data << "let A1:(R^1x1), A1 = (2.3, 4);\n";
+      data << "let A2:(R^2x2), A2 = ((2.3,4,2,0.3), (3,2.3,1,-4));\n";
+      data << "let A3:(R^3x3), A3 = ((2.3,4,-1,2,7,2.3,6,2,8), (3,2,1,1,2,5,2.1,3,-2.6));\n";
+      data << R"(let s:(string), s = ("foo", "bar");)";
+      data << R"(fout << b  << "\n";)";
+      data << R"(fout << n  << "\n";)";
+      data << R"(fout << z  << "\n";)";
+      data << R"(fout << r  << "\n";)";
+      data << R"(fout << u1 << "\n";)";
+      data << R"(fout << u2 << "\n";)";
+      data << R"(fout << u3 << "\n";)";
+      data << R"(fout << A1 << "\n";)";
+      data << R"(fout << A2 << "\n";)";
+      data << R"(fout << A3 << "\n";)";
+      data << R"(fout << s  << "\n";)";
       TAO_PEGTL_NAMESPACE::string_input input{data.str(), "test.pgs"};
       auto ast = ASTBuilder::build(input);
 
@@ -69,7 +91,9 @@ fout << createSocketServer(0);)";
 
       auto is_int = [](const std::string& s) {
         for (const char& c : s) {
-          if (not std::isdigit(c)) {
+          if (c == '\n') {
+            break;
+          } else if (not std::isdigit(c)) {
             return false;
           }
         }
@@ -79,6 +103,54 @@ fout << createSocketServer(0);)";
       REQUIRE(is_int(suffix));
     }
 
+    {
+      std::ifstream fin(filename.c_str());
+      char line[1024];
+
+      fin.getline(line, 1023);
+      REQUIRE(std::string_view(line) == "2 true 5");
+
+      char hbuf[NI_MAXHOST];
+      ::gethostname(hbuf, NI_MAXHOST);
+      std::ostringstream os;
+      os << '^' << hbuf << ":\\d+$";
+      fin.getline(line, 1023);
+      REQUIRE(std::regex_match(line, std::regex{os.str()}));
+
+      fin.getline(line, 1023);
+      REQUIRE(std::string_view(line) == "(true, false)");
+
+      fin.getline(line, 1023);
+      REQUIRE(std::string_view(line) == "(1, 3)");
+
+      fin.getline(line, 1023);
+      REQUIRE(std::string_view(line) == "(-1, 3)");
+
+      fin.getline(line, 1023);
+      REQUIRE(std::string_view(line) == "(2.3, 4)");
+
+      fin.getline(line, 1023);
+      REQUIRE(std::string_view(line) == "((2.3), (4))");
+
+      fin.getline(line, 1023);
+      REQUIRE(std::string_view(line) == "((2.3,4), (3,2))");
+
+      fin.getline(line, 1023);
+      REQUIRE(std::string_view(line) == "((2.3,4,-1), (3,2,1))");
+
+      fin.getline(line, 1023);
+      REQUIRE(std::string_view(line) == "([(2.3)], [(4)])");
+
+      fin.getline(line, 1023);
+      REQUIRE(std::string_view(line) == "([(2.3,4)(2,0.3)], [(3,2.3)(1,-4)])");
+
+      fin.getline(line, 1023);
+      REQUIRE(std::string_view(line) == "([(2.3,4,-1)(2,7,2.3)(6,2,8)], [(3,2,1)(1,2,5)(2.1,3,-2.6)])");
+
+      fin.getline(line, 1023);
+      REQUIRE(std::string_view(line) == "(foo, bar)");
+    }
+
     std::filesystem::remove(filename);
     REQUIRE(not std::filesystem::exists(filename));
   }
-- 
GitLab