microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.1.3

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

compiler/qsc_eval/src/tests.rs

3531lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#![allow(clippy::needless_raw_string_hashes)]
5
6use crate::{
7 backend::{Backend, SparseSim},
8 debug::{map_hir_package_to_fir, Frame},
9 output::{GenericReceiver, Receiver},
10 val, Env, Error, State, StepAction, StepResult, Value,
11};
12use expect_test::{expect, Expect};
13use indoc::indoc;
14use qsc_fir::fir;
15use qsc_fir::fir::{ExprId, PackageId, PackageStoreLookup};
16use qsc_frontend::compile::{self, compile, PackageStore, RuntimeCapabilityFlags, SourceMap};
17use qsc_passes::{run_core_passes, run_default_passes, PackageType};
18
19/// Evaluates the given expression with the given context.
20/// Creates a new environment and simulator.
21/// # Errors
22/// Returns the first error encountered during execution.
23pub(super) fn eval_expr(
24 expr: ExprId,
25 sim: &mut impl Backend<ResultType = impl Into<val::Result>>,
26 globals: &impl PackageStoreLookup,
27 package: PackageId,
28 out: &mut impl Receiver,
29) -> Result<Value, (Error, Vec<Frame>)> {
30 let mut state = State::new(package, None);
31 let mut env = Env::default();
32 state.push_expr(expr);
33 let StepResult::Return(value) =
34 state.eval(globals, &mut env, sim, out, &[], StepAction::Continue)?
35 else {
36 unreachable!("eval_expr should always return a value");
37 };
38 Ok(value)
39}
40
41fn check_expr(file: &str, expr: &str, expect: &Expect) {
42 let mut fir_lowerer = crate::lower::Lowerer::new();
43 let mut core = compile::core();
44 run_core_passes(&mut core);
45 let core_fir = fir_lowerer.lower_package(&core.package);
46 let mut store = PackageStore::new(core);
47
48 let mut std = compile::std(&store, RuntimeCapabilityFlags::all());
49 assert!(std.errors.is_empty());
50 assert!(run_default_passes(
51 store.core(),
52 &mut std,
53 PackageType::Lib,
54 RuntimeCapabilityFlags::all()
55 )
56 .is_empty());
57 let std_fir = fir_lowerer.lower_package(&std.package);
58 let std_id = store.insert(std);
59
60 let sources = SourceMap::new([("test".into(), file.into())], Some(expr.into()));
61 let mut unit = compile(&store, &[std_id], sources, RuntimeCapabilityFlags::all());
62 assert!(unit.errors.is_empty(), "{:?}", unit.errors);
63 let pass_errors = run_default_passes(
64 store.core(),
65 &mut unit,
66 PackageType::Lib,
67 RuntimeCapabilityFlags::all(),
68 );
69 assert!(pass_errors.is_empty(), "{pass_errors:?}");
70 let unit_fir = fir_lowerer.lower_package(&unit.package);
71 let entry = unit_fir.entry.expect("package should have entry");
72 let id = store.insert(unit);
73
74 let mut fir_store = fir::PackageStore::new();
75 fir_store.insert(
76 map_hir_package_to_fir(qsc_hir::hir::PackageId::CORE),
77 core_fir,
78 );
79 fir_store.insert(map_hir_package_to_fir(std_id), std_fir);
80 fir_store.insert(map_hir_package_to_fir(id), unit_fir);
81
82 let mut out = Vec::new();
83 match eval_expr(
84 entry,
85 &mut SparseSim::new(),
86 &fir_store,
87 map_hir_package_to_fir(id),
88 &mut GenericReceiver::new(&mut out),
89 ) {
90 Ok(value) => expect.assert_eq(&value.to_string()),
91 Err(err) => expect.assert_debug_eq(&err),
92 }
93}
94
95#[test]
96fn array_expr() {
97 check_expr("", "[1, 2, 3]", &expect!["[1, 2, 3]"]);
98}
99
100#[test]
101fn array_repeat_expr() {
102 check_expr("", "[4, size = 3]", &expect!["[4, 4, 4]"]);
103}
104
105#[test]
106fn block_expr() {
107 check_expr(
108 "",
109 indoc! { "{
110 let x = 1;
111 let y = x;
112 y
113 }"},
114 &expect!["1"],
115 );
116}
117
118#[test]
119fn block_empty_is_unit_expr() {
120 check_expr("", "{}", &expect!["()"]);
121}
122
123#[test]
124fn block_shadowing_expr() {
125 check_expr(
126 "",
127 indoc! { "{
128 let x = 1;
129 let x = 2;
130 x
131 }"},
132 &expect!["2"],
133 );
134}
135
136#[test]
137fn block_nested_shadowing_expr() {
138 check_expr(
139 "",
140 indoc! { "{
141 let x = 1;
142 let y = {
143 let x = 2;
144 x
145 };
146 (y, x)
147 }"},
148 &expect!["(2, 1)"],
149 );
150}
151
152#[test]
153fn block_let_bind_tuple_expr() {
154 check_expr(
155 "",
156 indoc! {"{
157 let x = (1, 2);
158 let (y, z) = x;
159 (z, y)
160 }"},
161 &expect!["(2, 1)"],
162 );
163}
164
165#[test]
166fn block_mutable_expr() {
167 check_expr(
168 "",
169 indoc! {"{
170 mutable x = 0;
171 x
172 }"},
173 &expect!["0"],
174 );
175}
176
177#[test]
178fn block_mutable_update_expr() {
179 check_expr(
180 "",
181 indoc! {"{
182 mutable x = 0;
183 set x = 1;
184 x
185 }"},
186 &expect!["1"],
187 );
188}
189
190#[test]
191fn block_mutable_update_tuple_expr() {
192 check_expr(
193 "",
194 indoc! {"{
195 mutable x = (0, 1);
196 set x = (1, 2);
197 x
198 }"},
199 &expect!["(1, 2)"],
200 );
201}
202
203#[test]
204fn block_mutable_update_tuple_item_expr() {
205 check_expr(
206 "",
207 indoc! {"{
208 mutable (x, y) = (0, 1);
209 set (x, y) = (1, 2);
210 (x, y)
211 }"},
212 &expect!["(1, 2)"],
213 );
214}
215
216#[test]
217fn block_mutable_update_tuple_hole_expr() {
218 check_expr(
219 "",
220 indoc! {"{
221 mutable (x, y) = (0, 1);
222 set (_, y) = (1, 2);
223 (x, y)
224 }"},
225 &expect!["(0, 2)"],
226 );
227}
228
229#[test]
230fn block_mutable_nested_scopes_expr() {
231 check_expr(
232 "",
233 indoc! {"{
234 mutable x = 0;
235 {
236 mutable y = 1;
237 set x = y;
238 }
239 x
240 }"},
241 &expect!["1"],
242 );
243}
244
245#[test]
246fn block_mutable_nested_scopes_shadowing_expr() {
247 check_expr(
248 "",
249 indoc! {"{
250 mutable x = 0;
251 {
252 mutable x = 1;
253 set x = 2;
254 }
255 x
256 }"},
257 &expect!["0"],
258 );
259}
260
261#[test]
262fn block_qubit_use_expr() {
263 check_expr(
264 "",
265 indoc! {"{
266 use q = Qubit();
267 q
268 }"},
269 &expect!["Qubit0"],
270 );
271}
272
273#[test]
274fn block_qubit_use_use_expr() {
275 check_expr(
276 "",
277 indoc! {"{
278 use q = Qubit();
279 use q1 = Qubit();
280 q1
281 }"},
282 &expect!["Qubit1"],
283 );
284}
285
286#[test]
287fn block_qubit_use_reuse_expr() {
288 check_expr(
289 "",
290 indoc! {"{
291 {
292 use q = Qubit();
293 }
294 use q = Qubit();
295 q
296 }"},
297 &expect!["Qubit0"],
298 );
299}
300
301#[test]
302fn block_qubit_use_scope_reuse_expr() {
303 check_expr(
304 "",
305 indoc! {"{
306 use q = Qubit() {
307 }
308 use q = Qubit();
309 q
310 }"},
311 &expect!["Qubit0"],
312 );
313}
314
315#[test]
316fn block_qubit_use_array_expr() {
317 check_expr(
318 "",
319 indoc! {"{
320 use q = Qubit[3];
321 q
322 }"},
323 &expect!["[Qubit0, Qubit1, Qubit2]"],
324 );
325}
326
327#[test]
328fn block_qubit_use_array_invalid_count_expr() {
329 check_expr(
330 "",
331 indoc! {"{
332 use q = Qubit[-3];
333 q
334 }"},
335 &expect![[r#"
336 (
337 UserFail(
338 "Cannot allocate qubit array with a negative length",
339 PackageSpan {
340 package: PackageId(
341 0,
342 ),
343 span: Span {
344 lo: 1568,
345 hi: 1625,
346 },
347 },
348 ),
349 [
350 Frame {
351 span: Span {
352 lo: 1573,
353 hi: 1625,
354 },
355 id: StoreItemId {
356 package: PackageId(
357 0,
358 ),
359 item: LocalItemId(
360 6,
361 ),
362 },
363 caller: PackageId(
364 2,
365 ),
366 functor: FunctorApp {
367 adjoint: false,
368 controlled: 0,
369 },
370 },
371 ],
372 )
373 "#]],
374 );
375}
376
377#[test]
378fn block_qubit_use_tuple_expr() {
379 check_expr(
380 "",
381 indoc! {"{
382 use q = (Qubit[3], Qubit(), Qubit());
383 q
384 }"},
385 &expect!["([Qubit0, Qubit1, Qubit2], Qubit3, Qubit4)"],
386 );
387}
388
389#[test]
390fn block_qubit_use_nested_tuple_expr() {
391 check_expr(
392 "",
393 indoc! {"{
394 use q = (Qubit[3], (Qubit(), Qubit()));
395 q
396 }"},
397 &expect!["([Qubit0, Qubit1, Qubit2], (Qubit3, Qubit4))"],
398 );
399}
400
401#[test]
402fn binop_add_array() {
403 check_expr("", "[1, 2] + [3, 4]", &expect!["[1, 2, 3, 4]"]);
404}
405
406#[test]
407fn binop_add_bigint() {
408 check_expr(
409 "",
410 "2L + 9_223_372_036_854_775_808L",
411 &expect!["9223372036854775810"],
412 );
413}
414
415#[test]
416fn binop_add_double() {
417 check_expr("", "2.8 + 5.4", &expect!["8.2"]);
418}
419
420#[test]
421fn binop_add_int() {
422 check_expr("", "28 + 54", &expect!["82"]);
423}
424
425#[test]
426fn binop_add_int_wrap() {
427 check_expr(
428 "",
429 "0x7FFFFFFFFFFFFFFF + 1",
430 &expect!["-9223372036854775808"],
431 );
432}
433
434#[test]
435fn binop_add_string() {
436 check_expr("", r#""Hello," + " World!""#, &expect!["Hello, World!"]);
437}
438
439#[test]
440fn binop_andb_bigint() {
441 check_expr("", "28L &&& 54L", &expect!["20"]);
442}
443
444#[test]
445fn binop_andb_int() {
446 check_expr("", "28 &&& 54", &expect!["20"]);
447}
448
449#[test]
450fn binop_andl() {
451 check_expr("", "true and true", &expect!["true"]);
452}
453
454#[test]
455fn binop_andl_false() {
456 check_expr("", "true and false", &expect!["false"]);
457}
458
459#[test]
460fn binop_andl_no_shortcut() {
461 check_expr(
462 "",
463 r#"true and (fail "Should Fail")"#,
464 &expect![[r#"
465 (
466 UserFail(
467 "Should Fail",
468 PackageSpan {
469 package: PackageId(
470 2,
471 ),
472 span: Span {
473 lo: 10,
474 hi: 28,
475 },
476 },
477 ),
478 [],
479 )
480 "#]],
481 );
482}
483
484#[test]
485fn binop_div_bigint() {
486 check_expr("", "12L / 3L", &expect!["4"]);
487}
488
489#[test]
490fn binop_div_bigint_zero() {
491 check_expr(
492 "",
493 "12L / 0L",
494 &expect![[r#"
495 (
496 DivZero(
497 PackageSpan {
498 package: PackageId(
499 2,
500 ),
501 span: Span {
502 lo: 6,
503 hi: 8,
504 },
505 },
506 ),
507 [],
508 )
509 "#]],
510 );
511}
512
513#[test]
514fn binop_div_int() {
515 check_expr("", "12 / 3", &expect!["4"]);
516}
517
518#[test]
519fn binop_div_int_wrap() {
520 check_expr(
521 "",
522 "(-0x8000000000000000) / (-1)",
523 &expect!["-9223372036854775808"],
524 );
525}
526
527#[test]
528fn binop_div_int_zero() {
529 check_expr(
530 "",
531 "12 / 0",
532 &expect![[r#"
533 (
534 DivZero(
535 PackageSpan {
536 package: PackageId(
537 2,
538 ),
539 span: Span {
540 lo: 5,
541 hi: 6,
542 },
543 },
544 ),
545 [],
546 )
547 "#]],
548 );
549}
550
551#[test]
552fn binop_div_double() {
553 check_expr("", "1.2 / 0.3", &expect!["4.0"]);
554}
555
556#[test]
557fn binop_div_double_inf() {
558 check_expr("", "1.2 / 0.0", &expect!["inf"]);
559}
560
561#[test]
562fn binop_div_double_neg_inf() {
563 check_expr("", "1.2 / -0.0", &expect!["-inf"]);
564}
565
566#[test]
567fn binop_div_double_nan() {
568 check_expr("", "0.0 / 0.0", &expect!["NaN"]);
569}
570
571#[test]
572fn binop_eq_double() {
573 check_expr("", "1.2 / 0.3", &expect!["4.0"]);
574}
575
576#[test]
577fn binop_equal_array() {
578 check_expr("", "[1, 2, 3] == [1, 2, 3]", &expect!["true"]);
579}
580
581#[test]
582fn binop_equal_array_false_content() {
583 check_expr("", "[1, 2, 3] == [1, 0, 3]", &expect!["false"]);
584}
585
586#[test]
587fn binop_equal_array_false_length() {
588 check_expr("", "[1, 2, 3] == [1, 2, 3, 4]", &expect!["false"]);
589}
590
591#[test]
592fn binop_equal_bigint() {
593 check_expr("", "18L == 18L", &expect!["true"]);
594}
595
596#[test]
597fn binop_equal_bigint_false() {
598 check_expr("", "18L == 8L", &expect!["false"]);
599}
600
601#[test]
602fn binop_equal_bool() {
603 check_expr("", "false == false", &expect!["true"]);
604}
605
606#[test]
607fn binop_equal_bool_false() {
608 check_expr("", "false == true", &expect!["false"]);
609}
610
611#[test]
612fn binop_equal_double() {
613 check_expr("", "1.254 == 1.254", &expect!["true"]);
614}
615
616#[test]
617fn binop_equal_double_false() {
618 check_expr("", "1.254 == 1.25", &expect!["false"]);
619}
620
621#[test]
622fn binop_equal_int() {
623 check_expr("", "42 == 42", &expect!["true"]);
624}
625
626#[test]
627fn binop_equal_int_false() {
628 check_expr("", "42 == 43", &expect!["false"]);
629}
630
631#[test]
632fn binop_equal_pauli() {
633 check_expr("", "PauliX == PauliX", &expect!["true"]);
634}
635
636#[test]
637fn binop_equal_pauli_false() {
638 check_expr("", "PauliX == PauliZ", &expect!["false"]);
639}
640
641#[test]
642fn binop_equal_range() {
643 check_expr("", "(0..4) == (0..4)", &expect!["true"]);
644}
645
646#[test]
647fn binop_equal_range_false() {
648 check_expr("", "(0..2..4) == (0..4)", &expect!["false"]);
649}
650
651#[test]
652fn binop_equal_result() {
653 check_expr("", "One == One", &expect!["true"]);
654}
655
656#[test]
657fn binop_equal_result_false() {
658 check_expr("", "One == Zero", &expect!["false"]);
659}
660
661#[test]
662fn binop_equal_string() {
663 check_expr("", r#""foo" == "foo""#, &expect!["true"]);
664}
665
666#[test]
667fn binop_equal_string_false() {
668 check_expr("", r#""foo" == "bar""#, &expect!["false"]);
669}
670
671#[test]
672fn binop_equal_tuple() {
673 check_expr("", "(1, 2, 3) == (1, 2, 3)", &expect!["true"]);
674}
675
676#[test]
677fn binop_equal_tuple_false_content() {
678 check_expr("", "(1, 2, 3) == (1, -2, 3)", &expect!["false"]);
679}
680
681#[test]
682fn binop_exp_bigint() {
683 check_expr("", "2L^3", &expect!["8"]);
684}
685
686#[test]
687fn binop_exp_bigint_zero_exp() {
688 check_expr("", "2L^0", &expect!["1"]);
689}
690
691#[test]
692fn binop_exp_bigint_neg_zero_exp() {
693 check_expr("", "(-2L)^0", &expect!["1"]);
694}
695
696#[test]
697fn binop_exp_bigint_negative_exp() {
698 check_expr(
699 "",
700 "2L^-3",
701 &expect![[r#"
702 (
703 InvalidNegativeInt(
704 -3,
705 PackageSpan {
706 package: PackageId(
707 2,
708 ),
709 span: Span {
710 lo: 3,
711 hi: 5,
712 },
713 },
714 ),
715 [],
716 )
717 "#]],
718 );
719}
720
721#[test]
722fn binop_exp_bigint_too_large() {
723 check_expr(
724 "",
725 "2L^9_223_372_036_854_775_807",
726 &expect![[r#"
727 (
728 IntTooLarge(
729 9223372036854775807,
730 PackageSpan {
731 package: PackageId(
732 2,
733 ),
734 span: Span {
735 lo: 3,
736 hi: 28,
737 },
738 },
739 ),
740 [],
741 )
742 "#]],
743 );
744}
745
746#[test]
747fn binop_exp_double() {
748 check_expr("", "2.3^3.1", &expect!["13.22380059125472"]);
749}
750
751#[test]
752fn binop_exp_double_negative_exp() {
753 check_expr("", "2.3^-3.1", &expect!["0.07562122501010253"]);
754}
755
756#[test]
757fn binop_exp_int() {
758 check_expr("", "2^3", &expect!["8"]);
759}
760
761#[test]
762fn binop_exp_int_zero_exp() {
763 check_expr("", "2^0", &expect!["1"]);
764}
765
766#[test]
767fn binop_exp_int_neg_zero_exp() {
768 check_expr("", "(-2)^0", &expect!["1"]);
769}
770
771#[test]
772fn binop_exp_int_negative_exp() {
773 check_expr(
774 "",
775 "2^-3",
776 &expect![[r#"
777 (
778 InvalidNegativeInt(
779 -3,
780 PackageSpan {
781 package: PackageId(
782 2,
783 ),
784 span: Span {
785 lo: 2,
786 hi: 4,
787 },
788 },
789 ),
790 [],
791 )
792 "#]],
793 );
794}
795
796#[test]
797fn binop_exp_int_too_large() {
798 check_expr(
799 "",
800 "100^50",
801 &expect![[r#"
802 (
803 IntTooLarge(
804 50,
805 PackageSpan {
806 package: PackageId(
807 2,
808 ),
809 span: Span {
810 lo: 4,
811 hi: 6,
812 },
813 },
814 ),
815 [],
816 )
817 "#]],
818 );
819}
820
821#[test]
822fn binop_gt_bigint() {
823 check_expr("", "23L > 3L", &expect!["true"]);
824}
825
826#[test]
827fn binop_gt_bigint_false() {
828 check_expr("", "2L > 3L", &expect!["false"]);
829}
830
831#[test]
832fn binop_gt_int() {
833 check_expr("", "23 > 3", &expect!["true"]);
834}
835
836#[test]
837fn binop_gt_int_false() {
838 check_expr("", "2 > 3", &expect!["false"]);
839}
840
841#[test]
842fn binop_gt_double() {
843 check_expr("", "2.3 > 0.3", &expect!["true"]);
844}
845
846#[test]
847fn binop_gt_double_false() {
848 check_expr("", "0.2 > 0.3", &expect!["false"]);
849}
850
851#[test]
852fn binop_gte_bigint() {
853 check_expr("", "23L >= 3L", &expect!["true"]);
854}
855
856#[test]
857fn binop_gte_bigint_false() {
858 check_expr("", "2L >= 3L", &expect!["false"]);
859}
860
861#[test]
862fn binop_gte_bigint_eq() {
863 check_expr("", "3L >= 3L", &expect!["true"]);
864}
865
866#[test]
867fn binop_gte_int() {
868 check_expr("", "23 >= 3", &expect!["true"]);
869}
870
871#[test]
872fn binop_gte_int_false() {
873 check_expr("", "2 >= 3", &expect!["false"]);
874}
875
876#[test]
877fn binop_gte_int_eq() {
878 check_expr("", "3 >= 3", &expect!["true"]);
879}
880
881#[test]
882fn binop_gte_double() {
883 check_expr("", "2.3 >= 0.3", &expect!["true"]);
884}
885
886#[test]
887fn binop_gte_double_false() {
888 check_expr("", "0.2 >= 0.3", &expect!["false"]);
889}
890
891#[test]
892fn binop_gte_double_eq() {
893 check_expr("", "0.3 >= 0.3", &expect!["true"]);
894}
895
896#[test]
897fn binop_lt_bigint_false() {
898 check_expr("", "23L < 3L", &expect!["false"]);
899}
900
901#[test]
902fn binop_lt_bigint() {
903 check_expr("", "2L < 3L", &expect!["true"]);
904}
905
906#[test]
907fn binop_lt_int_false() {
908 check_expr("", "23 < 3", &expect!["false"]);
909}
910
911#[test]
912fn binop_lt_int() {
913 check_expr("", "2 < 3", &expect!["true"]);
914}
915
916#[test]
917fn binop_lt_double_false() {
918 check_expr("", "2.3 < 0.3", &expect!["false"]);
919}
920
921#[test]
922fn binop_lt_double() {
923 check_expr("", "0.2 < 0.3", &expect!["true"]);
924}
925
926#[test]
927fn binop_lte_bigint_false() {
928 check_expr("", "23L <= 3L", &expect!["false"]);
929}
930
931#[test]
932fn binop_lte_bigint() {
933 check_expr("", "2L <= 3L", &expect!["true"]);
934}
935
936#[test]
937fn binop_lte_bigint_eq() {
938 check_expr("", "3L <= 3L", &expect!["true"]);
939}
940
941#[test]
942fn binop_lte_int_false() {
943 check_expr("", "23 <= 3", &expect!["false"]);
944}
945
946#[test]
947fn binop_lte_int() {
948 check_expr("", "2 <= 3", &expect!["true"]);
949}
950
951#[test]
952fn binop_lte_int_eq() {
953 check_expr("", "3 <= 3", &expect!["true"]);
954}
955
956#[test]
957fn binop_lte_double_false() {
958 check_expr("", "2.3 <= 0.3", &expect!["false"]);
959}
960
961#[test]
962fn binop_lte_double() {
963 check_expr("", "0.2 <= 0.3", &expect!["true"]);
964}
965
966#[test]
967fn binop_lte_double_eq() {
968 check_expr("", "0.3 <= 0.3", &expect!["true"]);
969}
970
971#[test]
972fn binop_mod_bigint() {
973 check_expr("", "8L % 6L", &expect!["2"]);
974}
975
976#[test]
977fn binop_mod_bigint_zero() {
978 check_expr(
979 "",
980 "12L % 0L",
981 &expect![[r#"
982 (
983 DivZero(
984 PackageSpan {
985 package: PackageId(
986 2,
987 ),
988 span: Span {
989 lo: 6,
990 hi: 8,
991 },
992 },
993 ),
994 [],
995 )
996 "#]],
997 );
998}
999
1000#[test]
1001fn binop_mod_int() {
1002 check_expr("", "8 % 6", &expect!["2"]);
1003}
1004
1005#[test]
1006fn binop_mod_int_wrap() {
1007 check_expr("", "(-0x8000000000000000) % (-1)", &expect!["0"]);
1008}
1009
1010#[test]
1011fn binop_mod_int_zero() {
1012 check_expr(
1013 "",
1014 "12 % 0",
1015 &expect![[r#"
1016 (
1017 DivZero(
1018 PackageSpan {
1019 package: PackageId(
1020 2,
1021 ),
1022 span: Span {
1023 lo: 5,
1024 hi: 6,
1025 },
1026 },
1027 ),
1028 [],
1029 )
1030 "#]],
1031 );
1032}
1033
1034#[test]
1035fn binop_mod_double() {
1036 check_expr("", "8.411 % 6.833", &expect!["1.5779999999999994"]);
1037}
1038
1039#[test]
1040fn binop_mod_double_zero() {
1041 check_expr(
1042 "",
1043 "1.2 % 0.0",
1044 &expect![[r#"
1045 (
1046 DivZero(
1047 PackageSpan {
1048 package: PackageId(
1049 2,
1050 ),
1051 span: Span {
1052 lo: 6,
1053 hi: 9,
1054 },
1055 },
1056 ),
1057 [],
1058 )
1059 "#]],
1060 );
1061}
1062
1063#[test]
1064fn binop_mul_bigint() {
1065 check_expr("", "8L * 6L", &expect!["48"]);
1066}
1067
1068#[test]
1069fn binop_mul_int() {
1070 check_expr("", "8 * 6", &expect!["48"]);
1071}
1072#[test]
1073fn binop_mul_int_wrap() {
1074 check_expr(
1075 "",
1076 "0x7FFFFFFFFFFFFFFF * 0xFF",
1077 &expect!["9223372036854775553"],
1078 );
1079}
1080
1081#[test]
1082fn binop_mul_double() {
1083 check_expr("", "8.411 * 6.833", &expect!["57.472363"]);
1084}
1085
1086#[test]
1087fn binop_neq_array() {
1088 check_expr("", "[1, 2, 3] != [1, 2, 3]", &expect!["false"]);
1089}
1090
1091#[test]
1092fn binop_neq_array_true_content() {
1093 check_expr("", "[1, 2, 3] != [1, 0, 3]", &expect!["true"]);
1094}
1095
1096#[test]
1097fn binop_neq_array_true_length() {
1098 check_expr("", "[1, 2, 3] != [1, 2, 3, 4]", &expect!["true"]);
1099}
1100
1101#[test]
1102fn binop_neq_bigint() {
1103 check_expr("", "18L != 18L", &expect!["false"]);
1104}
1105
1106#[test]
1107fn binop_neq_bigint_true() {
1108 check_expr("", "18L != 8L", &expect!["true"]);
1109}
1110
1111#[test]
1112fn binop_neq_bool() {
1113 check_expr("", "false != false", &expect!["false"]);
1114}
1115
1116#[test]
1117fn binop_neq_bool_true() {
1118 check_expr("", "false != true", &expect!["true"]);
1119}
1120
1121#[test]
1122fn binop_neq_double() {
1123 check_expr("", "1.254 != 1.254", &expect!["false"]);
1124}
1125
1126#[test]
1127fn binop_neq_double_true() {
1128 check_expr("", "1.254 != 1.25", &expect!["true"]);
1129}
1130
1131#[test]
1132fn binop_neq_int() {
1133 check_expr("", "42 != 42", &expect!["false"]);
1134}
1135
1136#[test]
1137fn binop_neq_int_true() {
1138 check_expr("", "42 != 43", &expect!["true"]);
1139}
1140
1141#[test]
1142fn binop_neq_pauli() {
1143 check_expr("", "PauliX != PauliX", &expect!["false"]);
1144}
1145
1146#[test]
1147fn binop_neq_pauli_true() {
1148 check_expr("", "PauliX != PauliZ", &expect!["true"]);
1149}
1150
1151#[test]
1152fn binop_neq_range() {
1153 check_expr("", "(0..4) != (0..4)", &expect!["false"]);
1154}
1155
1156#[test]
1157fn binop_neq_range_true() {
1158 check_expr("", "(0..2..4) != (0..4)", &expect!["true"]);
1159}
1160
1161#[test]
1162fn binop_neq_result() {
1163 check_expr("", "One != One", &expect!["false"]);
1164}
1165
1166#[test]
1167fn binop_neq_result_true() {
1168 check_expr("", "One != Zero", &expect!["true"]);
1169}
1170
1171#[test]
1172fn binop_neq_string() {
1173 check_expr("", r#""foo" != "foo""#, &expect!["false"]);
1174}
1175
1176#[test]
1177fn binop_neq_string_true() {
1178 check_expr("", r#""foo" != "bar""#, &expect!["true"]);
1179}
1180
1181#[test]
1182fn binop_neq_tuple() {
1183 check_expr("", "(1, 2, 3) != (1, 2, 3)", &expect!["false"]);
1184}
1185
1186#[test]
1187fn binop_neq_tuple_true_content() {
1188 check_expr("", "(1, 2, 3) != (1, -2, 3)", &expect!["true"]);
1189}
1190
1191#[test]
1192fn binop_orb_bigint() {
1193 check_expr("", "28L ||| 54L", &expect!["62"]);
1194}
1195
1196#[test]
1197fn binop_orb_int() {
1198 check_expr("", "28 ||| 54", &expect!["62"]);
1199}
1200
1201#[test]
1202fn binop_orl() {
1203 check_expr("", "true or true", &expect!["true"]);
1204}
1205
1206#[test]
1207fn binop_orl_true_lhs() {
1208 check_expr("", "true or false", &expect!["true"]);
1209}
1210
1211#[test]
1212fn binop_orl_true_rhs() {
1213 check_expr("", "false or true", &expect!["true"]);
1214}
1215
1216#[test]
1217fn binop_orl_false() {
1218 check_expr("", "false or false", &expect!["false"]);
1219}
1220
1221#[test]
1222fn binop_orl_shortcut() {
1223 check_expr("", r#"true or (fail "Shouldn't Fail")"#, &expect!["true"]);
1224}
1225
1226#[test]
1227fn binop_shl_bigint() {
1228 check_expr("", "4L <<< 2", &expect!["16"]);
1229}
1230
1231#[test]
1232fn binop_shl_bigint_negative() {
1233 check_expr("", "4L <<< -2", &expect!["1"]);
1234}
1235
1236#[test]
1237fn binop_shl_int() {
1238 check_expr("", "4 <<< 2", &expect!["16"]);
1239}
1240
1241#[test]
1242fn binop_shl_int_negative() {
1243 check_expr("", "4 <<< -2", &expect!["1"]);
1244}
1245
1246#[test]
1247fn binop_shl_int_truncate() {
1248 check_expr("", "1 <<< 63", &expect!["-9223372036854775808"]);
1249 check_expr("", "2 <<< 63", &expect!["0"]);
1250}
1251
1252#[test]
1253fn binop_shl_int_overflow() {
1254 check_expr(
1255 "",
1256 "1 <<< 64",
1257 &expect![[r#"
1258 (
1259 IntTooLarge(
1260 64,
1261 PackageSpan {
1262 package: PackageId(
1263 2,
1264 ),
1265 span: Span {
1266 lo: 6,
1267 hi: 8,
1268 },
1269 },
1270 ),
1271 [],
1272 )
1273 "#]],
1274 );
1275}
1276
1277#[test]
1278fn binop_shr_bigint() {
1279 check_expr("", "4L >>> 2", &expect!["1"]);
1280}
1281
1282#[test]
1283fn binop_shr_bigint_negative() {
1284 check_expr("", "4L >>> -2", &expect!["16"]);
1285}
1286
1287#[test]
1288fn binop_shr_int() {
1289 check_expr("", "4 >>> 2", &expect!["1"]);
1290}
1291
1292#[test]
1293fn binop_shr_int_negative() {
1294 check_expr("", "4 >>> -2", &expect!["16"]);
1295}
1296
1297#[test]
1298fn binop_shr_int_truncate() {
1299 check_expr("", "(-9223372036854775808) >>> 63", &expect!["-1"]);
1300 check_expr("", "1 >>> 63", &expect!["0"]);
1301}
1302
1303#[test]
1304fn binop_shr_int_overflow() {
1305 check_expr(
1306 "",
1307 "1 >>> 64",
1308 &expect![[r#"
1309 (
1310 IntTooLarge(
1311 64,
1312 PackageSpan {
1313 package: PackageId(
1314 2,
1315 ),
1316 span: Span {
1317 lo: 6,
1318 hi: 8,
1319 },
1320 },
1321 ),
1322 [],
1323 )
1324 "#]],
1325 );
1326}
1327
1328#[test]
1329fn binop_sub_bigint() {
1330 check_expr("", "4L - 2L", &expect!["2"]);
1331}
1332
1333#[test]
1334fn binop_sub_int() {
1335 check_expr("", "4 - 2", &expect!["2"]);
1336}
1337
1338#[test]
1339fn binop_sub_int_wrap() {
1340 check_expr(
1341 "",
1342 "-0x8000000000000000 - 1",
1343 &expect!["9223372036854775807"],
1344 );
1345}
1346
1347#[test]
1348fn binop_sub_double() {
1349 check_expr("", "4.7 - 2.5", &expect!["2.2"]);
1350}
1351
1352#[test]
1353fn binop_xorb_bigint() {
1354 check_expr("", "28L ^^^ 54L", &expect!["42"]);
1355}
1356
1357#[test]
1358fn binop_xorb_int() {
1359 check_expr("", "28 ^^^ 54", &expect!["42"]);
1360}
1361
1362#[test]
1363fn assignop_add_expr() {
1364 check_expr(
1365 "",
1366 indoc! {"{
1367 mutable x = 0;
1368 set x += 1;
1369 x
1370 }"},
1371 &expect!["1"],
1372 );
1373}
1374
1375#[test]
1376fn assignop_sub_expr() {
1377 check_expr(
1378 "",
1379 indoc! {"{
1380 mutable x = 0;
1381 set x -= 1;
1382 x
1383 }"},
1384 &expect!["-1"],
1385 );
1386}
1387
1388#[test]
1389fn assignop_orl_expr() {
1390 check_expr(
1391 "",
1392 indoc! {"{
1393 mutable x = false;
1394 set x or= true;
1395 x
1396 }"},
1397 &expect!["true"],
1398 );
1399}
1400
1401#[test]
1402fn fail_expr() {
1403 check_expr(
1404 "",
1405 r#"fail "This is a failure""#,
1406 &expect![[r#"
1407 (
1408 UserFail(
1409 "This is a failure",
1410 PackageSpan {
1411 package: PackageId(
1412 2,
1413 ),
1414 span: Span {
1415 lo: 0,
1416 hi: 24,
1417 },
1418 },
1419 ),
1420 [],
1421 )
1422 "#]],
1423 );
1424}
1425
1426#[test]
1427fn fail_shortcut_expr() {
1428 check_expr(
1429 "",
1430 r#"{ fail "Got Here!"; fail "Shouldn't get here..."; }"#,
1431 &expect![[r#"
1432 (
1433 UserFail(
1434 "Got Here!",
1435 PackageSpan {
1436 package: PackageId(
1437 2,
1438 ),
1439 span: Span {
1440 lo: 2,
1441 hi: 18,
1442 },
1443 },
1444 ),
1445 [],
1446 )
1447 "#]],
1448 );
1449}
1450
1451#[test]
1452fn field_range_start_expr() {
1453 check_expr("", "(0..2..8)::Start", &expect!["0"]);
1454}
1455
1456#[test]
1457fn field_range_step_expr() {
1458 check_expr("", "(0..2..8)::Step", &expect!["2"]);
1459}
1460
1461#[test]
1462fn field_range_step_missing_treated_as_1_expr() {
1463 check_expr("", "(0..8)::Step", &expect!["1"]);
1464}
1465
1466#[test]
1467fn field_range_end_expr() {
1468 check_expr("", "(0..2..8)::End", &expect!["8"]);
1469}
1470
1471#[test]
1472fn for_loop_range_expr() {
1473 check_expr(
1474 "",
1475 indoc! {"{
1476 mutable x = 0;
1477 for i in 0..10 {
1478 set x = x + i;
1479 }
1480 x
1481 }"},
1482 &expect!["55"],
1483 );
1484}
1485
1486#[test]
1487fn for_loop_array_expr() {
1488 check_expr(
1489 "",
1490 indoc! {"{
1491 mutable x = 0;
1492 for i in [5, size = 5] {
1493 set x = x + i;
1494 }
1495 x
1496 }"},
1497 &expect!["25"],
1498 );
1499}
1500
1501#[test]
1502fn for_loop_ignore_iterator_expr() {
1503 check_expr(
1504 "",
1505 indoc! {"{
1506 mutable x = 0;
1507 for _ in [5, size = 5] {
1508 set x = x + 1;
1509 }
1510 x
1511 }"},
1512 &expect!["5"],
1513 );
1514}
1515
1516#[test]
1517fn array_index_expr() {
1518 check_expr("", "[1, 2, 3][1]", &expect!["2"]);
1519}
1520
1521#[test]
1522fn array_slice_start_end_expr() {
1523 check_expr("", "[1, 2, 3, 4, 5][0..2]", &expect!["[1, 2, 3]"]);
1524}
1525
1526#[test]
1527fn array_slice_start_step_end_expr() {
1528 check_expr("", "[1, 2, 3, 4, 5][0..2..2]", &expect!["[1, 3]"]);
1529}
1530
1531#[test]
1532fn array_slice_start_expr() {
1533 check_expr("", "[1, 2, 3, 4, 5][2...]", &expect!["[3, 4, 5]"]);
1534}
1535
1536#[test]
1537fn array_slice_end_expr() {
1538 check_expr("", "[1, 2, 3, 4, 5][...2]", &expect!["[1, 2, 3]"]);
1539}
1540
1541#[test]
1542fn array_slice_step_end_expr() {
1543 check_expr("", "[1, 2, 3, 4, 5][...2..3]", &expect!["[1, 3]"]);
1544}
1545
1546#[test]
1547fn array_slice_step_expr() {
1548 check_expr("", "[1, 2, 3, 4, 5][...2...]", &expect!["[1, 3, 5]"]);
1549}
1550
1551#[test]
1552fn array_slice_reverse_expr() {
1553 check_expr("", "[1, 2, 3, 4, 5][2..-1..0]", &expect!["[3, 2, 1]"]);
1554}
1555
1556#[test]
1557fn array_slice_reverse_end_expr() {
1558 check_expr("", "[1, 2, 3, 4, 5][...-1..2]", &expect!["[5, 4, 3]"]);
1559}
1560
1561#[test]
1562fn array_slice_reverse_start_expr() {
1563 check_expr("", "[1, 2, 3, 4, 5][2..-1...]", &expect!["[3, 2, 1]"]);
1564}
1565
1566#[test]
1567fn array_slice_reverse_all_expr() {
1568 check_expr("", "[1, 2, 3, 4, 5][...-1...]", &expect!["[5, 4, 3, 2, 1]"]);
1569}
1570
1571#[test]
1572fn array_slice_all_expr() {
1573 check_expr("", "[1, 2, 3, 4, 5][...]", &expect!["[1, 2, 3, 4, 5]"]);
1574}
1575
1576#[test]
1577fn array_slice_none_expr() {
1578 check_expr("", "[1, 2, 3, 4, 5][1..0]", &expect!["[]"]);
1579}
1580
1581#[test]
1582fn array_slice_reverse_none_expr() {
1583 check_expr("", "[1, 2, 3, 4, 5][0..-1..1]", &expect!["[]"]);
1584}
1585
1586#[test]
1587fn array_slice_step_zero_expr() {
1588 check_expr(
1589 "",
1590 "[1, 2, 3, 4, 5][...0...]",
1591 &expect![[r#"
1592 (
1593 RangeStepZero(
1594 PackageSpan {
1595 package: PackageId(
1596 2,
1597 ),
1598 span: Span {
1599 lo: 16,
1600 hi: 23,
1601 },
1602 },
1603 ),
1604 [],
1605 )
1606 "#]],
1607 );
1608}
1609
1610#[test]
1611fn array_slice_out_of_range_expr() {
1612 check_expr(
1613 "",
1614 "[1, 2, 3, 4, 5][0..7]",
1615 &expect![[r#"
1616 (
1617 IndexOutOfRange(
1618 5,
1619 PackageSpan {
1620 package: PackageId(
1621 2,
1622 ),
1623 span: Span {
1624 lo: 16,
1625 hi: 20,
1626 },
1627 },
1628 ),
1629 [],
1630 )
1631 "#]],
1632 );
1633}
1634
1635#[test]
1636fn array_index_negative_expr() {
1637 check_expr(
1638 "",
1639 "[1, 2, 3][-2]",
1640 &expect![[r#"
1641 (
1642 InvalidIndex(
1643 -2,
1644 PackageSpan {
1645 package: PackageId(
1646 2,
1647 ),
1648 span: Span {
1649 lo: 10,
1650 hi: 12,
1651 },
1652 },
1653 ),
1654 [],
1655 )
1656 "#]],
1657 );
1658}
1659
1660#[test]
1661fn array_index_out_of_range_expr() {
1662 check_expr(
1663 "",
1664 "[1, 2, 3][4]",
1665 &expect![[r#"
1666 (
1667 IndexOutOfRange(
1668 4,
1669 PackageSpan {
1670 package: PackageId(
1671 2,
1672 ),
1673 span: Span {
1674 lo: 10,
1675 hi: 11,
1676 },
1677 },
1678 ),
1679 [],
1680 )
1681 "#]],
1682 );
1683}
1684
1685#[test]
1686fn literal_big_int_expr() {
1687 check_expr(
1688 "",
1689 "9_223_372_036_854_775_808L",
1690 &expect!["9223372036854775808"],
1691 );
1692}
1693
1694#[test]
1695fn literal_bool_false_expr() {
1696 check_expr("", "false", &expect!["false"]);
1697}
1698
1699#[test]
1700fn literal_bool_true_expr() {
1701 check_expr("", "true", &expect!["true"]);
1702}
1703
1704#[test]
1705fn literal_double_expr() {
1706 check_expr("", "4.2", &expect!["4.2"]);
1707}
1708
1709#[test]
1710fn literal_double_trailing_dot_expr() {
1711 check_expr("", "4.", &expect!["4.0"]);
1712}
1713
1714#[test]
1715fn literal_int_expr() {
1716 check_expr("", "42", &expect!["42"]);
1717}
1718
1719#[test]
1720fn literal_int_too_big_expr() {
1721 check_expr(
1722 "",
1723 "9_223_372_036_854_775_808",
1724 &expect!["-9223372036854775808"],
1725 );
1726}
1727
1728#[test]
1729fn literal_pauli_i_expr() {
1730 check_expr("", "PauliI", &expect!["PauliI"]);
1731}
1732
1733#[test]
1734fn literal_pauli_x_expr() {
1735 check_expr("", "PauliX", &expect!["PauliX"]);
1736}
1737
1738#[test]
1739fn literal_pauli_y_expr() {
1740 check_expr("", "PauliY", &expect!["PauliY"]);
1741}
1742
1743#[test]
1744fn literal_pauli_z_expr() {
1745 check_expr("", "PauliZ", &expect!["PauliZ"]);
1746}
1747
1748#[test]
1749fn literal_result_one_expr() {
1750 check_expr("", "One", &expect!["One"]);
1751}
1752
1753#[test]
1754fn literal_result_zero_expr() {
1755 check_expr("", "Zero", &expect!["Zero"]);
1756}
1757
1758#[test]
1759fn literal_string_expr() {
1760 check_expr("", r#""foo""#, &expect!["foo"]);
1761}
1762
1763#[test]
1764fn literal_tuple_expr() {
1765 check_expr("", "(1, 2, 3)", &expect!["(1, 2, 3)"]);
1766}
1767
1768#[test]
1769fn literal_tuple_singleton_expr() {
1770 check_expr("", "(1,)", &expect!["(1,)"]);
1771}
1772
1773#[test]
1774fn literal_tuple_mixed_expr() {
1775 check_expr(
1776 "",
1777 "(1, One, 1.0, [1, 2, 3])",
1778 &expect!["(1, One, 1.0, [1, 2, 3])"],
1779 );
1780}
1781
1782#[test]
1783fn paren_expr() {
1784 check_expr("", "(42)", &expect!["42"]);
1785}
1786
1787#[test]
1788fn range_all_expr() {
1789 check_expr("", "...", &expect!["..."]);
1790}
1791
1792#[test]
1793fn range_end_expr() {
1794 check_expr("", "...3", &expect!["...3"]);
1795}
1796
1797#[test]
1798fn range_step_end_expr() {
1799 check_expr("", "...2..3", &expect!["...2..3"]);
1800}
1801
1802#[test]
1803fn range_start_expr() {
1804 check_expr("", "1...", &expect!["1..."]);
1805}
1806
1807#[test]
1808fn range_start_end_expr() {
1809 check_expr("", "1..3", &expect!["1..3"]);
1810}
1811
1812#[test]
1813fn range_start_step_expr() {
1814 check_expr("", "1..2...", &expect!["1..2..."]);
1815}
1816
1817#[test]
1818fn range_start_step_end_expr() {
1819 check_expr("", "1..2..3", &expect!["1..2..3"]);
1820}
1821
1822#[test]
1823fn repeat_until_expr() {
1824 check_expr(
1825 "",
1826 indoc! {"{
1827 mutable x = 0;
1828 repeat {
1829 set x = x + 1;
1830 }
1831 until x >= 3;
1832 x
1833 }"},
1834 &expect!["3"],
1835 );
1836}
1837
1838#[test]
1839fn repeat_until_fixup_expr() {
1840 check_expr(
1841 "",
1842 indoc! {"{
1843 mutable x = 0;
1844 repeat {}
1845 until x >= 3
1846 fixup {
1847 set x = x + 1;
1848 }
1849 x
1850 }"},
1851 &expect!["3"],
1852 );
1853}
1854
1855#[test]
1856fn return_expr() {
1857 check_expr("", "return 4", &expect!["4"]);
1858}
1859
1860#[test]
1861fn return_shortcut_expr() {
1862 check_expr(
1863 "",
1864 r#"{return 4; fail "Shouldn't get here...";}"#,
1865 &expect!["4"],
1866 );
1867}
1868
1869#[test]
1870fn tuple_expr() {
1871 check_expr("", "(1, 2, 3)", &expect!["(1, 2, 3)"]);
1872}
1873
1874#[test]
1875fn unop_bitwise_not_big_int_expr() {
1876 check_expr(
1877 "",
1878 "~~~(9_223_372_036_854_775_808L)",
1879 &expect!["-9223372036854775809"],
1880 );
1881}
1882
1883#[test]
1884fn while_expr() {
1885 check_expr(
1886 "",
1887 indoc! {"{
1888 mutable x = 0;
1889 while x < 10 {
1890 set x = x + 1;
1891 }
1892 x
1893 }"},
1894 &expect!["10"],
1895 );
1896}
1897
1898#[test]
1899fn while_false_shortcut_expr() {
1900 check_expr(
1901 "",
1902 r#"while false { fail "Shouldn't fail" }"#,
1903 &expect!["()"],
1904 );
1905}
1906
1907#[test]
1908fn cond_expr() {
1909 check_expr("", "true ? 1 | 0", &expect!["1"]);
1910}
1911
1912#[test]
1913fn cond_false_expr() {
1914 check_expr("", "false ? 1 | 0", &expect!["0"]);
1915}
1916
1917#[test]
1918fn cond_shortcircuit_expr() {
1919 check_expr("", r#"true ? 1 | fail "Shouldn't fail""#, &expect!["1"]);
1920}
1921
1922#[test]
1923fn cond_false_shortcircuit_expr() {
1924 check_expr("", r#"false ? fail "Shouldn't fail" | 0"#, &expect!["0"]);
1925}
1926
1927#[test]
1928fn update_expr() {
1929 check_expr("", "[1, 2, 3] w/ 2 <- 4", &expect!["[1, 2, 4]"]);
1930}
1931
1932#[test]
1933fn update_invalid_index_range_expr() {
1934 check_expr(
1935 "",
1936 "[1, 2, 3] w/ 7 <- 4",
1937 &expect![[r#"
1938 (
1939 IndexOutOfRange(
1940 7,
1941 PackageSpan {
1942 package: PackageId(
1943 2,
1944 ),
1945 span: Span {
1946 lo: 13,
1947 hi: 14,
1948 },
1949 },
1950 ),
1951 [],
1952 )
1953 "#]],
1954 );
1955}
1956
1957#[test]
1958fn update_invalid_index_negative_expr() {
1959 check_expr(
1960 "",
1961 "[1, 2, 3] w/ -1 <- 4",
1962 &expect![[r#"
1963 (
1964 InvalidNegativeInt(
1965 -1,
1966 PackageSpan {
1967 package: PackageId(
1968 2,
1969 ),
1970 span: Span {
1971 lo: 13,
1972 hi: 15,
1973 },
1974 },
1975 ),
1976 [],
1977 )
1978 "#]],
1979 );
1980}
1981
1982#[test]
1983fn update_array_index_var() {
1984 check_expr(
1985 "",
1986 indoc! {"{
1987 let xs = [2];
1988 let i = 0;
1989 xs w/ i <- 3
1990 }"},
1991 &expect!["[3]"],
1992 );
1993}
1994
1995#[test]
1996fn update_array_index_expr() {
1997 check_expr(
1998 "",
1999 indoc! {"{
2000 let xs = [1, 2];
2001 let i = 0;
2002 xs w/ i + 1 <- 3
2003 }"},
2004 &expect!["[1, 3]"],
2005 );
2006}
2007
2008#[test]
2009fn update_udt_known_field_name() {
2010 check_expr(
2011 indoc! {"
2012 namespace A {
2013 newtype Pair = (First : Int, Second : Int);
2014 }
2015 "},
2016 indoc! {"{
2017 open A;
2018 let p = Pair(1, 2);
2019 p w/ First <- 3
2020 }"},
2021 &expect!["(3, 2)"],
2022 );
2023}
2024
2025#[test]
2026fn update_udt_nested_field() {
2027 check_expr(
2028 indoc! {"
2029 namespace A {
2030 newtype Triple = (First : Int, (Second : Int, Third : Int));
2031 }
2032 "},
2033 indoc! {"{
2034 open A;
2035 let p = Triple(1, (2, 3));
2036 p w/ Third <- 4
2037 }"},
2038 &expect!["(1, (2, 4))"],
2039 );
2040}
2041
2042#[test]
2043fn update_range_start() {
2044 check_expr("", "1..2..3 w/ Start <- 10", &expect!["10..2..3"]);
2045}
2046
2047#[test]
2048fn update_range_from_start() {
2049 check_expr("", "1..2... w/ Start <- 10", &expect!["10..2..."]);
2050}
2051
2052#[test]
2053fn update_range_step() {
2054 check_expr("", "1..2..3 w/ Step <- 10", &expect!["1..10..3"]);
2055}
2056
2057#[test]
2058fn update_range_from_step() {
2059 check_expr("", "1..2... w/ Step <- 10", &expect!["1..10..."]);
2060}
2061
2062#[test]
2063fn update_range_to_step() {
2064 check_expr("", "...2..3 w/ Step <- 10", &expect!["...10..3"]);
2065}
2066
2067#[test]
2068fn update_range_full_step() {
2069 check_expr("", "...2... w/ Step <- 10", &expect!["...10..."]);
2070}
2071
2072#[test]
2073fn update_range_end() {
2074 check_expr("", "1..2..3 w/ End <- 10", &expect!["1..2..10"]);
2075}
2076
2077#[test]
2078fn update_range_to_end() {
2079 check_expr("", "...2..3 w/ End <- 10", &expect!["...2..10"]);
2080}
2081
2082#[test]
2083fn update_array_with_range() {
2084 check_expr("", "[0, 1, 2] w/ 1..2 <- [10, 11]", &expect!["[0, 10, 11]"]);
2085}
2086
2087#[test]
2088fn update_array_with_range_start() {
2089 check_expr(
2090 "",
2091 "[0, 1, 2, 3] w/ 1... <- [10, 11]",
2092 &expect!["[0, 10, 11, 3]"],
2093 );
2094}
2095
2096#[test]
2097fn update_array_with_range_step() {
2098 check_expr(
2099 "",
2100 "[0, 1, 2, 3] w/ ...2... <- [10, 11]",
2101 &expect!["[10, 1, 11, 3]"],
2102 );
2103}
2104
2105#[test]
2106fn update_array_with_range_end() {
2107 check_expr(
2108 "",
2109 "[0, 1, 2, 3] w/ ...2 <- [10, 11, 12, 13]",
2110 &expect!["[10, 11, 12, 3]"],
2111 );
2112}
2113
2114#[test]
2115fn update_array_with_range_fully_open() {
2116 check_expr(
2117 "",
2118 "[0, 1, 2, 3] w/ ... <- [10, 11, 12, 13]",
2119 &expect!["[10, 11, 12, 13]"],
2120 );
2121}
2122
2123#[test]
2124fn update_array_with_range_reverse() {
2125 check_expr(
2126 "",
2127 "[0, 1, 2, 3] w/ 2..-1..0 <- [10, 11]",
2128 &expect!["[0, 11, 10, 3]"],
2129 );
2130}
2131
2132#[test]
2133fn update_array_with_range_out_of_range_err() {
2134 check_expr(
2135 "",
2136 "[0, 1, 2, 3] w/ 1..5 <- [10, 11, 12, 13]",
2137 &expect![[r#"
2138 (
2139 IndexOutOfRange(
2140 4,
2141 PackageSpan {
2142 package: PackageId(
2143 2,
2144 ),
2145 span: Span {
2146 lo: 16,
2147 hi: 20,
2148 },
2149 },
2150 ),
2151 [],
2152 )
2153 "#]],
2154 );
2155}
2156
2157#[test]
2158fn update_array_with_range_negative_index_err() {
2159 check_expr(
2160 "",
2161 "[0, 1, 2, 3] w/ -1..0 <- [10, 11, 12, 13]",
2162 &expect![[r#"
2163 (
2164 InvalidIndex(
2165 -1,
2166 PackageSpan {
2167 package: PackageId(
2168 2,
2169 ),
2170 span: Span {
2171 lo: 16,
2172 hi: 21,
2173 },
2174 },
2175 ),
2176 [],
2177 )
2178 "#]],
2179 );
2180}
2181
2182#[test]
2183fn update_array_with_range_zero_step_err() {
2184 check_expr(
2185 "",
2186 "[0, 1, 2, 3] w/ ...0... <- [10, 11, 12, 13]",
2187 &expect![[r#"
2188 (
2189 RangeStepZero(
2190 PackageSpan {
2191 package: PackageId(
2192 2,
2193 ),
2194 span: Span {
2195 lo: 16,
2196 hi: 23,
2197 },
2198 },
2199 ),
2200 [],
2201 )
2202 "#]],
2203 );
2204}
2205
2206#[test]
2207fn update_array_with_range_bigger_than_update() {
2208 check_expr(
2209 "",
2210 "[0, 1, 2, 3] w/ 1..3 <- [10]",
2211 &expect!["[0, 10, 2, 3]"],
2212 );
2213}
2214
2215#[test]
2216fn update_array_with_range_smaller_than_update() {
2217 check_expr(
2218 "",
2219 "[0, 1, 2, 3] w/ 1..3 <- [10, 11, 12, 13]",
2220 &expect!["[0, 10, 11, 12]"],
2221 );
2222}
2223
2224#[test]
2225fn update_array_with_range_open_ended_bigger_than_update() {
2226 check_expr(
2227 "",
2228 "[0, 1, 2, 3] w/ 1... <- [10]",
2229 &expect!["[0, 10, 2, 3]"],
2230 );
2231}
2232
2233#[test]
2234fn update_array_with_range_open_ended_smaller_than_update() {
2235 check_expr(
2236 "",
2237 "[0, 1, 2, 3] w/ 1... <- [10, 11, 12, 13]",
2238 &expect!["[0, 10, 11, 12]"],
2239 );
2240}
2241
2242#[test]
2243fn update_array_with_range_empty_update() {
2244 check_expr("", "[0, 1, 2, 3] w/ 1..3 <- []", &expect!["[0, 1, 2, 3]"]);
2245}
2246
2247#[test]
2248fn assignupdate_expr() {
2249 check_expr(
2250 "",
2251 indoc! {"{
2252 mutable x = [1, 2, 3];
2253 set x w/= 2 <- 4;
2254 x
2255 }"},
2256 &expect!["[1, 2, 4]"],
2257 );
2258}
2259
2260#[test]
2261fn assignupdate_out_of_range_err() {
2262 check_expr(
2263 "",
2264 indoc! {"{
2265 mutable x = [1, 2, 3];
2266 set x w/= 4 <- 4;
2267 x
2268 }"},
2269 &expect![[r#"
2270 (
2271 IndexOutOfRange(
2272 4,
2273 PackageSpan {
2274 package: PackageId(
2275 2,
2276 ),
2277 span: Span {
2278 lo: 43,
2279 hi: 44,
2280 },
2281 },
2282 ),
2283 [],
2284 )
2285 "#]],
2286 );
2287}
2288
2289#[test]
2290fn assignupdate_expr_negative_index_err() {
2291 check_expr(
2292 "",
2293 indoc! {"{
2294 mutable x = [1, 2, 3];
2295 set x w/= -1 <- 4;
2296 x
2297 }"},
2298 &expect![[r#"
2299 (
2300 InvalidNegativeInt(
2301 -1,
2302 PackageSpan {
2303 package: PackageId(
2304 2,
2305 ),
2306 span: Span {
2307 lo: 43,
2308 hi: 45,
2309 },
2310 },
2311 ),
2312 [],
2313 )
2314 "#]],
2315 );
2316}
2317
2318#[test]
2319fn assignupdate_expr_using_field_name() {
2320 check_expr(
2321 indoc! {"
2322 namespace A {
2323 newtype Pair = (First : Int, Second : Int);
2324 }
2325 "},
2326 indoc! {"{
2327 open A;
2328 mutable p = Pair(1, 2);
2329 set p w/= First <- 3;
2330 p
2331 }"},
2332 &expect!["(3, 2)"],
2333 );
2334}
2335
2336#[test]
2337fn assignupdate_expr_using_range() {
2338 check_expr(
2339 "",
2340 indoc! {"{
2341 mutable x = [1, 2, 3];
2342 set x w/= 1..2 <- [10, 11];
2343 x
2344 }"},
2345 &expect!["[1, 10, 11]"],
2346 );
2347}
2348
2349#[test]
2350fn assignupdate_expr_using_range_start() {
2351 check_expr(
2352 "",
2353 indoc! {"{
2354 mutable x = [1, 2, 3, 4];
2355 set x w/= 1... <- [10, 11];
2356 x
2357 }"},
2358 &expect!["[1, 10, 11, 4]"],
2359 );
2360}
2361
2362#[test]
2363fn assignupdate_expr_using_range_step() {
2364 check_expr(
2365 "",
2366 indoc! {"{
2367 mutable x = [1, 2, 3, 4];
2368 set x w/= ...2... <- [10, 11];
2369 x
2370 }"},
2371 &expect!["[10, 2, 11, 4]"],
2372 );
2373}
2374
2375#[test]
2376fn assignupdate_expr_using_range_end() {
2377 check_expr(
2378 "",
2379 indoc! {"{
2380 mutable x = [1, 2, 3, 4];
2381 set x w/= ...2 <- [10, 11, 12, 13];
2382 x
2383 }"},
2384 &expect!["[10, 11, 12, 4]"],
2385 );
2386}
2387
2388#[test]
2389fn assignupdate_expr_using_range_fully_open() {
2390 check_expr(
2391 "",
2392 indoc! {"{
2393 mutable x = [1, 2, 3, 4];
2394 set x w/= ... <- [10, 11, 12, 13];
2395 x
2396 }"},
2397 &expect!["[10, 11, 12, 13]"],
2398 );
2399}
2400
2401#[test]
2402fn assignupdate_expr_using_range_reverse() {
2403 check_expr(
2404 "",
2405 indoc! {"{
2406 mutable x = [1, 2, 3, 4];
2407 set x w/= 2..-1..0 <- [10, 11];
2408 x
2409 }"},
2410 &expect!["[1, 11, 10, 4]"],
2411 );
2412}
2413
2414#[test]
2415fn assignupdate_expr_using_range_bigger_than_update() {
2416 check_expr(
2417 "",
2418 indoc! {"{
2419 mutable x = [1, 2, 3, 4];
2420 set x w/= 1..3 <- [10];
2421 x
2422 }"},
2423 &expect!["[1, 10, 3, 4]"],
2424 );
2425}
2426
2427#[test]
2428fn assignupdate_expr_using_range_smaller_than_update() {
2429 check_expr(
2430 "",
2431 indoc! {"{
2432 mutable x = [1, 2, 3, 4];
2433 set x w/= 1..3 <- [10, 11, 12, 13];
2434 x
2435 }"},
2436 &expect!["[1, 10, 11, 12]"],
2437 );
2438}
2439
2440#[test]
2441fn assignupdate_expr_using_range_open_ended_bigger_than_update() {
2442 check_expr(
2443 "",
2444 indoc! {"{
2445 mutable x = [1, 2, 3, 4];
2446 set x w/= 1... <- [10, 11];
2447 x
2448 }"},
2449 &expect!["[1, 10, 11, 4]"],
2450 );
2451}
2452
2453#[test]
2454fn assignupdate_expr_using_range_open_ended_smaller_than_update() {
2455 check_expr(
2456 "",
2457 indoc! {"{
2458 mutable x = [1, 2, 3, 4];
2459 set x w/= 1... <- [10, 11, 12, 13];
2460 x
2461 }"},
2462 &expect!["[1, 10, 11, 12]"],
2463 );
2464}
2465
2466#[test]
2467fn assignupdate_expr_using_range_empty_update() {
2468 check_expr(
2469 "",
2470 indoc! {"{
2471 mutable x = [1, 2, 3, 4];
2472 set x w/= 1..3 <- [];
2473 x
2474 }"},
2475 &expect!["[1, 2, 3, 4]"],
2476 );
2477}
2478
2479#[test]
2480fn assignupdate_expr_using_range_out_of_range_err() {
2481 check_expr(
2482 "",
2483 indoc! {"{
2484 mutable x = [1, 2, 3, 4];
2485 set x w/= 1..5 <- [10, 11, 12, 13];
2486 x
2487 }"},
2488 &expect![[r#"
2489 (
2490 IndexOutOfRange(
2491 4,
2492 PackageSpan {
2493 package: PackageId(
2494 2,
2495 ),
2496 span: Span {
2497 lo: 46,
2498 hi: 50,
2499 },
2500 },
2501 ),
2502 [],
2503 )
2504 "#]],
2505 );
2506}
2507
2508#[test]
2509fn assignupdate_expr_using_range_negative_index_err() {
2510 check_expr(
2511 "",
2512 indoc! {"{
2513 mutable x = [1, 2, 3, 4];
2514 set x w/= -1..0 <- [10, 11, 12, 13];
2515 x
2516 }"},
2517 &expect![[r#"
2518 (
2519 InvalidNegativeInt(
2520 -1,
2521 PackageSpan {
2522 package: PackageId(
2523 2,
2524 ),
2525 span: Span {
2526 lo: 46,
2527 hi: 51,
2528 },
2529 },
2530 ),
2531 [],
2532 )
2533 "#]],
2534 );
2535}
2536
2537#[test]
2538fn unop_bitwise_not_int_expr() {
2539 check_expr("", "~~~(13)", &expect!["-14"]);
2540}
2541
2542#[test]
2543fn unop_negate_big_int_expr() {
2544 check_expr(
2545 "",
2546 "-(9_223_372_036_854_775_808L)",
2547 &expect!["-9223372036854775808"],
2548 );
2549}
2550
2551#[test]
2552fn unop_negate_double_expr() {
2553 check_expr("", "-(3.4)", &expect!["-3.4"]);
2554}
2555
2556#[test]
2557fn unop_negate_int_expr() {
2558 check_expr("", "-(13)", &expect!["-13"]);
2559}
2560
2561#[test]
2562fn unop_negate_int_overflow_expr() {
2563 check_expr(
2564 "",
2565 "-(9_223_372_036_854_775_808)",
2566 &expect!["-9223372036854775808"],
2567 );
2568}
2569
2570#[test]
2571fn unop_negate_negative_int_expr() {
2572 check_expr("", "-(-(13))", &expect!["13"]);
2573}
2574
2575#[test]
2576fn unop_not_bool_expr() {
2577 check_expr("", "not false", &expect!["true"]);
2578}
2579
2580#[test]
2581fn unop_positive_big_int_expr() {
2582 check_expr(
2583 "",
2584 "+(9_223_372_036_854_775_808L)",
2585 &expect!["9223372036854775808"],
2586 );
2587}
2588
2589#[test]
2590fn unop_positive_double_expr() {
2591 check_expr("", "+(3.4)", &expect!["3.4"]);
2592}
2593
2594#[test]
2595fn unop_positive_int_expr() {
2596 check_expr("", "+(13)", &expect!["13"]);
2597}
2598
2599#[test]
2600fn unop_adjoint_functor_expr() {
2601 check_expr(
2602 indoc! {"
2603 namespace Test {
2604 operation Foo() : Unit is Adj + Ctl {
2605 body ... {}
2606 }
2607 }
2608 "},
2609 "Adjoint Test.Foo",
2610 &expect!["Adjoint <item 1 in package 2>"],
2611 );
2612}
2613
2614#[test]
2615fn unop_controlled_functor_expr() {
2616 check_expr(
2617 indoc! {"
2618 namespace Test {
2619 operation Foo() : Unit is Adj + Ctl {
2620 body ... {}
2621 }
2622 }
2623 "},
2624 "Controlled Test.Foo",
2625 &expect!["Controlled <item 1 in package 2>"],
2626 );
2627}
2628
2629#[test]
2630fn unop_adjoint_adjoint_functor_expr() {
2631 check_expr(
2632 indoc! {"
2633 namespace Test {
2634 operation Foo() : Unit is Adj + Ctl {
2635 body ... {}
2636 }
2637 }
2638 "},
2639 "Adjoint (Adjoint Test.Foo)",
2640 &expect!["<item 1 in package 2>"],
2641 );
2642}
2643
2644#[test]
2645fn unop_controlled_adjoint_functor_expr() {
2646 check_expr(
2647 indoc! {"
2648 namespace Test {
2649 operation Foo() : Unit is Adj + Ctl {
2650 body ... {}
2651 }
2652 }
2653 "},
2654 "Controlled Adjoint Test.Foo",
2655 &expect!["Controlled Adjoint <item 1 in package 2>"],
2656 );
2657}
2658
2659#[test]
2660fn unop_adjoint_controlled_functor_expr() {
2661 check_expr(
2662 indoc! {"
2663 namespace Test {
2664 operation Foo() : Unit is Adj + Ctl {
2665 body ... {}
2666 }
2667 }
2668 "},
2669 "Adjoint Controlled Test.Foo",
2670 &expect!["Controlled Adjoint <item 1 in package 2>"],
2671 );
2672}
2673
2674#[test]
2675fn unop_controlled_controlled_functor_expr() {
2676 check_expr(
2677 indoc! {"
2678 namespace Test {
2679 operation Foo() : Unit is Adj + Ctl {
2680 body ... {}
2681 }
2682 }
2683 "},
2684 "Controlled (Controlled Test.Foo)",
2685 &expect!["Controlled Controlled <item 1 in package 2>"],
2686 );
2687}
2688
2689#[test]
2690fn if_true_expr() {
2691 check_expr(
2692 "",
2693 r#"if true {return "Got Here!";}"#,
2694 &expect!["Got Here!"],
2695 );
2696}
2697
2698#[test]
2699fn if_false_expr() {
2700 check_expr(
2701 "",
2702 r#"if false {return "Shouldn't get here...";}"#,
2703 &expect!["()"],
2704 );
2705}
2706
2707#[test]
2708fn if_else_true_expr() {
2709 check_expr(
2710 "",
2711 r#"if true {return "Got Here!";} else {return "Shouldn't get here..."}"#,
2712 &expect!["Got Here!"],
2713 );
2714}
2715
2716#[test]
2717fn if_else_false_expr() {
2718 check_expr(
2719 "",
2720 r#"if false {return "Shouldn't get here...";} else {return "Got Here!"}"#,
2721 &expect!["Got Here!"],
2722 );
2723}
2724
2725#[test]
2726fn if_elif_true_true_expr() {
2727 check_expr(
2728 "",
2729 r#"if true {return "Got Here!";} elif true {return"Shouldn't get here..."}"#,
2730 &expect!["Got Here!"],
2731 );
2732}
2733
2734#[test]
2735fn if_elif_false_true_expr() {
2736 check_expr(
2737 "",
2738 r#"if false {return "Shouldn't get here...";} elif true {return "Got Here!"}"#,
2739 &expect!["Got Here!"],
2740 );
2741}
2742
2743#[test]
2744fn if_elif_false_false_expr() {
2745 check_expr(
2746 "",
2747 r#"if false {return "Shouldn't get here...";} elif false {return "Shouldn't get here..."}"#,
2748 &expect!["()"],
2749 );
2750}
2751
2752#[test]
2753fn if_elif_else_true_true_expr() {
2754 check_expr(
2755 "",
2756 r#"if true {return "Got Here!";} elif true {return "Shouldn't get here..."} else {return "Shouldn't get here..."}"#,
2757 &expect!["Got Here!"],
2758 );
2759}
2760
2761#[test]
2762fn if_elif_else_false_true_expr() {
2763 check_expr(
2764 "",
2765 r#"if false {return "Shouldn't get here...";} elif true {return "Got Here!"} else {return "Shouldn't get here..."}"#,
2766 &expect!["Got Here!"],
2767 );
2768}
2769
2770#[test]
2771fn if_elif_else_false_false_expr() {
2772 check_expr(
2773 "",
2774 r#"if false {return "Shouldn't get here...";} elif false {return "Shouldn't get here..."} else {return "Got Here!"}"#,
2775 &expect!["Got Here!"],
2776 );
2777}
2778
2779#[test]
2780fn call_expr() {
2781 check_expr(
2782 indoc! {"
2783 namespace Test {
2784 function Answer() : Int {
2785 42
2786 }
2787 }
2788 "},
2789 "Test.Answer()",
2790 &expect!["42"],
2791 );
2792}
2793
2794#[test]
2795fn call_return_expr() {
2796 check_expr(
2797 indoc! {"
2798 namespace Test {
2799 function Answer() : Int {
2800 return 42;
2801 }
2802 }
2803 "},
2804 "Test.Answer()",
2805 &expect!["42"],
2806 );
2807}
2808
2809#[test]
2810fn call_args_expr() {
2811 check_expr(
2812 indoc! {"
2813 namespace Test {
2814 function Echo(val : Int) : Int {
2815 return val;
2816 }
2817 }
2818 "},
2819 "Test.Echo(42)",
2820 &expect!["42"],
2821 );
2822}
2823
2824#[test]
2825fn call_multiple_args_expr() {
2826 check_expr(
2827 indoc! {"
2828 namespace Test {
2829 function Echo(val1 : Int, val2 : Int) : (Int, Int) {
2830 return (val1, val2);
2831 }
2832 }
2833 "},
2834 "Test.Echo(42, 43)",
2835 &expect!["(42, 43)"],
2836 );
2837}
2838
2839#[test]
2840fn call_tuple_args_expr() {
2841 check_expr(
2842 indoc! {"
2843 namespace Test {
2844 function MakeList(val1 : (Int, Int), val2 : Int) : Int[] {
2845 let (v1, v2) = val1;
2846 return [v1, v2, val2];
2847 }
2848 }
2849 "},
2850 "Test.MakeList((42, 43), 44)",
2851 &expect!["[42, 43, 44]"],
2852 );
2853}
2854
2855#[test]
2856fn call_call_expr() {
2857 check_expr(
2858 indoc! {"
2859 namespace Test {
2860 function TupleToList(tup : (Int, Int)) : Int[] {
2861 let (val, size) = tup;
2862 return MakeList(val, size);
2863 }
2864 function MakeList(val : Int, size : Int) : Int[] {
2865 return [val, size = size];
2866 }
2867 }
2868 "},
2869 "Test.TupleToList((3, 2))",
2870 &expect!["[3, 3]"],
2871 );
2872}
2873
2874#[test]
2875fn call_adjoint_expr() {
2876 check_expr(
2877 indoc! {r#"
2878 namespace Test {
2879 operation Foo() : Unit is Adj + Ctl {
2880 body (...) {
2881 fail "Body Implementation";
2882 }
2883 adjoint (...) {
2884 fail "Adjoint Implementation";
2885 }
2886 controlled (ctls, ...) {
2887 fail "Controlled Implementation";
2888 }
2889 controlled adjoint (ctls, ...) {
2890 fail "Controlled Adjoint Implementation";
2891 }
2892 }
2893 }
2894 "#},
2895 "Adjoint Test.Foo()",
2896 &expect![[r#"
2897 (
2898 UserFail(
2899 "Adjoint Implementation",
2900 PackageSpan {
2901 package: PackageId(
2902 2,
2903 ),
2904 span: Span {
2905 lo: 185,
2906 hi: 214,
2907 },
2908 },
2909 ),
2910 [
2911 Frame {
2912 span: Span {
2913 lo: 190,
2914 hi: 214,
2915 },
2916 id: StoreItemId {
2917 package: PackageId(
2918 2,
2919 ),
2920 item: LocalItemId(
2921 1,
2922 ),
2923 },
2924 caller: PackageId(
2925 2,
2926 ),
2927 functor: FunctorApp {
2928 adjoint: true,
2929 controlled: 0,
2930 },
2931 },
2932 ],
2933 )
2934 "#]],
2935 );
2936}
2937
2938#[test]
2939fn call_adjoint_adjoint_expr() {
2940 check_expr(
2941 indoc! {r#"
2942 namespace Test {
2943 operation Foo() : Unit is Adj + Ctl {
2944 body (...) {
2945 fail "Body Implementation";
2946 }
2947 adjoint (...) {
2948 fail "Adjoint Implementation";
2949 }
2950 controlled (ctls, ...) {
2951 fail "Controlled Implementation";
2952 }
2953 controlled adjoint (ctls, ...) {
2954 fail "Controlled Adjoint Implementation";
2955 }
2956 }
2957 }
2958 "#},
2959 "Adjoint Adjoint Test.Foo()",
2960 &expect![[r#"
2961 (
2962 UserFail(
2963 "Body Implementation",
2964 PackageSpan {
2965 package: PackageId(
2966 2,
2967 ),
2968 span: Span {
2969 lo: 119,
2970 hi: 145,
2971 },
2972 },
2973 ),
2974 [
2975 Frame {
2976 span: Span {
2977 lo: 124,
2978 hi: 145,
2979 },
2980 id: StoreItemId {
2981 package: PackageId(
2982 2,
2983 ),
2984 item: LocalItemId(
2985 1,
2986 ),
2987 },
2988 caller: PackageId(
2989 2,
2990 ),
2991 functor: FunctorApp {
2992 adjoint: false,
2993 controlled: 0,
2994 },
2995 },
2996 ],
2997 )
2998 "#]],
2999 );
3000}
3001
3002#[test]
3003fn call_adjoint_self_expr() {
3004 check_expr(
3005 indoc! {r#"
3006 namespace Test {
3007 operation Foo() : Unit is Adj + Ctl {
3008 body (...) {
3009 fail "Body Implementation";
3010 }
3011 adjoint self;
3012 controlled (ctls, ...) {
3013 fail "Controlled Implementation";
3014 }
3015 }
3016 }
3017 "#},
3018 "Adjoint Test.Foo()",
3019 &expect![[r#"
3020 (
3021 UserFail(
3022 "Body Implementation",
3023 PackageSpan {
3024 package: PackageId(
3025 2,
3026 ),
3027 span: Span {
3028 lo: 111,
3029 hi: 137,
3030 },
3031 },
3032 ),
3033 [
3034 Frame {
3035 span: Span {
3036 lo: 116,
3037 hi: 137,
3038 },
3039 id: StoreItemId {
3040 package: PackageId(
3041 2,
3042 ),
3043 item: LocalItemId(
3044 1,
3045 ),
3046 },
3047 caller: PackageId(
3048 2,
3049 ),
3050 functor: FunctorApp {
3051 adjoint: true,
3052 controlled: 0,
3053 },
3054 },
3055 ],
3056 )
3057 "#]],
3058 );
3059}
3060
3061#[test]
3062fn check_ctls_count_expr() {
3063 check_expr(
3064 indoc! {r#"
3065 namespace Test {
3066 operation Foo() : Unit is Adj + Ctl {
3067 body (...) {}
3068 adjoint self;
3069 controlled (ctls, ...) {
3070 if Length(ctls) != 3 {
3071 fail "Incorrect ctls count!";
3072 }
3073 }
3074 }
3075 }
3076 "#},
3077 indoc! {"
3078 {
3079 use qs = Qubit[3];
3080 Controlled Test.Foo(qs, ());
3081 }
3082 "},
3083 &expect!["()"],
3084 );
3085}
3086
3087#[test]
3088fn check_ctls_count_nested_expr() {
3089 check_expr(
3090 indoc! {r#"
3091 namespace Test {
3092 operation Foo() : Unit is Adj + Ctl {
3093 body (...) {}
3094 adjoint self;
3095 controlled (ctls, ...) {
3096 if Length(ctls) != 3 {
3097 fail "Incorrect ctls count!";
3098 }
3099 }
3100 }
3101 }
3102 "#},
3103 indoc! {"
3104 {
3105 use qs1 = Qubit[1];
3106 use qs2 = Qubit[2];
3107 Controlled Controlled Test.Foo(qs2, (qs1, ()));
3108 }
3109 "},
3110 &expect!["()"],
3111 );
3112}
3113
3114#[test]
3115fn check_generated_ctl_expr() {
3116 check_expr(
3117 indoc! {r#"
3118 namespace Test {
3119 operation A() : Unit is Ctl {
3120 body ... {}
3121 controlled (ctls, ...) {
3122 if Length(ctls) != 3 {
3123 fail "Incorrect ctls count!";
3124 }
3125 }
3126 }
3127 operation B() : Unit is Ctl {
3128 A();
3129 }
3130 }
3131 "#},
3132 "{use qs = Qubit[3]; Controlled Test.B(qs, ())}",
3133 &expect!["()"],
3134 );
3135}
3136
3137#[test]
3138fn check_generated_ctladj_distrib_expr() {
3139 check_expr(
3140 indoc! {r#"
3141 namespace Test {
3142 operation A() : Unit is Ctl + Adj {
3143 body ... { fail "Shouldn't get here"; }
3144 adjoint self;
3145 controlled (ctls, ...) {
3146 if Length(ctls) != 3 {
3147 fail "Incorrect ctls count!";
3148 }
3149 }
3150 controlled adjoint (ctls, ...) {
3151 if Length(ctls) != 2 {
3152 fail "Incorrect ctls count!";
3153 }
3154 }
3155 }
3156 operation B() : Unit is Ctl + Adj {
3157 body ... { A(); }
3158 adjoint ... { Adjoint A(); }
3159 }
3160 }
3161 "#},
3162 "{use qs = Qubit[2]; Controlled Adjoint Test.B(qs, ())}",
3163 &expect!["()"],
3164 );
3165}
3166
3167#[test]
3168fn global_callable_as_arg() {
3169 check_expr(
3170 indoc! {"
3171 namespace Test {
3172 function PlusOne(x : Int) : Int {
3173 x + 1
3174 }
3175 function ApplyToIntArray(f : (Int -> Int)) : Int[] {
3176 mutable arr = [1, size = 3];
3177 for i in 0..2 {
3178 set arr w/= i <- f(arr[i]);
3179 }
3180 arr
3181 }
3182 }
3183 "},
3184 "Test.ApplyToIntArray(Test.PlusOne)",
3185 &expect!["[2, 2, 2]"],
3186 );
3187}
3188
3189#[test]
3190fn conjugate_output_preserved() {
3191 check_expr("", "{let x = within{}apply{4}; x}", &expect!["4"]);
3192}
3193
3194#[test]
3195fn interpolated_string() {
3196 check_expr("", r#"$"string""#, &expect!["string"]);
3197}
3198
3199#[test]
3200fn interpolated_string_var() {
3201 check_expr(
3202 "",
3203 indoc! {r#"{
3204 let x = 5;
3205 $"{x}"
3206 }"#},
3207 &expect!["5"],
3208 );
3209}
3210
3211#[test]
3212fn interpolated_string_array_index() {
3213 check_expr(
3214 "",
3215 indoc! {r#"{
3216 let xs = [1, 2, 3];
3217 $"{xs[0]}"
3218 }"#},
3219 &expect!["1"],
3220 );
3221}
3222
3223#[test]
3224fn interpolated_string_two_vars() {
3225 check_expr(
3226 "",
3227 indoc! {r#"{
3228 let x = 4;
3229 let y = (true, Zero);
3230 $"{x} {y}"
3231 }"#},
3232 &expect!["4 (true, Zero)"],
3233 );
3234}
3235
3236#[test]
3237fn interpolated_string_nested_normal_string() {
3238 check_expr("", r#"$"{"{}"}""#, &expect!["{}"]);
3239}
3240
3241#[test]
3242fn nested_interpolated_string() {
3243 check_expr(
3244 "",
3245 indoc! {r#"{
3246 let x = 4;
3247 $"{$"{x}"}"
3248 }"#},
3249 &expect!["4"],
3250 );
3251}
3252
3253#[test]
3254fn nested_interpolated_string_with_exprs() {
3255 check_expr(
3256 "",
3257 indoc! {r#"{
3258 let x = "hello!";
3259 let y = 1.5;
3260 $"foo {x + $"bar {y}"} baz"
3261 }"#},
3262 &expect!["foo hello!bar 1.5 baz"],
3263 );
3264}
3265
3266#[test]
3267fn udt_unwrap() {
3268 check_expr(
3269 "",
3270 "{
3271 newtype Foo = (Int, Bool);
3272 let foo = Foo(1, true);
3273 foo!
3274 }",
3275 &expect!["(1, true)"],
3276 );
3277}
3278
3279#[test]
3280fn udt_fields() {
3281 check_expr(
3282 "",
3283 "{
3284 newtype Point = (X : Int, Y : Int);
3285 let p = Point(1, 2);
3286 (p::X, p::Y)
3287 }",
3288 &expect!["(1, 2)"],
3289 );
3290}
3291
3292#[test]
3293fn udt_field_nested() {
3294 check_expr(
3295 "",
3296 "{
3297 newtype Point = (X : Int, (Y : Int, Z : Int));
3298 let p = Point(1, (2, 3));
3299 (p::Y, p::Z)
3300 }",
3301 &expect!["(2, 3)"],
3302 );
3303}
3304
3305#[test]
3306fn lambda_function_empty_closure() {
3307 check_expr("", "{ let f = x -> x + 1; f(1) }", &expect!["2"]);
3308}
3309
3310#[test]
3311fn lambda_function_empty_closure_passed() {
3312 check_expr(
3313 "",
3314 "{ function Foo(f : Int -> Int) : Int { f(2) }; Foo(x -> x + 1) }",
3315 &expect!["3"],
3316 );
3317}
3318
3319#[test]
3320fn lambda_function_closure() {
3321 check_expr(
3322 "",
3323 "{ let x = 5; let f = y -> (x, y); f(2) }",
3324 &expect!["(5, 2)"],
3325 );
3326}
3327
3328#[test]
3329fn lambda_function_closure_passed() {
3330 check_expr(
3331 "",
3332 "{ function Foo(f : Int -> (Int, Int)) : (Int, Int) { f(2) }; let x = 5; Foo(y -> (x, y)) }",
3333 &expect!["(5, 2)"],
3334 );
3335}
3336
3337#[test]
3338fn lambda_function_nested_closure() {
3339 check_expr(
3340 "
3341 namespace A {
3342 function Foo(f : Int -> Int -> (Int, Int, Int, Int)) : (Int, Int, Int, Int) {
3343 f(2)(3)
3344 }
3345
3346 function Bar() : (Int, Int, Int, Int) {
3347 let a = 5;
3348 Foo(b -> {
3349 let c = 1;
3350 d -> (a, b, c, d)
3351 })
3352 }
3353 }
3354 ",
3355 "A.Bar()",
3356 &expect!["(5, 2, 1, 3)"],
3357 );
3358}
3359
3360#[test]
3361fn lambda_operation_empty_closure() {
3362 check_expr(
3363 "
3364 namespace A {
3365 open Microsoft.Quantum.Measurement;
3366
3367 operation Foo(op : Qubit => ()) : Result {
3368 use q = Qubit();
3369 op(q);
3370 MResetZ(q)
3371 }
3372
3373 operation Bar() : Result { Foo(q => X(q)) }
3374 }
3375 ",
3376 "A.Bar()",
3377 &expect!["One"],
3378 );
3379}
3380
3381#[test]
3382fn lambda_operation_closure() {
3383 check_expr(
3384 "
3385 namespace A {
3386 open Microsoft.Quantum.Measurement;
3387 operation Foo(op : () => Result) : Result { op() }
3388 operation Bar() : Result {
3389 use q = Qubit();
3390 X(q);
3391 Foo(() => MResetZ(q))
3392 }
3393 }
3394 ",
3395 "A.Bar()",
3396 &expect!["One"],
3397 );
3398}
3399
3400#[test]
3401fn lambda_operation_controlled() {
3402 check_expr(
3403 "
3404 namespace A {
3405 open Microsoft.Quantum.Measurement;
3406 operation Foo(op : Qubit => Unit is Adj + Ctl, q : Qubit) : Unit is Adj + Ctl { op(q) }
3407 operation Bar() : Result[] {
3408 mutable output = [];
3409 use (ctls, q) = (Qubit[1], Qubit());
3410 let op = q => X(q);
3411 Foo(op, q);
3412 set output += [MResetZ(q)];
3413 Controlled Foo(ctls, (op, q));
3414 set output += [MResetZ(q)];
3415 X(ctls[0]);
3416 Controlled Foo(ctls, (op, q));
3417 set output += [MResetZ(q)];
3418 ResetAll(ctls);
3419 output
3420 }
3421 }
3422 ",
3423 "A.Bar()",
3424 &expect!["[One, Zero, One]"],
3425 );
3426}
3427
3428#[test]
3429fn lambda_operation_controlled_controlled() {
3430 check_expr(
3431 "
3432 namespace A {
3433 open Microsoft.Quantum.Measurement;
3434 operation Foo(op : Qubit => Unit is Adj + Ctl, q : Qubit) : Unit is Adj + Ctl { op(q) }
3435 operation Bar() : Result[] {
3436 mutable output = [];
3437 use (ctls1, ctls2, q) = (Qubit[1], Qubit[1], Qubit());
3438 let op = q => X(q);
3439 Foo(op, q);
3440 set output += [MResetZ(q)];
3441 Controlled Controlled Foo(ctls1, (ctls2, (op, q)));
3442 set output += [MResetZ(q)];
3443 X(ctls1[0]);
3444 X(ctls2[0]);
3445 Controlled Controlled Foo(ctls1, (ctls2, (op, q)));
3446 set output += [MResetZ(q)];
3447 ResetAll(ctls1 + ctls2);
3448 output
3449 }
3450 }
3451 ",
3452 "A.Bar()",
3453 &expect!["[One, Zero, One]"],
3454 );
3455}
3456
3457#[test]
3458fn partial_app_all_holes() {
3459 check_expr(
3460 "",
3461 "{
3462 function F(x : Int, y : Int) : Int { x + y }
3463 let f = F(_, _);
3464 f(1, 2)
3465 }",
3466 &expect!["3"],
3467 );
3468}
3469
3470#[test]
3471fn partial_app_one_fixed_arg() {
3472 check_expr(
3473 "",
3474 "{
3475 function F(x : Int, y : Int) : Int { x + y }
3476 let f = F(_, 2);
3477 f(1)
3478 }",
3479 &expect!["3"],
3480 );
3481}
3482
3483#[test]
3484fn partial_app_nested_tuple() {
3485 check_expr(
3486 "",
3487 "{
3488 function F(a : Int, (b : Int, c : Int, d : Int)) : (Int, Int, Int, Int) { (a, b, c, d) }
3489 let f = F(_, (_, 3, _));
3490 f(1, (2, 4))
3491 }",
3492 &expect!["(1, 2, 3, 4)"],
3493 );
3494}
3495
3496#[test]
3497fn partial_app_arg_with_side_effect() {
3498 check_expr(
3499 "",
3500 "{
3501 operation F(_ : (), x : Int) : Int { x }
3502 use q = Qubit();
3503 let f = F(X(q), _);
3504 let r1 = M(q);
3505 f(1);
3506 let r2 = M(q);
3507 f(2);
3508 let r3 = M(q);
3509 Reset(q);
3510 (r1, r2, r3)
3511 }",
3512 &expect!["(One, One, One)"],
3513 );
3514}
3515
3516#[test]
3517fn partial_app_mutable_arg() {
3518 check_expr(
3519 "",
3520 "{
3521 function F(a : Int, b : Int) : (Int, Int) { (a, b) }
3522 mutable x = 0;
3523 let f = F(x, _);
3524 let r1 = f(1);
3525 set x = 1;
3526 let r2 = f(2);
3527 (r1, r2)
3528 }",
3529 &expect!["((0, 1), (0, 2))"],
3530 );
3531}
3532