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}