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

Add braces to rewritten if block



Looking into ways to parse else blocks since it looks like the Python syntax expect to see the whole if-else block in one pass rather than line by line.

Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent 95d7fbd2
Loading
Loading
Loading
Loading
+22 −20
Original line number Diff line number Diff line
@@ -98,28 +98,30 @@ void PyXasmTokenCollector::collect(clang::Preprocessor &PP,

  int previous_col = lines[0].second;
  int line_counter = 0;
  // Tracking the scope of for loops by their indent
  std::stack<int> for_loop_indent;
  // Tracking the Python scopes by the indent of code blocks
  std::stack<int> scope_block_indent;
  for (const auto &line : lines) {
    std::cout << "processing line " << line_counter << " of " << lines.size()
              << ": " << line.first << ", " << line.second << std::boolalpha
              << ", " << !for_loop_indent.empty() << "\n";
    // std::cout << "processing line " << line_counter << " of " << lines.size()
    //           << ": " << line.first << ", " << line.second << std::boolalpha
    //           << ", " << !scope_block_indent.empty() << "\n";

    pyxasm_visitor visitor(bufferNames);
    // Should we close a 'for' scope after this statement
    // Should we close a 'for'/'if' scope after this statement
    // If > 0, indicate the number of for blocks to be closed.
    int close_for_scopes = 0;
    int nb_closing_scopes = 0;
    // If the stack is not empty and this line changed column to an outside
    // scope:
    while (!for_loop_indent.empty() && line.second < for_loop_indent.top()) {
    while (!scope_block_indent.empty() &&
           line.second < scope_block_indent.top()) {
      // Pop the stack and flag to close the scope afterward
      for_loop_indent.pop();
      close_for_scopes++;
      scope_block_indent.pop();
      nb_closing_scopes++;
    }

    // Enter a new for loop -> push to the stack
    if (line.first.find("for ") != std::string::npos) {
      for_loop_indent.push(line.second);
    // Enter a new for scope block (for/if/etc.) -> push to the stack
    if (line.first.find("for ") != std::string::npos ||
        line.first.find("if ") != std::string::npos) {
      scope_block_indent.push(line.second);
    }

    // is_in_for_loop = line.first.find("for ") != std::string::npos &&
@@ -147,20 +149,20 @@ void PyXasmTokenCollector::collect(clang::Preprocessor &PP,
      ss << visitor.result.first;
    }

    if (close_for_scopes > 0) {
      // std::cout << "Close " << close_for_scopes << " for scopes.\n";
    if (nb_closing_scopes > 0) {
      // std::cout << "Close " << nb_closing_scopes << " for scopes.\n";
      // need to close out the c++ or loop
      for (int i = 0; i < close_for_scopes; ++i) {
      for (int i = 0; i < nb_closing_scopes; ++i) {
        ss << "}\n";
      }
    }
    previous_col = line.second;
    line_counter++;
  }
  // If there are open for scope blocks here,
  // i.e. for loops at the end of the function body.
  while (!for_loop_indent.empty()) {
    for_loop_indent.pop();
  // If there are open scope blocks here,
  // e.g. for loops at the end of the function body.
  while (!scope_block_indent.empty()) {
    scope_block_indent.pop();
    ss << "}\n";
  }
}
+2 −2
Original line number Diff line number Diff line
@@ -288,7 +288,7 @@ class pyxasm_visitor : public pyxasmBaseVisitor {
        replaceMeasureInst(ifConditionExpr, "Measure", "quantum::mz");
      }

      ss << "if (" << ifConditionExpr << ")\n";
      ss << "if (" << ifConditionExpr << ") {\n";
      result.first = ss.str();
      return 0;
    }
+33 −0
Original line number Diff line number Diff line
@@ -40,6 +40,39 @@ quantum::mz(qb[i]);
            ss.str());
}

TEST(PyXASMTokenCollectorTester, checkIf) {
  LexerHelper helper;

  auto [tokens, PP] = helper.Lex(R"(
    H(qb[0])
    CX(qb[0],qb[1])
    for i in range(qb.size()):
      if Measure(qb[i]):
        X(qb[i])
)");

  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"#(quantum::h(qb[0]);
quantum::cnot(qb[0], qb[1]);
for (auto &i : range(qb.size())) {
if (quantum::mz(qb[i])) {
quantum::x(qb[i]);
}
}
)#";
  EXPECT_EQ(expectedCodeGen, ss.str());
}

int main(int argc, char **argv) {
  xacc::Initialize();
  ::testing::InitGoogleTest(&argc, argv);