4 #include "IRProvider.hpp"
7 #include "xasm_singleVisitor.h"
11 std::map<std::string, std::string> common_name_map{
12 {
"CX",
"CNOT"}, {
"qcor::exp",
"exp_i_theta"}, {
"exp",
"exp_i_theta"}};
13 using xasm_single_result_type =
14 std::pair<std::string, std::shared_ptr<xacc::Instruction>>;
18 int n_cached_execs = 0;
21 xasm_single_result_type result;
23 antlrcpp::Any visitStatement(
24 xasm_singleParser::StatementContext *context)
override {
28 return visitChildren(context);
31 antlrcpp::Any visitQinst(xasm_singleParser::QinstContext *context)
override {
32 if (!xacc::isInitialized()) {
37 auto inst_name = context->inst_name->getText();
38 auto provider = xacc::getIRProvider(
"quantum");
40 if (common_name_map.count(inst_name)) {
41 inst_name = common_name_map[inst_name];
44 if (xacc::container::contains(provider->getInstructions(), inst_name)) {
50 auto inst = provider->createInstruction(inst_name, 0);
54 if (!inst->isComposite()) {
56 auto required_bits = inst->nRequiredBits();
57 auto required_params = inst->getParameters().size();
59 if (required_bits + required_params !=
60 context->explist()->exp().size() &&
61 inst_name !=
"Measure") {
63 xx <<
"Invalid quantum instruction expression. " << inst_name
64 <<
" requires " << required_bits <<
" qubit args and "
65 << required_params <<
" parameter args.";
66 xacc::error(xx.str());
70 std::vector<std::string> buffer_names;
72 for (
int i = 0; i < required_bits; i++) {
73 auto bit_expr = context->explist()->exp(i);
74 auto bit_expr_str = bit_expr->getText();
76 auto found_bracket = bit_expr_str.find_first_of(
"[");
77 if (found_bracket != std::string::npos) {
78 auto buffer_name = bit_expr_str.substr(0, found_bracket);
79 auto bit_idx_expr = bit_expr_str.substr(
80 found_bracket + 1, bit_expr_str.length() - found_bracket - 2);
82 buffer_names.push_back(buffer_name);
83 inst->setBitExpression(i, bit_idx_expr);
86 inst->setBitExpression(-1*count, bit_expr_str);
87 buffer_names.push_back(bit_expr_str);
92 inst->setBufferNames(buffer_names);
96 for (
int i = required_bits; i < context->explist()->exp().size(); i++) {
97 inst->setParameter(counter, context->explist()->exp(i)->getText());
103 if (xacc::container::contains(quantum::kernels_in_translation_unit,
104 context->inst_name->getText())) {
108 std::stringstream ss;
109 for (
auto c : context->children) {
110 if (c->getText() ==
"(") {
111 ss << c->getText() <<
"parent_kernel, ";
114 ss << c->getText() <<
" ";
118 result.first = ss.str() +
"\n";
122 auto comp_inst = xacc::ir::asComposite(inst);
123 inst->setBufferNames({context->explist()->exp(0)->getText()});
124 for (
int i = 1; i < context->explist()->exp().size(); i++) {
125 comp_inst->addArgument(context->explist()->exp(i)->getText(),
"");
130 result.second = inst;
132 std::stringstream ss;
134 if (xacc::container::contains(quantum::kernels_in_translation_unit,
135 context->inst_name->getText())) {
140 for (
auto c : context->children) {
141 if (c->getText() ==
"(") {
142 ss << c->getText() <<
"parent_kernel, ";
144 }
else if (c->getText().find(
"qalloc") != std::string::npos) {
147 std::string arg_str = c->getText();
148 const std::string qalloc_name =
"qalloc";
149 auto qalloc_pos = arg_str.find(qalloc_name);
151 while (qalloc_pos != std::string::npos) {
154 std::stack<char> balance_matcher;
155 const auto open_pos =
156 arg_str.find_first_of(
"(", qalloc_pos);
157 if (open_pos == std::string::npos) {
158 xacc::error(
"Invalid Syntax: " + c->getText());
160 for (
int i = open_pos; i < arg_str.size(); ++i) {
161 if (arg_str[i] ==
'(') {
162 balance_matcher.push(
'(');
164 if (arg_str[i] ==
')') {
165 balance_matcher.pop();
168 if (balance_matcher.empty()) {
169 arg_str.insert(i,
", quantum::getAncillaQubitAllocator()");
174 if (!balance_matcher.empty()) {
175 xacc::error(
"Invalid Syntax: " + c->getText());
179 qalloc_pos = arg_str.find(qalloc_name, qalloc_pos + qalloc_name.size());
184 ss << c->getText() <<
" ";
188 for (
auto c : context->children) {
189 ss << c->getText() <<
" ";
192 result.first = ss.str() +
"\n";
199 antlrcpp::Any visitCinst(xasm_singleParser::CinstContext *context)
override {
203 std::stringstream ss;
205 if (context->getText().find(
"::adjoint") != std::string::npos) {
206 for (
auto c : context->children) {
207 if (c->getText() ==
"(") {
208 ss << c->getText() <<
"parent_kernel, ";
211 ss << c->getText() <<
" ";
214 }
else if (context->getText().find(
"::ctrl") != std::string::npos ||
215 context->getText().find(
".ctrl") != std::string::npos) {
216 for (
auto c : context->children) {
217 if (c->getText() ==
"(") {
218 ss << c->getText() <<
"parent_kernel, ";
221 ss << c->getText() <<
" ";
224 }
else if (context->getText().find(
"Measure") != std::string::npos) {
229 const auto replaceAll = [](std::string &s,
const std::string &search,
230 const std::string &replace) {
231 for (
size_t pos = 0;; pos += replace.length()) {
232 pos = s.find(search, pos);
233 if (pos == std::string::npos) {
236 if ((s.size() > pos + search.size()) &&
241 (!isspace(s[pos + search.length()]) &&
242 (s[pos + search.length()] !=
'('))) {
245 s.erase(pos, search.length());
246 s.insert(pos, replace);
249 for (
auto c : context->children) {
250 auto origText = c->getText();
251 replaceAll(origText,
"Measure",
" quantum::mz");
252 ss << origText <<
" ";
255 if (context->var_value &&
256 context->var_value->getText().find(
"qalloc") != std::string::npos) {
258 std::stringstream qalloc_ss;
259 for (
auto c : context->children) {
260 qalloc_ss << c->getText() <<
" ";
262 std::string qalloc_call = qalloc_ss.str();
264 const auto close_pos = qalloc_call.find_last_of(
")");
265 qalloc_call.insert(close_pos,
", quantum::getAncillaQubitAllocator()");
269 for (
auto c : context->children) {
270 ss << c->getText() <<
" ";
275 result.first = ss.str() +
"\n";
279 antlrcpp::Any visitLine(xasm_singleParser::LineContext *context)
override {
283 antlrcpp::Any visitComment(
284 xasm_singleParser::CommentContext *context)
override {
287 antlrcpp::Any visitCompare(
288 xasm_singleParser::CompareContext *context)
override {
292 antlrcpp::Any visitCpp_type(
293 xasm_singleParser::Cpp_typeContext *context)
override {
297 antlrcpp::Any visitExplist(
298 xasm_singleParser::ExplistContext *context)
override {
302 antlrcpp::Any visitExp(xasm_singleParser::ExpContext *context)
override {
306 antlrcpp::Any visitUnaryop(
307 xasm_singleParser::UnaryopContext *context)
override {
311 antlrcpp::Any visitId(xasm_singleParser::IdContext *context)
override {
315 antlrcpp::Any visitReal(xasm_singleParser::RealContext *context)
override {
319 antlrcpp::Any visitString(
320 xasm_singleParser::StringContext *context)
override {