microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
cesarzc/ssa-panic

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_eval/src/tests.rs

4151lines · modecode

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