1 /*
2  * This file is part of qasmtools.
3  *
4  * Copyright (c) 2019 - 2021 softwareQ Inc. All rights reserved.
5  *
6  * MIT License
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  */
26 
27 /**
28  * \file qasmtools/ast/traversal.hpp
29  * \brief Node traversal for syntax trees
30  */
31 
32 #pragma once
33 
34 #include "program.hpp"
35 #include "visitor.hpp"
36 
37 namespace qasmtools {
38 namespace ast {
39 
40 /**
41  * \class qasmtools::ast::Traverse
42  * \brief Generic complete traversal of ASTs
43  * \see qasmtools::ast::Visitor
44  *
45  * Implements a generic, pass-through traversal of the entire
46  * AST. Standard usage is to derive from this class and override only
47  * the nodes desired.
48  *
49  * Note that overriding a node kills traversal to
50  * children of that node. This can be useful for cutting off traversal
51  * to certain subtrees. Traversal logic can be accessed through the
52  * parent class, e.g. by calling Traverse::visit. In this way, the
53  * Traverse class can be used to implement post-order, pre-order, or
54  * mixed pre/post algorithms by directly calling the traversal logic.
55  */
56 class Traverse : public Visitor {
57   public:
visit(VarAccess & var)58     void visit(VarAccess& var) override {}
visit(BExpr & expr)59     void visit(BExpr& expr) override {
60         expr.lexp().accept(*this);
61         expr.rexp().accept(*this);
62     }
visit(UExpr & expr)63     void visit(UExpr& expr) override { expr.subexp().accept(*this); }
visit(PiExpr & expr)64     void visit(PiExpr& expr) override {}
visit(IntExpr & expr)65     void visit(IntExpr& expr) override {}
visit(RealExpr & expr)66     void visit(RealExpr& expr) override {}
visit(VarExpr & expr)67     void visit(VarExpr& expr) override {}
visit(MeasureStmt & stmt)68     void visit(MeasureStmt& stmt) override {
69         stmt.q_arg().accept(*this);
70         stmt.c_arg().accept(*this);
71     }
visit(ResetStmt & stmt)72     void visit(ResetStmt& stmt) override { stmt.arg().accept(*this); }
visit(IfStmt & stmt)73     void visit(IfStmt& stmt) override { stmt.then().accept(*this); }
visit(UGate & gate)74     void visit(UGate& gate) override {
75         gate.theta().accept(*this);
76         gate.phi().accept(*this);
77         gate.lambda().accept(*this);
78         gate.arg().accept(*this);
79     }
visit(CNOTGate & gate)80     void visit(CNOTGate& gate) override {
81         gate.ctrl().accept(*this);
82         gate.tgt().accept(*this);
83     }
visit(BarrierGate & gate)84     void visit(BarrierGate& gate) override {
85         for (int i = 0; i < gate.num_args(); i++)
86             gate.arg(i).accept(*this);
87     }
visit(DeclaredGate & gate)88     void visit(DeclaredGate& gate) override {
89         for (int i = 0; i < gate.num_cargs(); i++)
90             gate.carg(i).accept(*this);
91         for (int i = 0; i < gate.num_qargs(); i++)
92             gate.qarg(i).accept(*this);
93     }
94 
visit(GateDecl & decl)95     void visit(GateDecl& decl) override {
96         for (auto it = decl.begin(); it != decl.end(); it++)
97             (**it).accept(*this);
98     }
99 
visit(OracleDecl & decl)100     void visit(OracleDecl& decl) override {}
visit(RegisterDecl & decl)101     void visit(RegisterDecl& decl) override {}
visit(AncillaDecl & decl)102     void visit(AncillaDecl& decl) override {}
visit(Program & prog)103     void visit(Program& prog) override {
104         for (auto it = prog.begin(); it != prog.end(); it++)
105             (**it).accept(*this);
106     }
107 };
108 
109 } // namespace ast
110 } // namespace qasmtools
111