quil_rs/instruction/
classical.rs

1use crate::{hash::hash_f64, quil::Quil};
2
3use super::MemoryReference;
4
5#[derive(Clone, Debug, Hash, PartialEq)]
6pub struct Arithmetic {
7    pub operator: ArithmeticOperator,
8    pub destination: MemoryReference,
9    pub source: ArithmeticOperand,
10}
11
12impl Arithmetic {
13    pub fn new(
14        operator: ArithmeticOperator,
15        destination: MemoryReference,
16        source: ArithmeticOperand,
17    ) -> Self {
18        Self {
19            operator,
20            destination,
21            source,
22        }
23    }
24}
25
26impl Quil for Arithmetic {
27    fn write(
28        &self,
29        f: &mut impl std::fmt::Write,
30        fall_back_to_debug: bool,
31    ) -> crate::quil::ToQuilResult<()> {
32        self.operator.write(f, fall_back_to_debug)?;
33        write!(f, " ")?;
34        self.destination.write(f, fall_back_to_debug)?;
35        write!(f, " ")?;
36        self.source.write(f, fall_back_to_debug)
37    }
38}
39
40#[derive(Clone, Debug, PartialEq)]
41pub enum ArithmeticOperand {
42    LiteralInteger(i64),
43    LiteralReal(f64),
44    MemoryReference(MemoryReference),
45}
46
47impl std::hash::Hash for ArithmeticOperand {
48    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
49        match self {
50            Self::LiteralInteger(operand) => operand.hash(state),
51            Self::LiteralReal(operand) => hash_f64(*operand, state),
52            Self::MemoryReference(operand) => operand.hash(state),
53        }
54    }
55}
56
57impl Quil for ArithmeticOperand {
58    fn write(
59        &self,
60        f: &mut impl std::fmt::Write,
61        fall_back_to_debug: bool,
62    ) -> crate::quil::ToQuilResult<()> {
63        match &self {
64            ArithmeticOperand::LiteralInteger(value) => write!(f, "{value}").map_err(Into::into),
65            ArithmeticOperand::LiteralReal(value) => write!(f, "{value}").map_err(Into::into),
66            ArithmeticOperand::MemoryReference(value) => value.write(f, fall_back_to_debug),
67        }
68    }
69}
70
71impl From<MemoryReference> for ArithmeticOperand {
72    fn from(memory_reference: MemoryReference) -> Self {
73        ArithmeticOperand::MemoryReference(memory_reference)
74    }
75}
76
77#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
78pub enum ArithmeticOperator {
79    Add,
80    Subtract,
81    Divide,
82    Multiply,
83}
84
85impl Quil for ArithmeticOperator {
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            ArithmeticOperator::Add => write!(f, "ADD"),
93            ArithmeticOperator::Subtract => write!(f, "SUB"),
94            ArithmeticOperator::Divide => write!(f, "DIV"),
95            ArithmeticOperator::Multiply => write!(f, "MUL"),
96        }
97        .map_err(Into::into)
98    }
99}
100
101#[derive(Clone, Debug, Hash, PartialEq, Eq)]
102pub enum BinaryOperand {
103    LiteralInteger(i64),
104    MemoryReference(MemoryReference),
105}
106
107impl Quil for BinaryOperand {
108    fn write(
109        &self,
110        f: &mut impl std::fmt::Write,
111        fall_back_to_debug: bool,
112    ) -> crate::quil::ToQuilResult<()> {
113        match &self {
114            BinaryOperand::LiteralInteger(value) => write!(f, "{value}").map_err(Into::into),
115            BinaryOperand::MemoryReference(value) => value.write(f, fall_back_to_debug),
116        }
117    }
118}
119
120#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
121pub enum BinaryOperator {
122    And,
123    Ior,
124    Xor,
125}
126
127impl Quil for BinaryOperator {
128    fn write(
129        &self,
130        f: &mut impl std::fmt::Write,
131        _fall_back_to_debug: bool,
132    ) -> crate::quil::ToQuilResult<()> {
133        match &self {
134            BinaryOperator::And => write!(f, "AND"),
135            BinaryOperator::Ior => write!(f, "IOR"),
136            BinaryOperator::Xor => write!(f, "XOR"),
137        }
138        .map_err(Into::into)
139    }
140}
141
142#[derive(Clone, Debug, Hash, PartialEq, Eq)]
143pub struct BinaryLogic {
144    pub operator: BinaryOperator,
145    pub destination: MemoryReference,
146    pub source: BinaryOperand,
147}
148
149impl Quil for BinaryLogic {
150    fn write(
151        &self,
152        f: &mut impl std::fmt::Write,
153        fall_back_to_debug: bool,
154    ) -> crate::quil::ToQuilResult<()> {
155        self.operator.write(f, fall_back_to_debug)?;
156        write!(f, " ")?;
157        self.destination.write(f, fall_back_to_debug)?;
158        write!(f, " ")?;
159        self.source.write(f, fall_back_to_debug)?;
160        Ok(())
161    }
162}
163
164impl BinaryLogic {
165    pub fn new(
166        operator: BinaryOperator,
167        destination: MemoryReference,
168        source: BinaryOperand,
169    ) -> Self {
170        Self {
171            operator,
172            destination,
173            source,
174        }
175    }
176}
177
178#[derive(Clone, Debug, Hash, PartialEq, Eq)]
179pub struct Convert {
180    pub destination: MemoryReference,
181    pub source: MemoryReference,
182}
183
184impl Convert {
185    pub fn new(destination: MemoryReference, source: MemoryReference) -> Self {
186        Self {
187            destination,
188            source,
189        }
190    }
191}
192
193impl Quil for Convert {
194    fn write(
195        &self,
196        f: &mut impl std::fmt::Write,
197        fall_back_to_debug: bool,
198    ) -> crate::quil::ToQuilResult<()> {
199        write!(f, "CONVERT ")?;
200        self.destination.write(f, fall_back_to_debug)?;
201        write!(f, " ")?;
202        self.source.write(f, fall_back_to_debug)?;
203        Ok(())
204    }
205}
206
207#[derive(Clone, Debug, Hash, PartialEq)]
208pub struct Move {
209    pub destination: MemoryReference,
210    pub source: ArithmeticOperand,
211}
212
213impl Move {
214    pub fn new(destination: MemoryReference, source: ArithmeticOperand) -> Self {
215        Self {
216            destination,
217            source,
218        }
219    }
220}
221
222impl Quil for Move {
223    fn write(
224        &self,
225        f: &mut impl std::fmt::Write,
226        fall_back_to_debug: bool,
227    ) -> crate::quil::ToQuilResult<()> {
228        write!(f, "MOVE ")?;
229        self.destination.write(f, fall_back_to_debug)?;
230        write!(f, " ")?;
231        self.source.write(f, fall_back_to_debug)?;
232        Ok(())
233    }
234}
235
236#[derive(Clone, Debug, Hash, PartialEq)]
237pub struct Exchange {
238    pub left: MemoryReference,
239    pub right: MemoryReference,
240}
241
242impl Quil for Exchange {
243    fn write(
244        &self,
245        f: &mut impl std::fmt::Write,
246        fall_back_to_debug: bool,
247    ) -> crate::quil::ToQuilResult<()> {
248        write!(f, "EXCHANGE ")?;
249        self.left.write(f, fall_back_to_debug)?;
250        write!(f, " ")?;
251        self.right.write(f, fall_back_to_debug)?;
252        Ok(())
253    }
254}
255
256impl Exchange {
257    pub fn new(left: MemoryReference, right: MemoryReference) -> Self {
258        Self { left, right }
259    }
260}
261
262#[derive(Clone, Debug, Hash, PartialEq)]
263pub struct Comparison {
264    pub operator: ComparisonOperator,
265    pub destination: MemoryReference,
266    pub lhs: MemoryReference,
267    pub rhs: ComparisonOperand,
268}
269
270impl Comparison {
271    pub fn new(
272        operator: ComparisonOperator,
273        destination: MemoryReference,
274        lhs: MemoryReference,
275        rhs: ComparisonOperand,
276    ) -> Self {
277        Self {
278            operator,
279            destination,
280            lhs,
281            rhs,
282        }
283    }
284}
285
286impl Quil for Comparison {
287    fn write(
288        &self,
289        f: &mut impl std::fmt::Write,
290        fall_back_to_debug: bool,
291    ) -> crate::quil::ToQuilResult<()> {
292        self.operator.write(f, fall_back_to_debug)?;
293        write!(f, " ")?;
294        self.destination.write(f, fall_back_to_debug)?;
295        write!(f, " ")?;
296        self.lhs.write(f, fall_back_to_debug)?;
297        write!(f, " ")?;
298        self.rhs.write(f, fall_back_to_debug)?;
299        Ok(())
300    }
301}
302
303#[derive(Clone, Debug, PartialEq)]
304pub enum ComparisonOperand {
305    LiteralInteger(i64),
306    LiteralReal(f64),
307    MemoryReference(MemoryReference),
308}
309
310impl Quil for ComparisonOperand {
311    fn write(
312        &self,
313        f: &mut impl std::fmt::Write,
314        fall_back_to_debug: bool,
315    ) -> crate::quil::ToQuilResult<()> {
316        match &self {
317            ComparisonOperand::LiteralInteger(value) => write!(f, "{value}").map_err(Into::into),
318            ComparisonOperand::LiteralReal(value) => write!(f, "{value}").map_err(Into::into),
319            ComparisonOperand::MemoryReference(value) => value.write(f, fall_back_to_debug),
320        }
321    }
322}
323
324impl std::hash::Hash for ComparisonOperand {
325    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
326        match self {
327            ComparisonOperand::LiteralInteger(operand) => operand.hash(state),
328            ComparisonOperand::LiteralReal(operand) => hash_f64(*operand, state),
329            ComparisonOperand::MemoryReference(operand) => operand.hash(state),
330        }
331    }
332}
333
334#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
335pub enum ComparisonOperator {
336    Equal,
337    GreaterThanOrEqual,
338    GreaterThan,
339    LessThanOrEqual,
340    LessThan,
341}
342
343impl Quil for ComparisonOperator {
344    fn write(
345        &self,
346        f: &mut impl std::fmt::Write,
347        _fall_back_to_debug: bool,
348    ) -> crate::quil::ToQuilResult<()> {
349        match &self {
350            ComparisonOperator::Equal => write!(f, "EQ"),
351            ComparisonOperator::GreaterThanOrEqual => write!(f, "GE"),
352            ComparisonOperator::GreaterThan => write!(f, "GT"),
353            ComparisonOperator::LessThanOrEqual => write!(f, "LE"),
354            ComparisonOperator::LessThan => write!(f, "LT"),
355        }
356        .map_err(Into::into)
357    }
358}
359
360#[derive(Clone, Debug, Hash, PartialEq, Eq)]
361pub struct UnaryLogic {
362    pub operator: UnaryOperator,
363    pub operand: MemoryReference,
364}
365
366impl UnaryLogic {
367    pub fn new(operator: UnaryOperator, operand: MemoryReference) -> Self {
368        Self { operator, operand }
369    }
370}
371
372impl Quil for UnaryLogic {
373    fn write(
374        &self,
375        f: &mut impl std::fmt::Write,
376        fall_back_to_debug: bool,
377    ) -> crate::quil::ToQuilResult<()> {
378        self.operator.write(f, fall_back_to_debug)?;
379        write!(f, " ")?;
380        self.operand.write(f, fall_back_to_debug)?;
381        Ok(())
382    }
383}
384
385#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
386pub enum UnaryOperator {
387    Neg,
388    Not,
389}
390
391impl Quil for UnaryOperator {
392    fn write(
393        &self,
394        f: &mut impl std::fmt::Write,
395        _fall_back_to_debug: bool,
396    ) -> crate::quil::ToQuilResult<()> {
397        match &self {
398            UnaryOperator::Neg => write!(f, "NEG"),
399            UnaryOperator::Not => write!(f, "NOT"),
400        }
401        .map_err(Into::into)
402    }
403}