quil_rs/instruction/
frame.rs

1use std::str::FromStr;
2
3use indexmap::IndexMap;
4use nom_locate::LocatedSpan;
5
6use super::{MemoryReference, Qubit, QuotedString, WaveformInvocation};
7use crate::{
8    expression::Expression,
9    parser::{common::parse_frame_identifier, lex, ParseError},
10    program::{disallow_leftover, SyntaxError},
11    quil::{Quil, INDENT},
12};
13
14#[derive(Clone, Debug, PartialEq, Eq, Hash, strum::EnumTryAs)]
15pub enum AttributeValue {
16    String(String),
17    Expression(Expression),
18}
19
20impl Quil for AttributeValue {
21    fn write(
22        &self,
23        f: &mut impl std::fmt::Write,
24        fall_back_to_debug: bool,
25    ) -> crate::quil::ToQuilResult<()> {
26        use AttributeValue::*;
27        match self {
28            String(value) => write!(f, "{}", QuotedString(value)).map_err(Into::into),
29            Expression(value) => value.write(f, fall_back_to_debug),
30        }
31    }
32}
33
34pub type FrameAttributes = IndexMap<String, AttributeValue>;
35
36#[derive(Clone, Debug, PartialEq, Eq)]
37pub struct FrameDefinition {
38    pub identifier: FrameIdentifier,
39    pub attributes: FrameAttributes,
40}
41
42impl FrameDefinition {
43    pub fn new(identifier: FrameIdentifier, attributes: FrameAttributes) -> Self {
44        Self {
45            identifier,
46            attributes,
47        }
48    }
49}
50
51impl Quil for FrameDefinition {
52    fn write(
53        &self,
54        writer: &mut impl std::fmt::Write,
55        fall_back_to_debug: bool,
56    ) -> crate::quil::ToQuilResult<()> {
57        write!(writer, "DEFFRAME ")?;
58        self.identifier.write(writer, fall_back_to_debug)?;
59        write!(writer, ":")?;
60        for (key, value) in &self.attributes {
61            write!(writer, "\n{INDENT}{key}: ")?;
62            value.write(writer, fall_back_to_debug)?;
63        }
64
65        Ok(())
66    }
67}
68
69#[derive(Clone, Debug, Eq, Hash, PartialEq)]
70pub struct FrameIdentifier {
71    pub name: String,
72    pub qubits: Vec<Qubit>,
73}
74
75impl FrameIdentifier {
76    pub fn new(name: String, qubits: Vec<Qubit>) -> Self {
77        Self { name, qubits }
78    }
79}
80
81impl Quil for FrameIdentifier {
82    fn write(
83        &self,
84        writer: &mut impl std::fmt::Write,
85        fall_back_to_debug: bool,
86    ) -> std::result::Result<(), crate::quil::ToQuilError> {
87        for qubit in &self.qubits {
88            qubit.write(writer, fall_back_to_debug)?;
89            write!(writer, " ")?;
90        }
91        write!(writer, "{}", QuotedString(&self.name)).map_err(Into::into)
92    }
93}
94
95impl FromStr for FrameIdentifier {
96    type Err = SyntaxError<Self>;
97
98    fn from_str(s: &str) -> Result<Self, Self::Err> {
99        let input = LocatedSpan::new(s);
100        let tokens = lex(input)?;
101        disallow_leftover(
102            parse_frame_identifier(&tokens).map_err(ParseError::from_nom_internal_err),
103        )
104    }
105}
106
107#[derive(Clone, Debug, PartialEq, Eq)]
108pub struct Capture {
109    pub blocking: bool,
110    pub frame: FrameIdentifier,
111    pub memory_reference: MemoryReference,
112    pub waveform: WaveformInvocation,
113}
114
115impl Capture {
116    pub fn new(
117        blocking: bool,
118        frame: FrameIdentifier,
119        memory_reference: MemoryReference,
120        waveform: WaveformInvocation,
121    ) -> Self {
122        Self {
123            blocking,
124            frame,
125            memory_reference,
126            waveform,
127        }
128    }
129}
130
131impl Quil for Capture {
132    fn write(
133        &self,
134        writer: &mut impl std::fmt::Write,
135        fall_back_to_debug: bool,
136    ) -> Result<(), crate::quil::ToQuilError> {
137        {
138            if self.blocking {
139                write!(writer, "CAPTURE ")?;
140            } else {
141                write!(writer, "NONBLOCKING CAPTURE ")?;
142            }
143
144            self.frame.write(writer, fall_back_to_debug)?;
145            write!(writer, " ")?;
146            self.waveform.write(writer, fall_back_to_debug)?;
147            write!(writer, " ")?;
148            self.memory_reference.write(writer, fall_back_to_debug)?;
149            Ok(())
150        }
151    }
152}
153
154#[derive(Clone, Debug, PartialEq, Eq)]
155pub struct Pulse {
156    pub blocking: bool,
157    pub frame: FrameIdentifier,
158    pub waveform: WaveformInvocation,
159}
160
161impl Pulse {
162    pub fn new(blocking: bool, frame: FrameIdentifier, waveform: WaveformInvocation) -> Self {
163        Self {
164            blocking,
165            frame,
166            waveform,
167        }
168    }
169}
170
171impl Quil for Pulse {
172    fn write(
173        &self,
174        writer: &mut impl std::fmt::Write,
175        fall_back_to_debug: bool,
176    ) -> crate::quil::ToQuilResult<()> {
177        {
178            if self.blocking {
179                write!(writer, "PULSE ")?;
180            } else {
181                write!(writer, "NONBLOCKING PULSE ")?;
182            }
183            self.frame.write(writer, fall_back_to_debug)?;
184            write!(writer, " ")?;
185            self.waveform.write(writer, fall_back_to_debug)?;
186            Ok(())
187        }
188    }
189}
190
191#[derive(Clone, Debug, PartialEq, Eq, Hash)]
192pub struct RawCapture {
193    pub blocking: bool,
194    pub frame: FrameIdentifier,
195    pub duration: Expression,
196    pub memory_reference: MemoryReference,
197}
198
199impl RawCapture {
200    pub fn new(
201        blocking: bool,
202        frame: FrameIdentifier,
203        duration: Expression,
204        memory_reference: MemoryReference,
205    ) -> Self {
206        Self {
207            blocking,
208            frame,
209            duration,
210            memory_reference,
211        }
212    }
213}
214
215impl Quil for RawCapture {
216    fn write(
217        &self,
218        writer: &mut impl std::fmt::Write,
219        fall_back_to_debug: bool,
220    ) -> crate::quil::ToQuilResult<()> {
221        {
222            if self.blocking {
223                write!(writer, "RAW-CAPTURE ")?;
224            } else {
225                write!(writer, "NONBLOCKING RAW-CAPTURE ")?;
226            }
227            self.frame.write(writer, fall_back_to_debug)?;
228            write!(writer, " ")?;
229            self.duration.write(writer, fall_back_to_debug)?;
230            write!(writer, " ")?;
231            self.memory_reference.write(writer, fall_back_to_debug)?;
232            Ok(())
233        }
234    }
235}
236
237#[derive(Clone, Debug, PartialEq, Eq, Hash)]
238pub struct SetFrequency {
239    pub frame: FrameIdentifier,
240    pub frequency: Expression,
241}
242
243impl SetFrequency {
244    pub fn new(frame: FrameIdentifier, frequency: Expression) -> Self {
245        Self { frame, frequency }
246    }
247}
248
249impl Quil for SetFrequency {
250    fn write(
251        &self,
252        writer: &mut impl std::fmt::Write,
253        fall_back_to_debug: bool,
254    ) -> crate::quil::ToQuilResult<()> {
255        write!(writer, "SET-FREQUENCY ")?;
256        self.frame.write(writer, fall_back_to_debug)?;
257        write!(writer, " ")?;
258        self.frequency.write(writer, fall_back_to_debug)?;
259        Ok(())
260    }
261}
262
263#[derive(Clone, Debug, PartialEq, Eq, Hash)]
264pub struct SetPhase {
265    pub frame: FrameIdentifier,
266    pub phase: Expression,
267}
268
269impl SetPhase {
270    pub fn new(frame: FrameIdentifier, phase: Expression) -> Self {
271        Self { frame, phase }
272    }
273}
274
275impl Quil for SetPhase {
276    fn write(
277        &self,
278        writer: &mut impl std::fmt::Write,
279        fall_back_to_debug: bool,
280    ) -> crate::quil::ToQuilResult<()> {
281        write!(writer, "SET-PHASE ")?;
282        self.frame.write(writer, fall_back_to_debug)?;
283        write!(writer, " ")?;
284        self.phase.write(writer, fall_back_to_debug)?;
285        Ok(())
286    }
287}
288
289#[derive(Clone, Debug, PartialEq, Eq, Hash)]
290pub struct SetScale {
291    pub frame: FrameIdentifier,
292    pub scale: Expression,
293}
294
295impl SetScale {
296    pub fn new(frame: FrameIdentifier, scale: Expression) -> Self {
297        Self { frame, scale }
298    }
299}
300
301impl Quil for SetScale {
302    fn write(
303        &self,
304        writer: &mut impl std::fmt::Write,
305        fall_back_to_debug: bool,
306    ) -> crate::quil::ToQuilResult<()> {
307        write!(writer, "SET-SCALE ")?;
308        self.frame.write(writer, fall_back_to_debug)?;
309        write!(writer, " ")?;
310        self.scale.write(writer, fall_back_to_debug)?;
311        Ok(())
312    }
313}
314
315#[derive(Clone, Debug, PartialEq, Eq, Hash)]
316pub struct ShiftFrequency {
317    pub frame: FrameIdentifier,
318    pub frequency: Expression,
319}
320
321impl ShiftFrequency {
322    pub fn new(frame: FrameIdentifier, frequency: Expression) -> Self {
323        Self { frame, frequency }
324    }
325}
326
327impl Quil for ShiftFrequency {
328    fn write(
329        &self,
330        writer: &mut impl std::fmt::Write,
331        fall_back_to_debug: bool,
332    ) -> crate::quil::ToQuilResult<()> {
333        write!(writer, "SHIFT-FREQUENCY ")?;
334        self.frame.write(writer, fall_back_to_debug)?;
335        write!(writer, " ")?;
336        self.frequency.write(writer, fall_back_to_debug)?;
337        Ok(())
338    }
339}
340
341#[derive(Clone, Debug, PartialEq, Eq, Hash)]
342pub struct ShiftPhase {
343    pub frame: FrameIdentifier,
344    pub phase: Expression,
345}
346
347impl ShiftPhase {
348    pub fn new(frame: FrameIdentifier, phase: Expression) -> Self {
349        Self { frame, phase }
350    }
351}
352
353impl Quil for ShiftPhase {
354    fn write(
355        &self,
356        writer: &mut impl std::fmt::Write,
357        fall_back_to_debug: bool,
358    ) -> crate::quil::ToQuilResult<()> {
359        write!(writer, "SHIFT-PHASE ")?;
360        self.frame.write(writer, fall_back_to_debug)?;
361        write!(writer, " ")?;
362        self.phase.write(writer, fall_back_to_debug)?;
363        Ok(())
364    }
365}
366
367#[derive(Clone, Debug, PartialEq, Eq, Hash)]
368pub struct SwapPhases {
369    pub frame_1: FrameIdentifier,
370    pub frame_2: FrameIdentifier,
371}
372
373impl SwapPhases {
374    pub fn new(frame_1: FrameIdentifier, frame_2: FrameIdentifier) -> Self {
375        Self { frame_1, frame_2 }
376    }
377}
378
379impl Quil for SwapPhases {
380    fn write(
381        &self,
382        writer: &mut impl std::fmt::Write,
383        fall_back_to_debug: bool,
384    ) -> crate::quil::ToQuilResult<()> {
385        write!(writer, "SWAP-PHASES ")?;
386        self.frame_1.write(writer, fall_back_to_debug)?;
387        write!(writer, " ")?;
388        self.frame_2.write(writer, fall_back_to_debug)?;
389        Ok(())
390    }
391}