1use nom::branch::alt;
2use nom::combinator::{map, map_res, opt};
3use nom::multi::{many0, many1, separated_list0, separated_list1};
4use nom::sequence::{delimited, preceded, tuple};
5
6use crate::expression::Expression;
7use crate::instruction::{
8 Arithmetic, ArithmeticOperator, BinaryLogic, BinaryOperator, CalibrationDefinition,
9 CalibrationIdentifier, Call, Capture, CircuitDefinition, Comparison, ComparisonOperator,
10 Convert, Declaration, DefGateSequence, Delay, Exchange, Fence, FrameDefinition, GateDefinition,
11 GateSpecification, GateType, Include, Instruction, Jump, JumpUnless, JumpWhen, Label, Load,
12 MeasureCalibrationDefinition, MeasureCalibrationIdentifier, Measurement, Move, PauliSum,
13 Pragma, PragmaArgument, Pulse, Qubit, RawCapture, Reset, SetFrequency, SetPhase, SetScale,
14 ShiftFrequency, ShiftPhase, Store, SwapPhases, Target, UnaryLogic, UnaryOperator,
15 UnresolvedCallArgument, ValidationError, Waveform, WaveformDefinition,
16};
17
18use crate::parser::common::parse_sequence_elements;
19use crate::parser::instruction::parse_block;
20use crate::parser::InternalParserResult;
21use crate::{real, token};
22
23use super::common::{parse_memory_reference_with_brackets, parse_variable_qubit};
24use super::{
25 common::{
26 parse_arithmetic_operand, parse_binary_logic_operand, parse_comparison_operand,
27 parse_frame_attribute, parse_frame_identifier, parse_gate_modifier, parse_matrix,
28 parse_memory_reference, parse_pauli_terms, parse_permutation, parse_qubit, parse_sharing,
29 parse_vector, parse_waveform_invocation, parse_waveform_name,
30 },
31 expression::parse_expression,
32 InternalParseError, ParserErrorKind, ParserInput,
33};
34
35pub(crate) fn parse_arithmetic(
38 operator: ArithmeticOperator,
39 input: ParserInput,
40) -> InternalParserResult<Instruction> {
41 let (input, destination) = parse_memory_reference(input)?;
42 let (input, source) = parse_arithmetic_operand(input)?;
43
44 Ok((
45 input,
46 Instruction::Arithmetic(Arithmetic {
47 operator,
48 destination,
49 source,
50 }),
51 ))
52}
53
54pub(crate) fn parse_comparison(
57 operator: ComparisonOperator,
58 input: ParserInput,
59) -> InternalParserResult<Instruction> {
60 let (input, destination) = parse_memory_reference(input)?;
61 let (input, lhs) = parse_memory_reference(input)?;
62 let (input, rhs) = parse_comparison_operand(input)?;
63
64 Ok((
65 input,
66 Instruction::Comparison(Comparison {
67 operator,
68 destination,
69 lhs,
70 rhs,
71 }),
72 ))
73}
74
75pub(crate) fn parse_logical_binary(
78 operator: BinaryOperator,
79 input: ParserInput,
80) -> InternalParserResult<Instruction> {
81 let (input, destination) = parse_memory_reference(input)?;
82 let (input, source) = parse_binary_logic_operand(input)?;
83
84 Ok((
85 input,
86 Instruction::BinaryLogic(BinaryLogic {
87 operator,
88 destination,
89 source,
90 }),
91 ))
92}
93
94pub(crate) fn parse_logical_unary(
97 operator: UnaryOperator,
98 input: ParserInput,
99) -> InternalParserResult<Instruction> {
100 let (input, operand) = parse_memory_reference(input)?;
101
102 Ok((
103 input,
104 Instruction::UnaryLogic(UnaryLogic { operator, operand }),
105 ))
106}
107
108pub(crate) fn parse_declare<'a>(input: ParserInput<'a>) -> InternalParserResult<'a, Instruction> {
110 let (input, name) = token!(Identifier(v))(input)?;
111 let (input, size) = parse_vector(input)?;
112 let (input, sharing) = parse_sharing(input)?;
113
114 Ok((
115 input,
116 Instruction::Declaration(Declaration {
117 name,
118 size,
119 sharing,
120 }),
121 ))
122}
123
124pub(crate) fn parse_call<'a>(input: ParserInput<'a>) -> InternalParserResult<'a, Instruction> {
134 let (input, name) = token!(Identifier(v))(input)?;
135
136 let (input, arguments) = many0(parse_call_argument)(input)?;
137 let call = Call { name, arguments };
138
139 Ok((input, Instruction::Call(call)))
140}
141
142fn parse_call_argument<'a>(
143 input: ParserInput<'a>,
144) -> InternalParserResult<'a, UnresolvedCallArgument> {
145 alt((
146 map(
147 parse_memory_reference_with_brackets,
148 UnresolvedCallArgument::MemoryReference,
149 ),
150 map(token!(Identifier(v)), UnresolvedCallArgument::Identifier),
151 map(
152 super::expression::parse_immediate_value,
153 UnresolvedCallArgument::Immediate,
154 ),
155 ))(input)
156}
157
158pub(crate) fn parse_capture(
163 input: ParserInput,
164 blocking: bool,
165) -> InternalParserResult<Instruction> {
166 let (input, frame) = parse_frame_identifier(input)?;
167 let (input, waveform) = parse_waveform_invocation(input)?;
168 let (input, memory_reference) = parse_memory_reference(input)?;
169
170 Ok((
171 input,
172 Instruction::Capture(Capture {
173 blocking,
174 frame,
175 memory_reference,
176 waveform,
177 }),
178 ))
179}
180
181pub(crate) fn parse_convert(input: ParserInput) -> InternalParserResult<Instruction> {
183 let (input, to) = parse_memory_reference(input)?;
184 let (input, from) = parse_memory_reference(input)?;
185 Ok((
186 input,
187 Instruction::Convert(Convert {
188 destination: to,
189 source: from,
190 }),
191 ))
192}
193
194pub(crate) fn parse_defcal<'a>(input: ParserInput<'a>) -> InternalParserResult<'a, Instruction> {
197 use crate::parser::lexer::Command::Measure;
198 let (input, defcal_measure) = opt(token!(Command(Measure)))(input)?;
199 match defcal_measure {
200 Some(_) => parse_defcal_measure(input),
201 None => parse_defcal_gate(input),
202 }
203}
204
205pub(crate) fn parse_defcal_gate<'a>(
208 input: ParserInput<'a>,
209) -> InternalParserResult<'a, Instruction> {
210 let (input, modifiers) = many0(parse_gate_modifier)(input)?;
211 let (input, name) = token!(Identifier(v))(input)?;
212 let (input, parameters) = opt(delimited(
213 token!(LParenthesis),
214 separated_list0(token!(Comma), parse_expression),
215 token!(RParenthesis),
216 ))(input)?;
217 let parameters = parameters.unwrap_or_default();
218 let (input, qubits) = many0(parse_qubit)(input)?;
219 let (input, _) = token!(Colon)(input)?;
220 let (input, instructions) = parse_block(input)?;
221 Ok((
222 input,
223 Instruction::CalibrationDefinition(CalibrationDefinition {
224 identifier: CalibrationIdentifier {
225 name,
226 parameters,
227 qubits,
228 modifiers,
229 },
230 instructions,
231 }),
232 ))
233}
234
235pub(crate) fn parse_defcal_measure<'a>(
237 input: ParserInput<'a>,
238) -> InternalParserResult<'a, Instruction> {
239 let (input, name) = opt(preceded(token!(Bang), token!(Identifier(name))))(input)?;
240 let (input, qubit) = parse_qubit(input)?;
241 let (input, target) = opt(token!(Identifier(t)))(input)?;
242 let (input, _) = token!(Colon)(input)?;
243 let (input, instructions) = parse_block(input)?;
244 Ok((
245 input,
246 Instruction::MeasureCalibrationDefinition(MeasureCalibrationDefinition {
247 identifier: MeasureCalibrationIdentifier {
248 name,
249 qubit,
250 target,
251 },
252 instructions,
253 }),
254 ))
255}
256
257pub(crate) fn parse_defframe<'a>(input: ParserInput<'a>) -> InternalParserResult<'a, Instruction> {
259 let (input, identifier) = parse_frame_identifier(input)?;
260 let (input, _) = token!(Colon)(input)?;
261 let (input, attribute_pairs) = many1(parse_frame_attribute)(input)?;
262 let attributes = attribute_pairs.into_iter().collect();
263
264 Ok((
265 input,
266 Instruction::FrameDefinition(FrameDefinition {
267 identifier,
268 attributes,
269 }),
270 ))
271}
272
273pub(crate) fn parse_defgate<'a>(input: ParserInput<'a>) -> InternalParserResult<'a, Instruction> {
275 let (input, name) = token!(Identifier(v))(input)?;
276 let (input, parameters) = opt(delimited(
277 token!(LParenthesis),
278 separated_list0(token!(Comma), token!(Variable(v))),
279 token!(RParenthesis),
280 ))(input)?;
281 let (input, mut arguments) = opt(many0(token!(Identifier(v))))(input)?;
282 let (input, gate_type) = opt(preceded(
283 token!(As),
284 alt((
285 map(token!(Matrix), |()| GateType::Matrix),
286 map(token!(Permutation), |()| GateType::Permutation),
287 map(token!(PauliSum), |()| GateType::PauliSum),
288 map(token!(Sequence), |()| GateType::Sequence),
289 )),
290 ))(input)?;
291
292 let (input, _) = token!(Colon)(input)?;
293
294 let gate_type = gate_type.unwrap_or(GateType::Matrix);
295 let (input, specification) = match gate_type {
296 GateType::Matrix => map(parse_matrix, GateSpecification::Matrix)(input)?,
297 GateType::Permutation => map(parse_permutation, GateSpecification::Permutation)(input)?,
298 GateType::PauliSum => map_res(parse_pauli_terms, |terms| {
299 Ok(GateSpecification::PauliSum(
300 PauliSum::new(arguments.take().unwrap_or_default(), terms)
301 .map_err(ValidationError::from)
302 .map_err(|e| InternalParseError::from_kind(input, ParserErrorKind::from(e)))?,
303 ))
304 })(input)?,
305 GateType::Sequence => map_res(parse_sequence_elements, |gates| {
306 let gate_sequence =
307 DefGateSequence::try_new(arguments.take().unwrap_or_default(), gates)
308 .map_err(ValidationError::from)
309 .map_err(ParserErrorKind::from)
310 .map_err(|e| InternalParseError::from_kind(input, e))?;
311 Ok(GateSpecification::Sequence(gate_sequence))
312 })(input)?,
313 };
314
315 Ok((
316 input,
317 Instruction::GateDefinition(GateDefinition {
318 name,
319 parameters: parameters.unwrap_or_default(),
320 specification,
321 }),
322 ))
323}
324
325pub(crate) fn parse_defwaveform<'a>(
327 input: ParserInput<'a>,
328) -> InternalParserResult<'a, Instruction> {
329 let (input, name) = parse_waveform_name(input)?;
330 let (input, parameters) = opt(delimited(
331 token!(LParenthesis),
332 separated_list0(token!(Comma), token!(Variable(v))),
333 token!(RParenthesis),
334 ))(input)?;
335 let parameters = parameters.unwrap_or_default();
336
337 let (input, _) = tuple((token!(Colon), token!(NewLine), token!(Indentation)))(input)?;
338 let (input, matrix) = separated_list1(token!(Comma), parse_expression)(input)?;
339
340 Ok((
341 input,
342 Instruction::WaveformDefinition(WaveformDefinition {
343 name,
344 definition: Waveform { matrix, parameters },
345 }),
346 ))
347}
348
349pub(crate) fn parse_defcircuit<'a>(
350 input: ParserInput<'a>,
351) -> InternalParserResult<'a, Instruction> {
352 let (input, name) = token!(Identifier(v))(input)?;
353 let (input, parameters) = opt(delimited(
354 token!(LParenthesis),
355 separated_list0(token!(Comma), token!(Variable(v))),
356 token!(RParenthesis),
357 ))(input)?;
358 let parameters = parameters.unwrap_or_default();
359 let (input, qubit_variables) = many0(parse_variable_qubit)(input)?;
360 let (input, _) = token!(Colon)(input)?;
361 let (input, instructions) = parse_block(input)?;
362
363 Ok((
364 input,
365 Instruction::CircuitDefinition(CircuitDefinition {
366 name,
367 parameters,
368 qubit_variables,
369 instructions,
370 }),
371 ))
372}
373
374pub(crate) fn parse_delay<'a>(input: ParserInput<'a>) -> InternalParserResult<'a, Instruction> {
376 let (input, mut qubits) = many0(parse_qubit)(input)?;
377 let (input, frame_names) = many0(token!(String(v)))(input)?;
378 let (input, duration) = parse_expression(input).or_else(|e| {
381 if let Some(Qubit::Fixed(index)) = qubits.last() {
382 let duration = *index as f64;
383 qubits.pop();
384 Ok((input, Expression::Number(real!(duration))))
385 } else {
386 Err(e)
387 }
388 })?;
389
390 Ok((
391 input,
392 Instruction::Delay(Delay {
393 duration,
394 frame_names,
395 qubits,
396 }),
397 ))
398}
399
400pub(crate) fn parse_exchange(input: ParserInput) -> InternalParserResult<Instruction> {
402 let (input, left) = parse_memory_reference(input)?;
403 let (input, right) = parse_memory_reference(input)?;
404
405 Ok((input, Instruction::Exchange(Exchange { left, right })))
406}
407
408pub(crate) fn parse_fence(input: ParserInput) -> InternalParserResult<Instruction> {
410 let (input, qubits) = many0(parse_qubit)(input)?;
411
412 Ok((input, Instruction::Fence(Fence { qubits })))
413}
414
415pub(crate) fn parse_jump<'a>(input: ParserInput<'a>) -> InternalParserResult<'a, Instruction> {
417 let (input, target) = token!(Target(v))(input)?;
418 Ok((
419 input,
420 Instruction::Jump(Jump {
421 target: Target::Fixed(target),
422 }),
423 ))
424}
425
426pub(crate) fn parse_jump_when<'a>(input: ParserInput<'a>) -> InternalParserResult<'a, Instruction> {
428 let (input, target) = token!(Target(v))(input)?;
429 let (input, condition) = parse_memory_reference(input)?;
430 Ok((
431 input,
432 Instruction::JumpWhen(JumpWhen {
433 target: Target::Fixed(target),
434 condition,
435 }),
436 ))
437}
438
439pub(crate) fn parse_jump_unless<'a>(
441 input: ParserInput<'a>,
442) -> InternalParserResult<'a, Instruction> {
443 let (input, target) = token!(Target(v))(input)?;
444 let (input, condition) = parse_memory_reference(input)?;
445 Ok((
446 input,
447 Instruction::JumpUnless(JumpUnless {
448 target: Target::Fixed(target),
449 condition,
450 }),
451 ))
452}
453
454pub(crate) fn parse_label<'a>(input: ParserInput<'a>) -> InternalParserResult<'a, Instruction> {
456 let (input, name) = token!(Target(v))(input)?;
457 Ok((
458 input,
459 Instruction::Label(Label {
460 target: Target::Fixed(name),
461 }),
462 ))
463}
464
465pub(crate) fn parse_move(input: ParserInput) -> InternalParserResult<Instruction> {
467 let (input, destination) = parse_memory_reference(input)?;
468 let (input, source) = parse_arithmetic_operand(input)?;
469 Ok((
470 input,
471 Instruction::Move(Move {
472 destination,
473 source,
474 }),
475 ))
476}
477
478pub(crate) fn parse_load<'a>(input: ParserInput<'a>) -> InternalParserResult<'a, Instruction> {
480 let (input, destination) = parse_memory_reference(input)?;
481 let (input, source) = token!(Identifier(v))(input)?;
482 let (input, offset) = parse_memory_reference(input)?;
483
484 Ok((
485 input,
486 Instruction::Load(Load {
487 destination,
488 source,
489 offset,
490 }),
491 ))
492}
493
494pub(crate) fn parse_store<'a>(input: ParserInput<'a>) -> InternalParserResult<'a, Instruction> {
496 let (input, destination) = token!(Identifier(v))(input)?;
497 let (input, offset) = parse_memory_reference(input)?;
498 let (input, source) = parse_arithmetic_operand(input)?;
499
500 Ok((
501 input,
502 Instruction::Store(Store {
503 destination,
504 offset,
505 source,
506 }),
507 ))
508}
509
510pub(crate) fn parse_pragma<'a>(input: ParserInput<'a>) -> InternalParserResult<'a, Instruction> {
512 let (input, pragma_type) = token!(Identifier(v))(input)?;
513 let (input, arguments) = many0(alt((
514 map(token!(Identifier(v)), PragmaArgument::Identifier),
515 map(token!(Integer(i)), PragmaArgument::Integer),
516 )))(input)?;
517 let (input, data) = opt(token!(String(v)))(input)?;
518 Ok((
519 input,
520 Instruction::Pragma(Pragma {
521 name: pragma_type,
522 arguments,
523 data,
524 }),
525 ))
526}
527
528pub(crate) fn parse_pulse(input: ParserInput, blocking: bool) -> InternalParserResult<Instruction> {
530 let (input, frame) = parse_frame_identifier(input)?;
531 let (input, waveform) = parse_waveform_invocation(input)?;
532
533 Ok((
534 input,
535 Instruction::Pulse(Pulse {
536 blocking,
537 frame,
538 waveform,
539 }),
540 ))
541}
542
543pub(crate) fn parse_raw_capture(
545 input: ParserInput,
546 blocking: bool,
547) -> InternalParserResult<Instruction> {
548 let (input, frame) = parse_frame_identifier(input)?;
549 let (input, duration) = parse_expression(input)?;
550 let (input, memory_reference) = parse_memory_reference(input)?;
551
552 Ok((
553 input,
554 Instruction::RawCapture(RawCapture {
555 blocking,
556 frame,
557 duration,
558 memory_reference,
559 }),
560 ))
561}
562
563pub(crate) fn parse_reset(input: ParserInput) -> InternalParserResult<Instruction> {
565 let (input, qubit) = opt(parse_qubit)(input)?;
566
567 Ok((input, Instruction::Reset(Reset { qubit })))
568}
569
570pub(crate) fn parse_set_frequency(input: ParserInput) -> InternalParserResult<Instruction> {
572 let (input, frame) = parse_frame_identifier(input)?;
573 let (input, frequency) = parse_expression(input)?;
574
575 Ok((
576 input,
577 Instruction::SetFrequency(SetFrequency { frame, frequency }),
578 ))
579}
580
581pub(crate) fn parse_set_phase(input: ParserInput) -> InternalParserResult<Instruction> {
583 let (input, frame) = parse_frame_identifier(input)?;
584 let (input, phase) = parse_expression(input)?;
585
586 Ok((input, Instruction::SetPhase(SetPhase { frame, phase })))
587}
588
589pub(crate) fn parse_set_scale(input: ParserInput) -> InternalParserResult<Instruction> {
591 let (input, frame) = parse_frame_identifier(input)?;
592 let (input, scale) = parse_expression(input)?;
593
594 Ok((input, Instruction::SetScale(SetScale { frame, scale })))
595}
596
597pub(crate) fn parse_shift_frequency(input: ParserInput) -> InternalParserResult<Instruction> {
599 let (input, frame) = parse_frame_identifier(input)?;
600 let (input, frequency) = parse_expression(input)?;
601
602 Ok((
603 input,
604 Instruction::ShiftFrequency(ShiftFrequency { frame, frequency }),
605 ))
606}
607
608pub(crate) fn parse_shift_phase(input: ParserInput) -> InternalParserResult<Instruction> {
610 let (input, frame) = parse_frame_identifier(input)?;
611 let (input, phase) = parse_expression(input)?;
612
613 Ok((input, Instruction::ShiftPhase(ShiftPhase { frame, phase })))
614}
615
616pub(crate) fn parse_swap_phases(input: ParserInput) -> InternalParserResult<Instruction> {
618 let (input, frame_1) = parse_frame_identifier(input)?;
619 let (input, frame_2) = parse_frame_identifier(input)?;
620
621 Ok((
622 input,
623 Instruction::SwapPhases(SwapPhases { frame_1, frame_2 }),
624 ))
625}
626
627pub(crate) fn parse_measurement<'a>(
629 input: ParserInput<'a>,
630) -> InternalParserResult<'a, Instruction> {
631 let (input, name) = opt(preceded(token!(Bang), token!(Identifier(name))))(input)?;
632 let (input, qubit) = parse_qubit(input)?;
633 let (input, target) = match parse_memory_reference(input) {
634 Ok((input, target)) => (input, Some(target)),
635 Err(_) => (input, None),
636 };
637
638 Ok((
639 input,
640 Instruction::Measurement(Measurement {
641 name,
642 qubit,
643 target,
644 }),
645 ))
646}
647
648pub(crate) fn parse_include<'a>(input: ParserInput<'a>) -> InternalParserResult<'a, Instruction> {
650 let (input, filename) = token!(String(v))(input)?;
651 Ok((input, Instruction::Include(Include { filename })))
652}
653
654#[cfg(test)]
655mod tests {
656 use crate::expression::{
657 Expression, ExpressionFunction, FunctionCallExpression, InfixExpression, InfixOperator,
658 PrefixExpression, PrefixOperator,
659 };
660 use crate::instruction::{
661 Call, DefGateSequence, DefGateSequenceError, GateDefinition, GateSpecification, Offset,
662 PauliGate, PauliSum, PauliTerm, PragmaArgument, Sharing, UnresolvedCallArgument,
663 };
664 use crate::parser::lexer::lex;
665 use crate::parser::Token;
666 use crate::{imag, real};
667 use crate::{
668 instruction::{
669 CircuitDefinition, Declaration, Gate, Instruction, Measurement, MemoryReference,
670 Pragma, Qubit, ScalarType, Vector,
671 },
672 make_test,
673 };
674 use internment::ArcIntern;
675 use num_complex::Complex64;
676 use rstest::*;
677
678 use super::{parse_declare, parse_defcircuit, parse_defgate, parse_measurement, parse_pragma};
679
680 make_test!(
681 declare_instruction_length_1,
682 parse_declare,
683 "ro BIT",
684 Instruction::Declaration(Declaration {
685 name: "ro".to_owned(),
686 size: Vector {
687 data_type: ScalarType::Bit,
688 length: 1
689 },
690 sharing: None,
691 })
692 );
693
694 make_test!(
695 declare_instruction_length_n,
696 parse_declare,
697 "ro INTEGER[5]",
698 Instruction::Declaration(Declaration {
699 name: "ro".to_owned(),
700 size: Vector {
701 data_type: ScalarType::Integer,
702 length: 5
703 },
704 sharing: None,
705 })
706 );
707
708 make_test!(
709 declare_instruction_sharing,
710 parse_declare,
711 "ro REAL[1] SHARING bar",
712 Instruction::Declaration(Declaration {
713 name: "ro".to_owned(),
714 size: Vector {
715 data_type: ScalarType::Real,
716 length: 1,
717 },
718 sharing: Some(Sharing {
719 name: "bar".to_string(),
720 offsets: vec![]
721 })
722 })
723 );
724
725 make_test!(
726 declare_instruction_sharing_offsets,
727 parse_declare,
728 "ro REAL[1] SHARING bar OFFSET 2 BIT 3 INTEGER",
729 Instruction::Declaration(Declaration {
730 name: "ro".to_owned(),
731 size: Vector {
732 data_type: ScalarType::Real,
733 length: 1,
734 },
735 sharing: Some(Sharing {
736 name: "bar".to_string(),
737 offsets: vec![
738 Offset {
739 offset: 2,
740 data_type: ScalarType::Bit
741 },
742 Offset {
743 offset: 3,
744 data_type: ScalarType::Integer
745 }
746 ],
747 })
748 })
749 );
750
751 make_test!(
752 measure_into_register,
753 parse_measurement,
754 "0 ro[0]",
755 Instruction::Measurement(Measurement {
756 name: None,
757 qubit: Qubit::Fixed(0),
758 target: Some(MemoryReference {
759 name: String::from("ro"),
760 index: 0
761 })
762 })
763 );
764
765 make_test!(
766 named_measure_into_register,
767 parse_measurement,
768 "!midcircuit 0 ro[0]",
769 Instruction::Measurement(Measurement {
770 name: Some(String::from("midcircuit")),
771 qubit: Qubit::Fixed(0),
772 target: Some(MemoryReference {
773 name: String::from("ro"),
774 index: 0
775 })
776 })
777 );
778
779 make_test!(
780 measure_discard,
781 parse_measurement,
782 "0",
783 Instruction::Measurement(Measurement {
784 name: None,
785 qubit: Qubit::Fixed(0),
786 target: None
787 })
788 );
789
790 make_test!(
791 named_measure_discard,
792 parse_measurement,
793 "!midcircuit 0",
794 Instruction::Measurement(Measurement {
795 name: Some(String::from("midcircuit")),
796 qubit: Qubit::Fixed(0),
797 target: None
798 })
799 );
800
801 make_test!(
802 measure_named_qubit,
803 parse_measurement,
804 "q0 ro[0]",
805 Instruction::Measurement(Measurement {
806 name: None,
807 qubit: Qubit::Variable(String::from("q0")),
808 target: Some(MemoryReference {
809 name: String::from("ro"),
810 index: 0
811 })
812 })
813 );
814
815 make_test!(
816 named_measure_named_qubit,
817 parse_measurement,
818 "!midcircuit q0 ro[0]",
819 Instruction::Measurement(Measurement {
820 name: Some(String::from("midcircuit")),
821 qubit: Qubit::Variable(String::from("q0")),
822 target: Some(MemoryReference {
823 name: String::from("ro"),
824 index: 0
825 })
826 })
827 );
828
829 make_test!(
830 measure_named_qubit_discard,
831 parse_measurement,
832 "q0",
833 Instruction::Measurement(Measurement {
834 name: None,
835 qubit: Qubit::Variable(String::from("q0")),
836 target: None
837 })
838 );
839
840 make_test!(
841 named_measure_named_qubit_discard,
842 parse_measurement,
843 "!midcircuit q0",
844 Instruction::Measurement(Measurement {
845 name: Some(String::from("midcircuit")),
846 qubit: Qubit::Variable(String::from("q0")),
847 target: None
848 })
849 );
850
851 make_test!(
852 pragma_inline_json_single_quotes,
853 parse_pragma,
854 "FILTER-NODE q35_unclassified \"{'module':'lodgepole.filters.io','filter_type':'DataBuffer','source':'q35_ro_rx/filter','publish':true,'params':{},'_type':'FilterNode'}\"",
855 Instruction::Pragma(Pragma {
856 name: "FILTER-NODE".to_owned(),
857 arguments: vec![PragmaArgument::Identifier("q35_unclassified".to_string())],
858 data: Some("{'module':'lodgepole.filters.io','filter_type':'DataBuffer','source':'q35_ro_rx/filter','publish':true,'params':{},'_type':'FilterNode'}".to_owned())
859 })
860 );
861
862 make_test!(
863 pragma_inline_json_double_quotes,
864 parse_pragma,
865 r#"FILTER-NODE q35_unclassified "{\"module\":\"lodgepole.filters.io\",\"filter_type\":\"DataBuffer\",\"source\":\"q35_ro_rx/filter\",\"publish\":true,\"params\":{},\"_type\":\"FilterNode\"}""#,
866 Instruction::Pragma(Pragma {
867 name: "FILTER-NODE".to_owned(),
868 arguments: vec![PragmaArgument::Identifier("q35_unclassified".to_string())],
869 data: Some(r#"{"module":"lodgepole.filters.io","filter_type":"DataBuffer","source":"q35_ro_rx/filter","publish":true,"params":{},"_type":"FilterNode"}"#.to_owned())
870 })
871 );
872
873 make_test!(
874 pragma_integer_argument,
875 parse_pragma,
876 "READOUT-POVM 0 \"(0.9 0.19999999999999996 0.09999999999999998 0.8)\"",
877 Instruction::Pragma(Pragma {
878 name: "READOUT-POVM".to_string(),
879 arguments: vec![PragmaArgument::Integer(0)],
880 data: Some("(0.9 0.19999999999999996 0.09999999999999998 0.8)".to_string()),
881 })
882 );
883
884 make_test!(
885 pragma_identifier_and_integer_argument,
886 parse_pragma,
887 "NAME identifier 0 \"data\"",
888 Instruction::Pragma(Pragma {
889 name: "NAME".to_string(),
890 arguments: vec![
891 PragmaArgument::Identifier("identifier".to_string()),
892 PragmaArgument::Integer(0)
893 ],
894 data: Some("data".to_string()),
895 })
896 );
897
898 make_test!(
899 defcircuit_no_params,
900 parse_defcircuit,
901 "BELL a b:
902 H a
903 CNOT a b",
904 Instruction::CircuitDefinition(CircuitDefinition {
905 name: "BELL".to_owned(),
906 parameters: vec![],
907 qubit_variables: vec!["a".to_owned(), "b".to_owned()],
908 instructions: vec![
909 Instruction::Gate(Gate {
910 name: "H".to_owned(),
911 parameters: vec![],
912 qubits: vec![Qubit::Variable("a".to_owned())],
913 modifiers: vec![],
914 }),
915 Instruction::Gate(Gate {
916 name: "CNOT".to_owned(),
917 parameters: vec![],
918 qubits: vec![
919 Qubit::Variable("a".to_owned()),
920 Qubit::Variable("b".to_owned())
921 ],
922 modifiers: vec![],
923 })
924 ]
925 })
926 );
927
928 make_test!(
929 defcircuit_with_params,
930 parse_defcircuit,
931 "BELL(%a) a b:
932 RZ(%a) a
933 RX(%a) a
934 RZ(%a) a
935 CNOT a b",
936 Instruction::CircuitDefinition(CircuitDefinition {
937 name: "BELL".to_owned(),
938 parameters: vec!["a".to_owned()],
939 qubit_variables: vec!["a".to_owned(), "b".to_owned()],
940 instructions: vec![
941 Instruction::Gate(Gate {
942 name: "RZ".to_owned(),
943 parameters: vec![Expression::Variable("a".to_owned())],
944 qubits: vec![Qubit::Variable("a".to_owned())],
945 modifiers: vec![],
946 }),
947 Instruction::Gate(Gate {
948 name: "RX".to_owned(),
949 parameters: vec![Expression::Variable("a".to_owned())],
950 qubits: vec![Qubit::Variable("a".to_owned())],
951 modifiers: vec![],
952 }),
953 Instruction::Gate(Gate {
954 name: "RZ".to_owned(),
955 parameters: vec![Expression::Variable("a".to_owned())],
956 qubits: vec![Qubit::Variable("a".to_owned())],
957 modifiers: vec![],
958 }),
959 Instruction::Gate(Gate {
960 name: "CNOT".to_owned(),
961 parameters: vec![],
962 qubits: vec![
963 Qubit::Variable("a".to_owned()),
964 Qubit::Variable("b".to_owned())
965 ],
966 modifiers: vec![],
967 })
968 ]
969 })
970 );
971
972 make_test!(
973 defgate,
974 parse_defgate,
975 r#"H:
976 1/sqrt(2), 1/sqrt(2)
977 1/sqrt(2), -1/sqrt(2)"#,
978 {
979 let expression = Expression::Infix(InfixExpression {
981 left: ArcIntern::new(Expression::Number(real!(1.0))),
982 operator: InfixOperator::Slash,
983 right: ArcIntern::new(Expression::FunctionCall(FunctionCallExpression {
984 function: crate::expression::ExpressionFunction::SquareRoot,
985 expression: ArcIntern::new(Expression::Number(real!(2.0))),
986 })),
987 });
988
989 let negative_expression = Expression::Infix(InfixExpression {
991 left: ArcIntern::new(Expression::Prefix(PrefixExpression {
992 operator: PrefixOperator::Minus,
993 expression: ArcIntern::new(Expression::Number(real!(1.0))),
994 })),
995 operator: InfixOperator::Slash,
996 right: ArcIntern::new(Expression::FunctionCall(FunctionCallExpression {
997 function: crate::expression::ExpressionFunction::SquareRoot,
998 expression: ArcIntern::new(Expression::Number(real!(2.0))),
999 })),
1000 });
1001
1002 Instruction::GateDefinition(GateDefinition {
1003 name: "H".to_string(),
1004 parameters: vec![],
1005 specification: GateSpecification::Matrix(vec![
1006 vec![expression.clone(), expression.clone()],
1007 vec![expression, negative_expression],
1008 ]),
1009 })
1010 }
1011 );
1012
1013 make_test!(
1014 defgate_parameterized,
1015 parse_defgate,
1016 r#"RX(%theta):
1017 cos(%theta/2), -i*sin(%theta/2)
1018 -i*sin(%theta/2), cos(%theta/2)"#,
1019 Instruction::GateDefinition(GateDefinition {
1020 name: "RX".to_string(),
1021 parameters: vec!["theta".to_string()],
1022 specification: GateSpecification::Matrix(vec![
1023 vec![
1024 Expression::FunctionCall(FunctionCallExpression {
1025 function: crate::expression::ExpressionFunction::Cosine,
1026 expression: ArcIntern::new(Expression::Infix(InfixExpression {
1027 left: ArcIntern::new(Expression::Variable("theta".to_string())),
1028 operator: InfixOperator::Slash,
1029 right: ArcIntern::new(Expression::Number(real!(2.0))),
1030 })),
1031 }),
1032 Expression::Infix(InfixExpression {
1033 left: ArcIntern::new(Expression::Prefix(PrefixExpression {
1034 operator: PrefixOperator::Minus,
1035 expression: ArcIntern::new(Expression::Number(imag!(1f64)))
1036 })),
1037 operator: InfixOperator::Star,
1038 right: ArcIntern::new(Expression::FunctionCall(FunctionCallExpression {
1039 function: ExpressionFunction::Sine,
1040 expression: ArcIntern::new(Expression::Infix(InfixExpression {
1041 left: ArcIntern::new(Expression::Variable("theta".to_string())),
1042 operator: InfixOperator::Slash,
1043 right: ArcIntern::new(Expression::Number(real!(2.0))),
1044 })),
1045 })),
1046 })
1047 ],
1048 vec![
1049 Expression::Infix(InfixExpression {
1050 left: ArcIntern::new(Expression::Prefix(PrefixExpression {
1051 operator: PrefixOperator::Minus,
1052 expression: ArcIntern::new(Expression::Number(imag!(1f64)))
1053 })),
1054 operator: InfixOperator::Star,
1055 right: ArcIntern::new(Expression::FunctionCall(FunctionCallExpression {
1056 function: ExpressionFunction::Sine,
1057 expression: ArcIntern::new(Expression::Infix(InfixExpression {
1058 left: ArcIntern::new(Expression::Variable("theta".to_string())),
1059 operator: InfixOperator::Slash,
1060 right: ArcIntern::new(Expression::Number(real!(2.0))),
1061 })),
1062 })),
1063 }),
1064 Expression::FunctionCall(FunctionCallExpression {
1065 function: crate::expression::ExpressionFunction::Cosine,
1066 expression: ArcIntern::new(Expression::Infix(InfixExpression {
1067 left: ArcIntern::new(Expression::Variable("theta".to_string())),
1068 operator: InfixOperator::Slash,
1069 right: ArcIntern::new(Expression::Number(real!(2.0))),
1070 })),
1071 }),
1072 ],
1073 ]),
1074 })
1075 );
1076
1077 make_test!(
1078 defgate_permutation,
1079 parse_defgate,
1080 r#"CCNOT AS PERMUTATION:
1081 0, 1, 2, 3, 4, 5, 7, 6"#,
1082 Instruction::GateDefinition(GateDefinition {
1083 name: "CCNOT".to_string(),
1084 parameters: vec![],
1085 specification: GateSpecification::Permutation(vec![0, 1, 2, 3, 4, 5, 7, 6]),
1086 })
1087 );
1088
1089 make_test!(
1090 defgate_pauli_sum,
1091 parse_defgate,
1092 r#"PauliSumGate(%theta) p q AS PAULI-SUM:
1093 ZZ((-%theta)/4) p q
1094 Y(%theta/4) p
1095 X(%theta/4) q"#,
1096 Instruction::GateDefinition(GateDefinition {
1097 name: "PauliSumGate".to_string(),
1098 parameters: vec!["theta".to_string()],
1099 specification: GateSpecification::PauliSum(PauliSum {
1100 arguments: vec!["p".to_string(), "q".to_string()],
1101 terms: vec![
1102 PauliTerm {
1103 arguments: vec![
1104 (PauliGate::Z, "p".to_string()),
1105 (PauliGate::Z, "q".to_string())
1106 ],
1107 expression: Expression::Infix(InfixExpression {
1108 left: ArcIntern::new(Expression::Prefix(PrefixExpression {
1109 operator: PrefixOperator::Minus,
1110 expression: ArcIntern::new(Expression::Variable(
1111 "theta".to_string()
1112 ))
1113 })),
1114 operator: InfixOperator::Slash,
1115 right: ArcIntern::new(Expression::Number(real!(4.0)))
1116 }),
1117 },
1118 PauliTerm {
1119 arguments: vec![(PauliGate::Y, "p".to_string())],
1120 expression: Expression::Infix(InfixExpression {
1121 left: ArcIntern::new(Expression::Variable("theta".to_string())),
1122 operator: InfixOperator::Slash,
1123 right: ArcIntern::new(Expression::Number(real!(4.0)))
1124 }),
1125 },
1126 PauliTerm {
1127 arguments: vec![(PauliGate::X, "q".to_string())],
1128 expression: Expression::Infix(InfixExpression {
1129 left: ArcIntern::new(Expression::Variable("theta".to_string())),
1130 operator: InfixOperator::Slash,
1131 right: ArcIntern::new(Expression::Number(real!(4.0)))
1132 }),
1133 },
1134 ]
1135 })
1136 })
1137 );
1138
1139 struct ParseCallTestCase {
1141 input: &'static str,
1143 remainder: Vec<Token>,
1145 expected: Result<Call, String>,
1147 }
1148
1149 impl ParseCallTestCase {
1150 fn case_01() -> Self {
1152 Self {
1153 input: "foo integer[0] 1.0 bar",
1154 remainder: vec![],
1155 expected: Ok(Call {
1156 name: "foo".to_string(),
1157 arguments: vec![
1158 UnresolvedCallArgument::MemoryReference(MemoryReference {
1159 name: "integer".to_string(),
1160 index: 0,
1161 }),
1162 UnresolvedCallArgument::Immediate(real!(1.0)),
1163 UnresolvedCallArgument::Identifier("bar".to_string()),
1164 ],
1165 }),
1166 }
1167 }
1168
1169 fn case_02() -> Self {
1171 Self {
1172 input: "foo",
1173 remainder: vec![],
1174 expected: Ok(Call {
1175 name: "foo".to_string(),
1176 arguments: vec![],
1177 }),
1178 }
1179 }
1180
1181 fn case_03() -> Self {
1183 Self {
1184 input: "INCLUDE",
1185 remainder: vec![],
1186 expected: Err(
1187 "ExpectedToken { actual: COMMAND(INCLUDE), expected: \"Identifier\" }"
1188 .to_string(),
1189 ),
1190 }
1191 }
1192
1193 fn case_04() -> Self {
1195 Self {
1196 input: "foo integer[0] 1.0 bar; baz",
1197 remainder: vec![Token::Semicolon, Token::Identifier("baz".to_string())],
1198 expected: Ok(Call {
1199 name: "foo".to_string(),
1200 arguments: vec![
1201 UnresolvedCallArgument::MemoryReference(MemoryReference {
1202 name: "integer".to_string(),
1203 index: 0,
1204 }),
1205 UnresolvedCallArgument::Immediate(real!(1.0)),
1206 UnresolvedCallArgument::Identifier("bar".to_string()),
1207 ],
1208 }),
1209 }
1210 }
1211 }
1212
1213 #[rstest]
1215 #[case(ParseCallTestCase::case_01())]
1216 #[case(ParseCallTestCase::case_02())]
1217 #[case(ParseCallTestCase::case_03())]
1218 #[case(ParseCallTestCase::case_04())]
1219 fn test_parse_call(#[case] test_case: ParseCallTestCase) {
1220 let input = ::nom_locate::LocatedSpan::new(test_case.input);
1221 let tokens = lex(input).unwrap();
1222 match (test_case.expected, super::parse_call(&tokens)) {
1223 (Ok(expected), Ok((remainder, parsed))) => {
1224 assert_eq!(parsed, Instruction::Call(expected));
1225 let remainder: Vec<_> = remainder.iter().map(|t| t.as_token().clone()).collect();
1226 assert_eq!(remainder, test_case.remainder);
1227 }
1228 (Ok(expected), Err(e)) => {
1229 panic!("Expected {expected:?}, got error: {e:?}");
1230 }
1231 (Err(expected), Ok((_, parsed))) => {
1232 panic!("Expected error: {expected:?}, got {parsed:?}");
1233 }
1234 (Err(expected), Err(found)) => {
1235 let found = format!("{found:?}");
1236 assert!(found.contains(&expected), "`{expected}` not in `{found}`");
1237 }
1238 }
1239 }
1240
1241 struct ParseGateDefinitionTestCase {
1242 input: &'static str,
1244 remainder: Vec<Token>,
1246 expected: Result<GateDefinition, String>,
1248 }
1249
1250 impl ParseGateDefinitionTestCase {
1251 fn simple_sequence() -> Self {
1252 const SIMPLE_SEQUENCE: &str = r"seq1(%param01) q1 AS SEQUENCE:
1253 RX(%param01) q1";
1254 let gate1 = Gate::new(
1255 "RX",
1256 vec![Expression::Variable("param01".to_string())],
1257 vec![Qubit::Variable("q1".to_string())],
1258 vec![],
1259 )
1260 .expect("must be valid gate");
1261 let gate_sequence = DefGateSequence::try_new(vec!["q1".to_string()], vec![gate1])
1262 .expect("must be valid sequence");
1263 Self {
1264 input: SIMPLE_SEQUENCE,
1265 remainder: vec![],
1266 expected: Ok(GateDefinition {
1267 name: "seq1".to_string(),
1268 parameters: vec!["param01".to_string()],
1269 specification: GateSpecification::Sequence(gate_sequence),
1270 }),
1271 }
1272 }
1273
1274 fn simple_2q() -> Self {
1275 const SIMPLE_2Q: &str = r"seq1(%param01, %param02) q1 q2 AS SEQUENCE:
1276 RX(%param01) q1
1277 RX(%param02) q2";
1278 let gate1 = Gate::new(
1279 "RX",
1280 vec![Expression::Variable("param01".to_string())],
1281 vec![Qubit::Variable("q1".to_string())],
1282 vec![],
1283 )
1284 .expect("must be valid gate");
1285 let gate2 = Gate::new(
1286 "RX",
1287 vec![Expression::Variable("param02".to_string())],
1288 vec![Qubit::Variable("q2".to_string())],
1289 vec![],
1290 )
1291 .expect("must be valid gate");
1292 let gate_sequence = DefGateSequence::try_new(
1293 vec!["q1".to_string(), "q2".to_string()],
1294 vec![gate1, gate2],
1295 )
1296 .expect("must be valid sequence");
1297 Self {
1298 input: SIMPLE_2Q,
1299 remainder: vec![],
1300 expected: Ok(GateDefinition {
1301 name: "seq1".to_string(),
1302 parameters: vec!["param01".to_string(), "param02".to_string()],
1303 specification: GateSpecification::Sequence(gate_sequence),
1304 }),
1305 }
1306 }
1307
1308 fn no_parameters() -> Self {
1309 const NO_PARAMETERS: &str = r"seq1() q1 AS SEQUENCE:
1310 RX(pi/2) q1";
1311 let gate1 = Gate::new(
1312 "RX",
1313 vec![Expression::Infix(InfixExpression {
1314 left: ArcIntern::new(Expression::PiConstant()),
1315 operator: InfixOperator::Slash,
1316 right: ArcIntern::new(Expression::Number(Complex64 { re: 2.0, im: 0.0 })),
1317 })],
1318 vec![Qubit::Variable("q1".to_string())],
1319 vec![],
1320 )
1321 .expect("must be valid gate");
1322 let gate_sequence = DefGateSequence::try_new(vec!["q1".to_string()], vec![gate1])
1323 .expect("must be valid sequence");
1324 Self {
1325 input: NO_PARAMETERS,
1326 remainder: vec![],
1327 expected: Ok(GateDefinition {
1328 name: "seq1".to_string(),
1329 parameters: vec![],
1330 specification: GateSpecification::Sequence(gate_sequence),
1331 }),
1332 }
1333 }
1334
1335 fn no_parentheses() -> Self {
1336 const NO_PARENTHESES: &str = r"seq1 q1 AS SEQUENCE:
1337 RX(pi/2) q1";
1338 let gate1 = Gate::new(
1339 "RX",
1340 vec![Expression::Infix(InfixExpression {
1341 left: ArcIntern::new(Expression::PiConstant()),
1342 operator: InfixOperator::Slash,
1343 right: ArcIntern::new(Expression::Number(Complex64 { re: 2.0, im: 0.0 })),
1344 })],
1345 vec![Qubit::Variable("q1".to_string())],
1346 vec![],
1347 )
1348 .expect("must be valid gate");
1349 let gate_sequence = DefGateSequence::try_new(vec!["q1".to_string()], vec![gate1])
1350 .expect("must be valid sequence");
1351 Self {
1352 input: NO_PARENTHESES,
1353 remainder: vec![],
1354 expected: Ok(GateDefinition {
1355 name: "seq1".to_string(),
1356 parameters: vec![],
1357 specification: GateSpecification::Sequence(gate_sequence),
1358 }),
1359 }
1360 }
1361
1362 fn unused_argument() -> Self {
1363 const NO_PARAMETERS: &str = r"seq1(%param01) q1 q2 AS SEQUENCE:
1364 RX(pi/2) q1";
1365 let gate1 = Gate::new(
1366 "RX",
1367 vec![Expression::Infix(InfixExpression {
1368 left: ArcIntern::new(Expression::PiConstant()),
1369 operator: InfixOperator::Slash,
1370 right: ArcIntern::new(Expression::Number(Complex64 { re: 2.0, im: 0.0 })),
1371 })],
1372 vec![Qubit::Variable("q1".to_string())],
1373 vec![],
1374 )
1375 .expect("must be valid gate");
1376 let gate_sequence =
1377 DefGateSequence::try_new(vec!["q1".to_string(), "q2".to_string()], vec![gate1])
1378 .expect("must be valid sequence");
1379 Self {
1380 input: NO_PARAMETERS,
1381 remainder: vec![],
1382 expected: Ok(GateDefinition {
1383 name: "seq1".to_string(),
1384 parameters: vec!["param01".to_string()],
1385 specification: GateSpecification::Sequence(gate_sequence),
1386 }),
1387 }
1388 }
1389
1390 fn error_undefined_gate_sequence_element_qubit() -> Self {
1391 const UNDEFINED_QUBIT: &str = r"seq1(%param01) q1 AS SEQUENCE:
1392 RZ(%param01) q1
1393 ISWAP q1 doesnt_exist_qubit";
1394 Self {
1395 input: UNDEFINED_QUBIT,
1396 remainder: vec![],
1397 expected: Err(format!(
1398 "{:?}",
1399 DefGateSequenceError::UndefinedGateSequenceElementQubit {
1400 gate_index: 1,
1401 qubit_argument_index: 1,
1402 argument_name: "doesnt_exist_qubit".to_string(),
1403 }
1404 )),
1405 }
1406 }
1407
1408 fn error_invalid_gate_sequence_element_qubit() -> Self {
1409 const INVALID_QUBIT: &str = r"seq1(%param01) q1 AS SEQUENCE:
1410 RZ(%param01) q1
1411 ISWAP q1 3";
1412 Self {
1413 input: INVALID_QUBIT,
1414 remainder: vec![],
1415 expected: Err(format!(
1416 "{:?}",
1417 DefGateSequenceError::InvalidGateSequenceElementQubit {
1418 gate_index: 1,
1419 qubit_argument_index: 1,
1420 qubit: Qubit::Fixed(3)
1421 }
1422 )),
1423 }
1424 }
1425
1426 fn error_at_least_one_qubit() -> Self {
1427 const AT_LEAST_ONE_QUBIT: &str = r"seq1() AS SEQUENCE:
1428 RX(pi/2) q1";
1429 Self {
1430 input: AT_LEAST_ONE_QUBIT,
1431 remainder: vec![],
1432 expected: Err(format!(
1433 "{:?}",
1434 DefGateSequenceError::AtLeastOneQubitParameterRequired
1435 )),
1436 }
1437 }
1438 }
1439
1440 #[rstest]
1441 #[case::simple_sequence(ParseGateDefinitionTestCase::simple_sequence())]
1442 #[case::simple_2q(ParseGateDefinitionTestCase::simple_2q())]
1443 #[case::no_parameters(ParseGateDefinitionTestCase::no_parameters())]
1444 #[case::no_parentheses(ParseGateDefinitionTestCase::no_parentheses())]
1445 #[case::unused_argument(ParseGateDefinitionTestCase::unused_argument())]
1446 #[case::error_undefined_gate_sequence_element_qubit(
1447 ParseGateDefinitionTestCase::error_undefined_gate_sequence_element_qubit()
1448 )]
1449 #[case::error_invalid_gate_sequence_element_qubit(
1450 ParseGateDefinitionTestCase::error_invalid_gate_sequence_element_qubit()
1451 )]
1452 #[case::error_at_least_one_qubit(ParseGateDefinitionTestCase::error_at_least_one_qubit())]
1453 fn test_parse_gate_definition(#[case] test_case: ParseGateDefinitionTestCase) {
1454 let input = ::nom_locate::LocatedSpan::new(test_case.input);
1455 let tokens = lex(input).unwrap();
1456 match (test_case.expected, super::parse_defgate(&tokens)) {
1457 (Ok(expected), Ok((remainder, parsed))) => {
1458 assert_eq!(parsed, Instruction::GateDefinition(expected));
1459 let remainder: Vec<_> = remainder.iter().map(|t| t.as_token().clone()).collect();
1460 assert_eq!(remainder, test_case.remainder);
1461 }
1462 (Ok(expected), Err(e)) => {
1463 panic!("Expected {expected:?}, got error: {e:?}");
1464 }
1465 (Err(expected), Ok((_, parsed))) => {
1466 panic!("Expected error: {expected:?}, got {parsed:?}");
1467 }
1468 (Err(expected), Err(found)) => {
1469 let found = format!("{found:?}");
1470 assert!(found.contains(&expected), "`{expected}` not in `{found}`");
1471 }
1472 }
1473 }
1474}