1#[cfg(feature = "stubs")]
2use pyo3_stub_gen::derive::{
3 gen_stub_pyclass, gen_stub_pyclass_complex_enum, gen_stub_pyclass_enum,
4};
5
6use super::MemoryReference;
7
8use crate::{floating_point_eq, pickleable_new, quil::Quil};
9
10#[derive(Clone, Debug, Hash, PartialEq)]
11#[cfg_attr(feature = "stubs", gen_stub_pyclass)]
12#[cfg_attr(
13 feature = "python",
14 pyo3::pyclass(module = "quil.instructions", eq, frozen, hash, get_all, subclass)
15)]
16pub struct Arithmetic {
17 pub operator: ArithmeticOperator,
18 pub destination: MemoryReference,
19 pub source: ArithmeticOperand,
20}
21
22pickleable_new! {
23 impl Arithmetic {
24 pub fn new(
25 operator: ArithmeticOperator,
26 destination: MemoryReference,
27 source: ArithmeticOperand,
28 );
29 }
30}
31
32impl Quil for Arithmetic {
33 fn write(
34 &self,
35 f: &mut impl std::fmt::Write,
36 fall_back_to_debug: bool,
37 ) -> crate::quil::ToQuilResult<()> {
38 self.operator.write(f, fall_back_to_debug)?;
39 write!(f, " ")?;
40 self.destination.write(f, fall_back_to_debug)?;
41 write!(f, " ")?;
42 self.source.write(f, fall_back_to_debug)
43 }
44}
45
46#[derive(Clone, Debug)]
47#[cfg_attr(feature = "stubs", gen_stub_pyclass_complex_enum)]
48#[cfg_attr(
49 feature = "python",
50 pyo3::pyclass(module = "quil.instructions", eq, frozen, hash, get_all)
51)]
52pub enum ArithmeticOperand {
53 LiteralInteger(i64),
54 LiteralReal(f64),
55 MemoryReference(MemoryReference),
56}
57
58impl PartialEq for ArithmeticOperand {
59 fn eq(&self, other: &Self) -> bool {
60 match (self, other) {
61 (Self::LiteralInteger(this), Self::LiteralInteger(that)) => this == that,
62 (Self::LiteralReal(this), Self::LiteralReal(that)) => {
63 floating_point_eq::f64::eq(*this, *that)
64 }
65 (Self::MemoryReference(this), Self::MemoryReference(that)) => this == that,
66 (Self::LiteralInteger(_) | Self::LiteralReal(_) | Self::MemoryReference(_), _) => false,
69 }
70 }
71}
72
73impl Eq for ArithmeticOperand {}
74
75impl std::hash::Hash for ArithmeticOperand {
76 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
77 match self {
78 Self::LiteralInteger(operand) => operand.hash(state),
79 Self::LiteralReal(operand) => floating_point_eq::f64::hash(*operand, state),
80 Self::MemoryReference(operand) => operand.hash(state),
81 }
82 }
83}
84
85impl Quil for ArithmeticOperand {
86 fn write(
87 &self,
88 f: &mut impl std::fmt::Write,
89 fall_back_to_debug: bool,
90 ) -> crate::quil::ToQuilResult<()> {
91 match &self {
92 ArithmeticOperand::LiteralInteger(value) => write!(f, "{value}").map_err(Into::into),
93 ArithmeticOperand::LiteralReal(value) => write!(f, "{value}").map_err(Into::into),
94 ArithmeticOperand::MemoryReference(value) => value.write(f, fall_back_to_debug),
95 }
96 }
97}
98
99impl From<MemoryReference> for ArithmeticOperand {
100 fn from(memory_reference: MemoryReference) -> Self {
101 ArithmeticOperand::MemoryReference(memory_reference)
102 }
103}
104
105#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
106#[cfg_attr(feature = "stubs", gen_stub_pyclass_enum)]
107#[cfg_attr(
108 feature = "python",
109 pyo3::pyclass(
110 module = "quil.instructions",
111 eq,
112 frozen,
113 hash,
114 rename_all = "SCREAMING_SNAKE_CASE"
115 )
116)]
117pub enum ArithmeticOperator {
118 Add,
119 Subtract,
120 Divide,
121 Multiply,
122}
123
124impl Quil for ArithmeticOperator {
125 fn write(
126 &self,
127 f: &mut impl std::fmt::Write,
128 _fall_back_to_debug: bool,
129 ) -> crate::quil::ToQuilResult<()> {
130 match &self {
131 ArithmeticOperator::Add => write!(f, "ADD"),
132 ArithmeticOperator::Subtract => write!(f, "SUB"),
133 ArithmeticOperator::Divide => write!(f, "DIV"),
134 ArithmeticOperator::Multiply => write!(f, "MUL"),
135 }
136 .map_err(Into::into)
137 }
138}
139
140#[derive(Clone, Debug, Hash, PartialEq, Eq)]
141#[cfg_attr(feature = "stubs", gen_stub_pyclass_complex_enum)]
142#[cfg_attr(
143 feature = "python",
144 pyo3::pyclass(module = "quil.instructions", eq, frozen, hash, get_all)
145)]
146pub enum BinaryOperand {
147 LiteralInteger(i64),
148 MemoryReference(MemoryReference),
149}
150
151impl Quil for BinaryOperand {
152 fn write(
153 &self,
154 f: &mut impl std::fmt::Write,
155 fall_back_to_debug: bool,
156 ) -> crate::quil::ToQuilResult<()> {
157 match &self {
158 BinaryOperand::LiteralInteger(value) => write!(f, "{value}").map_err(Into::into),
159 BinaryOperand::MemoryReference(value) => value.write(f, fall_back_to_debug),
160 }
161 }
162}
163
164#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
165#[cfg_attr(feature = "stubs", gen_stub_pyclass_enum)]
166#[cfg_attr(
167 feature = "python",
168 pyo3::pyclass(
169 module = "quil.instructions",
170 eq,
171 frozen,
172 hash,
173 rename_all = "SCREAMING_SNAKE_CASE"
174 )
175)]
176pub enum BinaryOperator {
177 And,
178 Ior,
179 Xor,
180}
181
182impl Quil for BinaryOperator {
183 fn write(
184 &self,
185 f: &mut impl std::fmt::Write,
186 _fall_back_to_debug: bool,
187 ) -> crate::quil::ToQuilResult<()> {
188 match &self {
189 BinaryOperator::And => write!(f, "AND"),
190 BinaryOperator::Ior => write!(f, "IOR"),
191 BinaryOperator::Xor => write!(f, "XOR"),
192 }
193 .map_err(Into::into)
194 }
195}
196
197#[derive(Clone, Debug, Hash, PartialEq, Eq)]
198#[cfg_attr(feature = "stubs", gen_stub_pyclass)]
199#[cfg_attr(
200 feature = "python",
201 pyo3::pyclass(module = "quil.instructions", eq, frozen, hash, get_all, subclass)
202)]
203pub struct BinaryLogic {
204 pub operator: BinaryOperator,
205 pub destination: MemoryReference,
206 pub source: BinaryOperand,
207}
208
209impl Quil for BinaryLogic {
210 fn write(
211 &self,
212 f: &mut impl std::fmt::Write,
213 fall_back_to_debug: bool,
214 ) -> crate::quil::ToQuilResult<()> {
215 self.operator.write(f, fall_back_to_debug)?;
216 write!(f, " ")?;
217 self.destination.write(f, fall_back_to_debug)?;
218 write!(f, " ")?;
219 self.source.write(f, fall_back_to_debug)?;
220 Ok(())
221 }
222}
223
224pickleable_new! {
225 impl BinaryLogic {
226 pub fn new(
227 operator: BinaryOperator,
228 destination: MemoryReference,
229 source: BinaryOperand,
230 );
231 }
232}
233
234#[derive(Clone, Debug, Hash, PartialEq, Eq)]
235#[cfg_attr(feature = "stubs", gen_stub_pyclass)]
236#[cfg_attr(
237 feature = "python",
238 pyo3::pyclass(module = "quil.instructions", eq, frozen, hash, get_all, subclass)
239)]
240pub struct Convert {
241 pub destination: MemoryReference,
242 pub source: MemoryReference,
243}
244
245pickleable_new! {
246 impl Convert {
247 pub fn new(destination: MemoryReference, source: MemoryReference);
248 }
249}
250
251impl Quil for Convert {
252 fn write(
253 &self,
254 f: &mut impl std::fmt::Write,
255 fall_back_to_debug: bool,
256 ) -> crate::quil::ToQuilResult<()> {
257 write!(f, "CONVERT ")?;
258 self.destination.write(f, fall_back_to_debug)?;
259 write!(f, " ")?;
260 self.source.write(f, fall_back_to_debug)?;
261 Ok(())
262 }
263}
264
265#[derive(Clone, Debug, Hash, PartialEq)]
266#[cfg_attr(feature = "stubs", gen_stub_pyclass)]
267#[cfg_attr(
268 feature = "python",
269 pyo3::pyclass(module = "quil.instructions", eq, frozen, hash, get_all, subclass)
270)]
271pub struct Move {
272 pub destination: MemoryReference,
273 pub source: ArithmeticOperand,
274}
275
276pickleable_new! {
277 impl Move {
278 pub fn new(destination: MemoryReference, source: ArithmeticOperand);
279 }
280}
281
282impl Quil for Move {
283 fn write(
284 &self,
285 f: &mut impl std::fmt::Write,
286 fall_back_to_debug: bool,
287 ) -> crate::quil::ToQuilResult<()> {
288 write!(f, "MOVE ")?;
289 self.destination.write(f, fall_back_to_debug)?;
290 write!(f, " ")?;
291 self.source.write(f, fall_back_to_debug)?;
292 Ok(())
293 }
294}
295
296#[derive(Clone, Debug, Hash, PartialEq)]
297#[cfg_attr(feature = "stubs", gen_stub_pyclass)]
298#[cfg_attr(
299 feature = "python",
300 pyo3::pyclass(module = "quil.instructions", eq, frozen, hash, get_all, subclass)
301)]
302pub struct Exchange {
303 pub left: MemoryReference,
304 pub right: MemoryReference,
305}
306
307impl Quil for Exchange {
308 fn write(
309 &self,
310 f: &mut impl std::fmt::Write,
311 fall_back_to_debug: bool,
312 ) -> crate::quil::ToQuilResult<()> {
313 write!(f, "EXCHANGE ")?;
314 self.left.write(f, fall_back_to_debug)?;
315 write!(f, " ")?;
316 self.right.write(f, fall_back_to_debug)?;
317 Ok(())
318 }
319}
320
321pickleable_new! {
322 impl Exchange {
323 pub fn new(left: MemoryReference, right: MemoryReference);
324 }
325}
326
327#[derive(Clone, Debug, Hash, PartialEq)]
328#[cfg_attr(feature = "stubs", gen_stub_pyclass)]
329#[cfg_attr(
330 feature = "python",
331 pyo3::pyclass(module = "quil.instructions", eq, frozen, hash, get_all, subclass)
332)]
333pub struct Comparison {
334 pub operator: ComparisonOperator,
335 pub destination: MemoryReference,
336 pub lhs: MemoryReference,
337 pub rhs: ComparisonOperand,
338}
339
340pickleable_new! {
341 impl Comparison {
342 pub fn new(
343 operator: ComparisonOperator,
344 destination: MemoryReference,
345 lhs: MemoryReference,
346 rhs: ComparisonOperand,
347 );
348 }
349}
350
351impl Quil for Comparison {
352 fn write(
353 &self,
354 f: &mut impl std::fmt::Write,
355 fall_back_to_debug: bool,
356 ) -> crate::quil::ToQuilResult<()> {
357 self.operator.write(f, fall_back_to_debug)?;
358 write!(f, " ")?;
359 self.destination.write(f, fall_back_to_debug)?;
360 write!(f, " ")?;
361 self.lhs.write(f, fall_back_to_debug)?;
362 write!(f, " ")?;
363 self.rhs.write(f, fall_back_to_debug)?;
364 Ok(())
365 }
366}
367
368#[derive(Clone, Debug)]
369#[cfg_attr(feature = "stubs", gen_stub_pyclass_complex_enum)]
370#[cfg_attr(
371 feature = "python",
372 pyo3::pyclass(module = "quil.instructions", eq, frozen, hash, get_all)
373)]
374pub enum ComparisonOperand {
375 LiteralInteger(i64),
376 LiteralReal(f64),
377 MemoryReference(MemoryReference),
378}
379
380impl Quil for ComparisonOperand {
381 fn write(
382 &self,
383 f: &mut impl std::fmt::Write,
384 fall_back_to_debug: bool,
385 ) -> crate::quil::ToQuilResult<()> {
386 match &self {
387 ComparisonOperand::LiteralInteger(value) => write!(f, "{value}").map_err(Into::into),
388 ComparisonOperand::LiteralReal(value) => write!(f, "{value}").map_err(Into::into),
389 ComparisonOperand::MemoryReference(value) => value.write(f, fall_back_to_debug),
390 }
391 }
392}
393
394impl PartialEq for ComparisonOperand {
395 fn eq(&self, other: &Self) -> bool {
396 match (self, other) {
397 (Self::LiteralInteger(this), Self::LiteralInteger(that)) => this == that,
398 (Self::LiteralReal(this), Self::LiteralReal(that)) => {
399 floating_point_eq::f64::eq(*this, *that)
400 }
401 (Self::MemoryReference(this), Self::MemoryReference(that)) => this == that,
402 (Self::LiteralInteger(_) | Self::LiteralReal(_) | Self::MemoryReference(_), _) => false,
405 }
406 }
407}
408
409impl Eq for ComparisonOperand {}
410
411impl std::hash::Hash for ComparisonOperand {
412 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
413 match self {
414 ComparisonOperand::LiteralInteger(operand) => operand.hash(state),
415 ComparisonOperand::LiteralReal(operand) => {
416 floating_point_eq::f64::hash(*operand, state)
417 }
418 ComparisonOperand::MemoryReference(operand) => operand.hash(state),
419 }
420 }
421}
422
423#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
424#[cfg_attr(feature = "stubs", gen_stub_pyclass_enum)]
425#[cfg_attr(
426 feature = "python",
427 pyo3::pyclass(
428 module = "quil.instructions",
429 eq,
430 frozen,
431 hash,
432 rename_all = "SCREAMING_SNAKE_CASE"
433 )
434)]
435pub enum ComparisonOperator {
436 Equal,
437 GreaterThanOrEqual,
438 GreaterThan,
439 LessThanOrEqual,
440 LessThan,
441}
442
443impl Quil for ComparisonOperator {
444 fn write(
445 &self,
446 f: &mut impl std::fmt::Write,
447 _fall_back_to_debug: bool,
448 ) -> crate::quil::ToQuilResult<()> {
449 match &self {
450 ComparisonOperator::Equal => write!(f, "EQ"),
451 ComparisonOperator::GreaterThanOrEqual => write!(f, "GE"),
452 ComparisonOperator::GreaterThan => write!(f, "GT"),
453 ComparisonOperator::LessThanOrEqual => write!(f, "LE"),
454 ComparisonOperator::LessThan => write!(f, "LT"),
455 }
456 .map_err(Into::into)
457 }
458}
459
460#[derive(Clone, Debug, Hash, PartialEq, Eq)]
461#[cfg_attr(feature = "stubs", gen_stub_pyclass)]
462#[cfg_attr(
463 feature = "python",
464 pyo3::pyclass(module = "quil.instructions", eq, frozen, hash, get_all, subclass)
465)]
466pub struct UnaryLogic {
467 pub operator: UnaryOperator,
468 pub operand: MemoryReference,
469}
470
471pickleable_new! {
472 impl UnaryLogic {
473 pub fn new(operator: UnaryOperator, operand: MemoryReference);
474 }
475}
476
477impl Quil for UnaryLogic {
478 fn write(
479 &self,
480 f: &mut impl std::fmt::Write,
481 fall_back_to_debug: bool,
482 ) -> crate::quil::ToQuilResult<()> {
483 self.operator.write(f, fall_back_to_debug)?;
484 write!(f, " ")?;
485 self.operand.write(f, fall_back_to_debug)?;
486 Ok(())
487 }
488}
489
490#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
491#[cfg_attr(feature = "stubs", gen_stub_pyclass_enum)]
492#[cfg_attr(
493 feature = "python",
494 pyo3::pyclass(
495 module = "quil.instructions",
496 eq,
497 frozen,
498 hash,
499 rename_all = "SCREAMING_SNAKE_CASE"
500 )
501)]
502pub enum UnaryOperator {
503 Neg,
504 Not,
505}
506
507impl Quil for UnaryOperator {
508 fn write(
509 &self,
510 f: &mut impl std::fmt::Write,
511 _fall_back_to_debug: bool,
512 ) -> crate::quil::ToQuilResult<()> {
513 match &self {
514 UnaryOperator::Neg => write!(f, "NEG"),
515 UnaryOperator::Not => write!(f, "NOT"),
516 }
517 .map_err(Into::into)
518 }
519}