Commit b3fbaf96 authored by Nguyen, Thien Minh's avatar Nguyen, Thien Minh
Browse files

PyXASM converts single-quotes -> double quotes for string literals



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent c832468b
Loading
Loading
Loading
Loading
+40 −2
Original line number Diff line number Diff line
@@ -85,7 +85,14 @@ class pyxasm_visitor : public pyxasmBaseVisitor {
    if (context->atom() && !context->atom()->STRING().empty()) {
      // Strings:
      for (auto &strNode : context->atom()->STRING()) {
        std::cout << "String expression: " << strNode->getText() << "\n";
        std::string cppStrLiteral = strNode->getText();
        // Handle Python single-quotes
        if (cppStrLiteral.front() == '\'' && cppStrLiteral.back() == '\'') {
          cppStrLiteral.front() = '"';
          cppStrLiteral.back() = '"';
        }
        sub_node_translation << cppStrLiteral;
        std::cout << "String expression: " << strNode->getText() << " --> " << cppStrLiteral << "\n";
      }
      return 0;
    }
@@ -285,8 +292,39 @@ class pyxasm_visitor : public pyxasmBaseVisitor {
            // A classical call-like expression: i.e. not a kernel call:
            // Just output it *as-is* to the C++ stream.
            // We can hook more sophisticated code-gen here if required.
            std::cout << "Callable: " << context->getText() << "\n";
            std::stringstream ss;

            if (context->trailer()[0]->arglist() &&
                !context->trailer()[0]->arglist()->argument().empty()) {
              const auto &argList =
                  context->trailer()[0]->arglist()->argument();
              ss << inst_name << "(";
              for (size_t i = 0; i < argList.size(); ++i) {                
                // Find rewrite for arguments
                sub_node_translation.str(std::string());
                // visit arg sub-node:
                visitChildren(argList[i]);
                // Check if there is a rewrite:
                if (!sub_node_translation.str().empty()) {
                  const auto arg_new_str = sub_node_translation.str();
                  std::cout << argList[i]->getText() << " --> " << arg_new_str << "\n";
                  sub_node_translation.str(std::string());
                  ss << arg_new_str;
                }
                else {
                  // Use the arg as is:
                  ss << argList[i]->getText();
                }
                                
                if (i != argList.size() - 1) {
                  ss << ", ";
                }
              }
              ss << ");\n";
            } else {
              ss << context->getText() << ";\n";
            }
            result.first = ss.str();
          }
        }
+27 −0
Original line number Diff line number Diff line
@@ -102,6 +102,33 @@ auto array_val = {q[1], q[2]};
  EXPECT_EQ(expectedCodeGen, ss.str());
}

TEST(PyXASMTokenCollectorTester, checkStringLiteral) {
  LexerHelper helper;

  auto [tokens, PP] = helper.Lex(R"(
    # Cpp style strings
    print("hello", 1, "world")
    # Python style
    print('howdy', 1, 'abc')
)");

  clang::CachedTokens cached;
  for (auto &t : tokens) {
    cached.push_back(t);
  }

  std::stringstream ss;
  auto xasm_tc = xacc::getService<qcor::TokenCollector>("pyxasm");
  xasm_tc->collect(*PP.get(), cached, {"qb"}, ss);
  std::cout << "heres the test\n";
  std::cout << ss.str() << "\n";
  const std::string expectedCodeGen =
      R"#(print("hello", 1, "world");
print("howdy", 1, "abc");
)#";
  EXPECT_EQ(expectedCodeGen, ss.str());
}

int main(int argc, char **argv) {
  std::string xacc_config_install_dir = std::string(XACC_INSTALL_DIR);
  std::string qcor_root = std::string(QCOR_INSTALL_DIR);
+1 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ class TestKernelJIT(unittest.TestCase):
        @qjit
        def test_cccx_gate(q : qreg):
            for i in range(q.size()):
                print('Apply gate at', i)
                X(q[i])
            # 3 control bits
            X.ctrl([q[1], q[2], q[3]], q[0])