Skip to main content

quil/instruction/
declaration.rs

1use quil_rs::instruction::{
2    ArithmeticOperand, Declaration, Load, MemoryReference, Offset, ScalarType, Sharing, Store,
3    Vector,
4};
5
6use super::PyArithmeticOperand;
7use crate::{impl_copy_for_instruction, impl_eq, impl_pickle_for_instruction, impl_to_quil};
8
9use rigetti_pyo3::{
10    impl_from_str, impl_hash, impl_parse, impl_repr, py_wrap_data_struct, py_wrap_error,
11    py_wrap_simple_enum,
12    pyo3::{
13        exceptions::PyValueError,
14        pymethods,
15        types::{PyInt, PyString},
16        Py, PyResult, Python,
17    },
18    wrap_error, PyTryFrom,
19};
20
21wrap_error!(RustParseMemoryReferenceError(quil_rs::program::SyntaxError<MemoryReference>));
22py_wrap_error!(
23    quil,
24    RustParseMemoryReferenceError,
25    ParseMemoryReferenceError,
26    PyValueError
27);
28
29py_wrap_simple_enum! {
30    PyScalarType(ScalarType) as "ScalarType" {
31        Bit,
32        Integer,
33        Octet,
34        Real
35    }
36}
37impl_repr!(PyScalarType);
38impl_to_quil!(PyScalarType);
39impl_hash!(PyScalarType);
40
41impl rigetti_pyo3::PyTryFrom<pyo3::PyAny> for PyScalarType {
42    fn py_try_from(_py: Python, item: &pyo3::PyAny) -> PyResult<Self> {
43        let item = item.extract::<String>()?;
44        match item.as_str() {
45            "BIT" => Ok(Self::Bit),
46            "INTEGER" => Ok(Self::Integer),
47            "OCTET" => Ok(Self::Octet),
48            "REAL" => Ok(Self::Real),
49            _ => Err(PyValueError::new_err(format!(
50                "Invalid value for ScalarType: {item}"
51            ))),
52        }
53    }
54}
55
56py_wrap_data_struct! {
57    #[derive(Debug, Hash, PartialEq, Eq)]
58    #[pyo3(subclass)]
59    PyVector(Vector) as "Vector" {
60        data_type: ScalarType => PyScalarType,
61        length: u64 => Py<PyInt>
62    }
63}
64impl_repr!(PyVector);
65impl_to_quil!(PyVector);
66impl_hash!(PyVector);
67impl_eq!(PyVector);
68
69#[pymethods]
70impl PyVector {
71    #[new]
72    pub fn new(py: Python<'_>, data_type: PyScalarType, length: u64) -> PyResult<Self> {
73        Ok(Self(Vector::new(
74            ScalarType::py_try_from(py, &data_type)?,
75            length,
76        )))
77    }
78}
79
80py_wrap_data_struct! {
81    #[derive(Debug, PartialEq, Eq, Hash)]
82    #[pyo3(subclass)]
83    PyOffset(Offset) as "Offset" {
84        offset: u64 => Py<PyInt>,
85        data_type: ScalarType => PyScalarType
86    }
87}
88impl_repr!(PyOffset);
89impl_to_quil!(PyOffset);
90impl_hash!(PyOffset);
91impl_eq!(PyOffset);
92
93#[pymethods]
94impl PyOffset {
95    #[new]
96    pub fn new(py: Python<'_>, offset: u64, data_type: PyScalarType) -> PyResult<Self> {
97        Ok(Self(Offset::new(
98            offset,
99            ScalarType::py_try_from(py, &data_type)?,
100        )))
101    }
102}
103
104py_wrap_data_struct! {
105    #[derive(Debug, PartialEq, Eq, Hash)]
106    #[pyo3(subclass)]
107    PySharing(Sharing) as "Sharing" {
108        name: String => Py<PyString>,
109        offsets: Vec<Offset> => Vec<PyOffset>
110    }
111}
112impl_repr!(PySharing);
113impl_hash!(PySharing);
114impl_eq!(PySharing);
115
116#[pymethods]
117impl PySharing {
118    #[new]
119    pub fn new(py: Python<'_>, name: String, offsets: Vec<PyOffset>) -> PyResult<Self> {
120        Ok(Self(Sharing::new(
121            name,
122            Vec::<Offset>::py_try_from(py, &offsets)?,
123        )))
124    }
125}
126
127py_wrap_data_struct! {
128    #[derive(Debug, PartialEq, Eq)]
129    #[pyo3(subclass, module = "quil.instructions")]
130    PyDeclaration(Declaration) as "Declaration" {
131        name: String => Py<PyString>,
132        size: Vector => PyVector,
133        sharing: Option<Sharing> => Option<PySharing>
134    }
135}
136impl_repr!(PyDeclaration);
137impl_to_quil!(PyDeclaration);
138impl_copy_for_instruction!(PyDeclaration);
139impl_hash!(PyDeclaration);
140impl_eq!(PyDeclaration);
141impl_pickle_for_instruction!(PyDeclaration);
142
143#[pymethods]
144impl PyDeclaration {
145    #[new]
146    pub fn new(
147        py: Python<'_>,
148        name: String,
149        size: PyVector,
150        sharing: Option<PySharing>,
151    ) -> PyResult<Self> {
152        Ok(Self(Declaration::new(
153            name,
154            Vector::py_try_from(py, &size)?,
155            Option::<Sharing>::py_try_from(py, &sharing)?,
156        )))
157    }
158}
159
160py_wrap_data_struct! {
161    #[derive(Debug, Hash, PartialEq)]
162    #[pyo3(subclass)]
163    PyMemoryReference(MemoryReference) as "MemoryReference" {
164        name: String => Py<PyString>,
165        index: u64 => Py<PyInt>
166    }
167}
168impl_hash!(PyMemoryReference);
169impl_repr!(PyMemoryReference);
170impl_to_quil!(PyMemoryReference);
171impl_from_str!(PyMemoryReference, RustParseMemoryReferenceError);
172impl_parse!(PyMemoryReference);
173impl_eq!(PyMemoryReference);
174
175#[pymethods]
176impl PyMemoryReference {
177    #[new]
178    pub fn new(name: String, index: u64) -> Self {
179        Self(MemoryReference::new(name, index))
180    }
181}
182
183py_wrap_data_struct! {
184    #[derive(Debug, PartialEq, Eq)]
185    #[pyo3(subclass, module = "quil.instructions")]
186    PyLoad(Load) as "Load" {
187        destination: MemoryReference => PyMemoryReference,
188        source: String => Py<PyString>,
189        offset: MemoryReference => PyMemoryReference
190    }
191}
192impl_repr!(PyLoad);
193impl_to_quil!(PyLoad);
194impl_copy_for_instruction!(PyLoad);
195impl_hash!(PyLoad);
196impl_eq!(PyLoad);
197impl_pickle_for_instruction!(PyLoad);
198
199#[pymethods]
200impl PyLoad {
201    #[new]
202    pub fn new(
203        py: Python<'_>,
204        destination: PyMemoryReference,
205        source: String,
206        offset: PyMemoryReference,
207    ) -> PyResult<Self> {
208        Ok(Self(Load::new(
209            MemoryReference::py_try_from(py, &destination)?,
210            source,
211            MemoryReference::py_try_from(py, &offset)?,
212        )))
213    }
214}
215
216py_wrap_data_struct! {
217    #[derive(Debug, PartialEq)]
218    #[pyo3(subclass, module = "quil.instructions")]
219    PyStore(Store) as "Store" {
220        destination: String => Py<PyString>,
221        offset: MemoryReference => PyMemoryReference,
222        source: ArithmeticOperand => PyArithmeticOperand
223    }
224}
225impl_repr!(PyStore);
226impl_to_quil!(PyStore);
227impl_copy_for_instruction!(PyStore);
228impl_hash!(PyStore);
229impl_eq!(PyStore);
230impl_pickle_for_instruction!(PyStore);
231
232#[pymethods]
233impl PyStore {
234    #[new]
235    pub fn new(
236        py: Python<'_>,
237        destination: String,
238        offset: PyMemoryReference,
239        source: PyArithmeticOperand,
240    ) -> PyResult<Self> {
241        Ok(Self(Store::new(
242            destination,
243            MemoryReference::py_try_from(py, &offset)?,
244            ArithmeticOperand::py_try_from(py, &source)?,
245        )))
246    }
247}