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}