1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// This code is part of Cqlib.
//
// (C) Copyright China Telecom Quantum Group 2026
//
// This code is licensed under the Apache License, Version 2.0. You may
// obtain a copy of this license in the LICENSE.txt file in the root directory
// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
//
// Any modifications or derivative works of this code must retain this
// copyright notice, and modified files need to carry a notice indicating
// that they have been altered from the originals.
//! # OpenQASM 2.0
//!
//! This module loads and dumps the OpenQASM 2.0 circuit subset that can be
//! represented by Cqlib's [`Circuit`](crate::circuit::Circuit) IR.
//!
//! Loading supports registers, measurements, resets, barriers, standard gates,
//! user `gate` definitions, `opaque` declarations, external includes, and the
//! OpenQASM 2.0 conditional form `if (creg == integer) qop;`.
//! `include "qelib1.inc";` is handled as a built-in special include: Cqlib
//! registers qelib1 gate names internally and does not require a local
//! `qelib1.inc` file. For compatibility, qelib1 gates are available even when
//! the include is omitted, and those names cannot be redefined.
//!
//! The loader intentionally accepts a few expression extensions used by
//! existing Cqlib inputs: scientific notation without a decimal point
//! (`1e-5`) and the unary functions `asin`, `acos`, and `atan`. Gate
//! definitions are collected before operations are generated, so forward
//! references to gates declared later in the source are accepted.
//!
//! Dumping emits normalized OpenQASM 2.0 with `include "qelib1.inc";`, `qreg`
//! and `creg` declarations, generated gate definitions, and operations. It
//! rejects features that OpenQASM 2.0 cannot represent losslessly, including
//! else branches, loops, switches, nested control flow, general classical
//! assignment, conditional barriers, and indexed-bit conditions such as
//! `if (c[0] == 1)`.
//!
//! ## Entry Points and Errors
//!
//! - [`load::load`] / [`load::from_path`] reads an OpenQASM 2.0 file and
//! returns [`load::QasmParseError`] on failure.
//! - [`load::loads`] / [`load::from_str`] reads OpenQASM 2.0 source from a
//! string and returns [`load::QasmParseError`] on failure.
//! - [`dump::dump`] / [`dump::to_path`] writes a circuit to an OpenQASM 2.0 file
//! and returns [`dump::QasmDumpError`] on failure.
//! - [`dump::dumps`] / [`dump::to_string`] serializes a circuit to an OpenQASM
//! 2.0 string and returns [`dump::QasmDumpError`] on failure.
//!
//! ## Load Example
//!
//! ```rust
//! use cqlib_core::ir::qasm2::load::loads;
//!
//! let qasm = r#"
//! OPENQASM 2.0;
//! include "qelib1.inc";
//! qreg q[2];
//! creg c[1];
//! h q[0];
//! cx q[0], q[1];
//! measure q[0] -> c[0];
//! "#;
//!
//! let circuit = loads(qasm).unwrap();
//! assert_eq!(circuit.num_qubits(), 2);
//! ```
//!
//! ## Dump Example
//!
//! ```rust
//! use cqlib_core::ir::qasm2::dump::dumps;
//! use cqlib_core::circuit::Circuit;
//! use cqlib_core::circuit::Qubit;
//!
//! let mut circuit = Circuit::new(2);
//! circuit.h(Qubit::new(0)).unwrap();
//! circuit.cx(Qubit::new(0), Qubit::new(1)).unwrap();
//!
//! let qasm = dumps(&circuit).unwrap();
//! assert_eq!(
//! qasm,
//! concat!("// This file is auto-generated by Cqlib v", env!("CARGO_PKG_VERSION"), ".\n\
//! OPENQASM 2.0;\n\
//! include \"qelib1.inc\";\n\
//! \n\
//! qreg q[2];\n\
//! \n\
//! \n\
//! \n\
//! h q[0];\n\
//! cx q[0],q[1];\n")
//! );
//! ```
pub use ;
pub use ;