openqasm/ast/
mod.rs

1mod utils;
2pub use self::utils::*;
3
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6
7/// Represents a whole program with defintions and statements.
8/// The definitions and declarations may cover more than one file.
9#[derive(Debug, Clone)]
10#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11pub struct Program {
12    /// The declarations in this program.
13    pub decls: Vec<Span<Decl>>,
14}
15
16/// A declaration of some kind.
17#[derive(Debug, Clone)]
18#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
19pub enum Decl {
20    /// An `include` statement. These are usually resolved by the parser.
21    Include {
22        /// The file to include.
23        file: Span<Symbol>,
24    },
25    /// A quantum register declaration.
26    QReg {
27        /// The register name and size.
28        reg: Span<Reg>,
29    },
30    /// A classical register declaration.
31    CReg {
32        /// The register name and size.
33        reg: Span<Reg>,
34    },
35    /// A gate definition.
36    Def {
37        /// The gate name.
38        name: Span<Symbol>,
39        /// The names of parameters to take.
40        params: Vec<Span<Symbol>>,
41        /// The names of the arguments to take.
42        args: Vec<Span<Symbol>>,
43        /// The content of the definition.
44        /// A value of `None` represents an opaque gate definition.
45        body: Option<Vec<Span<Stmt>>>,
46    },
47    /// A top-level statement.
48    Stmt(Span<Stmt>),
49}
50
51/// A statement that represents an action.
52#[derive(Debug, Clone)]
53#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
54pub enum Stmt {
55    /// Apply a universal single-qubit unitary to a register.
56    U {
57        theta: Span<Expr>,
58        phi: Span<Expr>,
59        lambda: Span<Expr>,
60        reg: Span<Reg>,
61    },
62    /// Apply a CNOT gate between two registers.
63    CX { copy: Span<Reg>, xor: Span<Reg> },
64    /// Measure a quantum register and store the result in a classical one.
65    Measure { from: Span<Reg>, to: Span<Reg> },
66    /// Reset a quantum register to the |0> state.
67    Reset { reg: Span<Reg> },
68    /// Prohibit optimizations crossing this point.
69    Barrier { regs: Vec<Span<Reg>> },
70    /// Apply a defined gate to some qubits.
71    Gate {
72        name: Span<Symbol>,
73        params: Vec<Span<Expr>>,
74        args: Vec<Span<Reg>>,
75    },
76    /// Perform an action conditional on a classical register value.
77    Conditional {
78        reg: Span<Reg>,
79        val: Span<u64>,
80        then: Span<Stmt>,
81    },
82}
83
84/// A parameter expression.
85#[derive(Debug, Clone)]
86#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
87pub enum Expr {
88    /// The circle constant Pi.
89    Pi,
90    /// An arbitrary real number.
91    Real(f32),
92    /// An integer.
93    Int(u64),
94    /// A defined parameter.
95    Var(Symbol),
96    /// The addition of two expressions.
97    Add(Span<Expr>, Span<Expr>),
98    /// The subtraction of two expressions.
99    Sub(Span<Expr>, Span<Expr>),
100    /// The multiplication of two expressions.
101    Mul(Span<Expr>, Span<Expr>),
102    /// The division of two expressions.
103    Div(Span<Expr>, Span<Expr>),
104    /// The exponentiation of two expressions.
105    Pow(Span<Expr>, Span<Expr>),
106    /// The negation of an expression.
107    Neg(Span<Expr>),
108    /// The sine of an expression.
109    Sin(Span<Expr>),
110    /// The cosine of an expression.
111    Cos(Span<Expr>),
112    /// The tangent of an expression.
113    Tan(Span<Expr>),
114    /// The exponential of an expression.
115    Exp(Span<Expr>),
116    /// The natural logarithm of an expression.
117    Ln(Span<Expr>),
118    /// The square root of an expression.
119    Sqrt(Span<Expr>),
120}
121
122/// A reference to (or definition of) a register or qubit.
123#[derive(Debug, Clone)]
124#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
125pub struct Reg {
126    /// The name of the register.
127    pub name: Symbol,
128    /// The index to select if `Some` variant given,
129    /// `None` represents the whole register.
130    /// In definitions, this represents the size
131    /// of the register, and `None` means size one.
132    pub index: Option<u64>,
133}
134
135/// An object with an attached span.
136/// The span references where in the source code
137/// this object was derived from.
138#[derive(Debug, Clone)]
139#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
140pub struct Span<T> {
141    /// The span corresponding to this object.
142    pub span: FileSpan,
143    /// The actual object itself.
144    pub inner: Box<T>,
145}
146
147impl<T> std::ops::Deref for Span<T> {
148    type Target = T;
149
150    fn deref(&self) -> &T {
151        &*self.inner
152    }
153}