Skip to main content

cqlib_core/ir/qasm2/
ast.rs

1// This code is part of Cqlib.
2//
3// (C) Copyright China Telecom Quantum Group 2026
4//
5// This code is licensed under the Apache License, Version 2.0. You may
6// obtain a copy of this license in the LICENSE.txt file in the root directory
7// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8//
9// Any modifications or derivative works of this code must retain this
10// copyright notice, and modified files need to carry a notice indicating
11// that they have been altered from the originals.
12
13//! # OpenQASM 2.0 Abstract Syntax Tree (AST)
14//!
15//! This module defines the intermediate representation (IR) for parsing OpenQASM 2.0 quantum
16//! programs. It provides data structures that represent the grammatical elements of the
17//! OpenQASM 2.0 language specification.
18//!
19//! ## Overview
20//!
21//! The AST is structured as a tree of statements that correspond to the quantum circuit
22//! description language defined in the OpenQASM 2.0 specification. Key elements include:
23//!
24//! - **Expressions**: Mathematical expressions for gate parameters (real numbers, integers,
25//!   identifiers, binary/ unary operations)
26//! - **Arguments**: Quantum/classical register references (named or indexed)
27//! - **Statements**: Quantum operations, gate declarations, classical operations
28//! - **Program**: Complete OpenQASM program containing version and statements
29//!
30//! ## Example
31//!
32//! ```rust
33//! use cqlib_core::ir::qasm2::ast::{Statement, Argument, Expression};
34//!
35//! // Represents: qreg q[2];
36//! let qreg_stmt = Statement::QReg("q".to_string(), 2);
37//!
38//! // Represents: h q[0];
39//! let h_gate = Statement::CustomGate(
40//!     "h".to_string(),
41//!     vec![],
42//!     vec![Argument::IndexedId("q".to_string(), 0)]
43//! );
44//! ```
45
46/// Represents literal values and expressions in OpenQASM 2.0.
47///
48/// This enum covers all expression types defined in the OpenQASM 2.0 specification:
49/// - Real and integer constants
50/// - Identifier references (variables/parameters)
51/// - Built-in constant `pi`
52/// - Binary operations (arithmetic)
53/// - Unary operations (trigonometric, exponential, etc.)
54#[derive(Debug, Clone, PartialEq)]
55pub enum Expression {
56    /// Real number literal (e.g., `3.14159`, `0.5`)
57    Real(f64),
58    /// Integer literal (e.g., `1`, `2`, `-3`)
59    Integer(i64),
60    /// Identifier reference (parameter name or variable)
61    Id(String),
62    /// Built-in constant pi (π ≈ 3.14159...)
63    Pi,
64    /// Binary operation (e.g., `a + b`, `x * 2`, `pi/2`)
65    BinaryOp(Box<Expression>, OpCode, Box<Expression>),
66    /// Unary operation (e.g., `sin(theta)`, `sqrt(x)`, `-y`)
67    UnaryOp(UnaryOpCode, Box<Expression>),
68}
69
70/// Binary arithmetic operators supported in OpenQASM 2.0 expressions.
71///
72/// These operators follow standard precedence rules and are used within
73/// gate parameter expressions.
74#[derive(Debug, Clone, PartialEq)]
75pub enum OpCode {
76    /// Addition operator (`+`)
77    Add,
78    /// Subtraction operator (`-`)
79    Sub,
80    /// Multiplication operator (`*`)
81    Mul,
82    /// Division operator (`/`)
83    Div,
84    /// Power/exponentiation operator (`^`)
85    Pow,
86}
87
88/// Unary operators (functions) supported in OpenQASM 2.0 expressions.
89///
90/// These include trigonometric functions, exponential/logarithmic functions,
91/// and the negation operator.
92#[derive(Debug, Clone, PartialEq)]
93pub enum UnaryOpCode {
94    /// Sine function: `sin(x)`
95    Sin,
96    /// Cosine function: `cos(x)`
97    Cos,
98    /// Tangent function: `tan(x)`
99    Tan,
100    /// Exponential function: `exp(x)`
101    Exp,
102    /// Natural logarithm: `ln(x)`
103    Ln,
104    /// Square root: `sqrt(x)`
105    Sqrt,
106    /// Arcsine: `asin(x)`
107    Asin,
108    /// Arccosine: `acos(x)`
109    Acos,
110    /// Arctangent: `atan(x)`
111    Atan,
112    /// Negation operator: `-x`
113    Neg,
114}
115
116/// Represents a quantum or classical register argument.
117///
118/// Arguments can be either:
119/// - Named references (entire register): `q` refers to all qubits in register `q`
120/// - Indexed references (single element): `q[0]` refers to the first qubit in register `q`
121#[derive(Debug, Clone, PartialEq)]
122pub enum Argument {
123    /// Named register reference (e.g., `q` in `h q`)
124    Id(String),
125    /// Indexed register reference (e.g., `q[0]` in `cx q[0], q[1]`)
126    IndexedId(String, i64),
127}
128
129/// Top-level statements in an OpenQASM 2.0 program.
130///
131/// Each variant represents a distinct type of statement as defined in the
132/// OpenQASM 2.0 specification, including declarations, quantum operations,
133/// gate definitions, and control flow.
134#[derive(Debug, Clone, PartialEq)]
135pub enum Statement {
136    /// Quantum register declaration: `qreg q[5];`
137    QReg(String, i64),
138    /// Classical register declaration: `creg c[3];`
139    CReg(String, i64),
140    /// Include external file: `include "qelib1.inc";`
141    Include(String),
142    /// Barrier operation: `barrier q[0], q[1];`
143    Barrier(Vec<Argument>),
144    /// Reset operation: `reset q[0];`
145    Reset(Argument),
146    /// Measurement: `measure q[0] -> c[0];`
147    Measure(Argument, Argument),
148    /// Custom gate invocation: `gate_name(params) qubits;`
149    CustomGate(String, Vec<Expression>, Vec<Argument>),
150    /// Opaque gate declaration (no body): `opaque gate_name q;`
151    Opaque(String, Vec<String>, Vec<String>),
152    /// Gate definition with body: `gate gate_name(params) q { ... }`
153    GateDecl(Box<GateDeclData>),
154    /// Conditional execution: `if (c == 1) gate q;`.
155    If(String, i64, Box<Statement>),
156}
157
158/// Data structure holding gate definition content.
159///
160/// This represents the complete gate declaration including:
161/// - Gate name
162/// - Formal parameters (may be empty)
163/// - Formal qubits (the qubits the gate operates on)
164/// - Gate body (sequence of statements)
165#[derive(Debug, Clone, PartialEq)]
166pub struct GateDeclData {
167    /// Name of the gate being defined
168    pub name: String,
169    /// List of parameter names (empty if gate takes no parameters)
170    pub params: Vec<String>,
171    /// List of qubit argument names (the qubits the gate operates on)
172    pub qubits: Vec<String>,
173    /// Gate body: sequence of quantum operations making up the gate
174    pub body: Vec<Statement>,
175}
176
177/// Represents a complete OpenQASM 2.0 program.
178///
179/// This is the root structure containing the version number and
180/// all top-level statements in the program.
181#[derive(Debug, Clone)]
182pub struct OpenQASMProgram {
183    /// OpenQASM version (typically 2.0)
184    pub version: f64,
185    /// List of top-level statements in program order
186    pub statements: Vec<Statement>,
187}