1use super::{CompletedMarker, EXPR_RECOVERY, Parser};
23use crate::syntax_kind::{SyntaxKind, SyntaxKind::*};
24
25fn infix_binding_power(op: SyntaxKind) -> Option<(u8, u8)> {
35 let bp = match op {
36 PIPE2 => (28, 29),
39 AMP2 => (26, 27),
41 EQ2 | BANG_EQ => (24, 25),
43 LT | LT_EQ | GT | GT_EQ => (22, 23),
45 PIPE => (20, 21),
47 CARET => (18, 19),
49 AMP => (16, 17),
51 SHL | SHR => (14, 15),
53 PLUS | MINUS => (12, 13),
55 STAR | SLASH | PERCENT => (10, 11),
57 STAR2 => (9, 8),
59 KW_AS => (6, 7),
61 _ => return None,
62 };
63 Some(bp)
64}
65
66fn prefix_binding_power(op: SyntaxKind) -> Option<u8> {
68 match op {
69 BANG | MINUS => Some(30),
71 _ => None,
72 }
73}
74
75fn postfix_binding_power(op: SyntaxKind) -> Option<u8> {
77 match op {
78 DOT | L_BRACKET | L_PAREN => Some(32),
80 _ => None,
81 }
82}
83
84#[derive(Default, Clone, Copy)]
90pub struct ExprOpts {
91 pub no_struct: bool,
94}
95
96impl ExprOpts {
97 pub fn no_struct() -> Self {
99 Self { no_struct: true }
100 }
101}
102
103impl Parser<'_, '_> {
108 pub fn parse_expr(&mut self) -> Option<CompletedMarker> {
110 self.parse_expr_with_opts(ExprOpts::default())
111 }
112
113 pub fn parse_expr_with_opts(&mut self, opts: ExprOpts) -> Option<CompletedMarker> {
115 self.parse_expr_bp(0, opts)
116 }
117
118 fn parse_expr_bp(&mut self, min_bp: u8, opts: ExprOpts) -> Option<CompletedMarker> {
120 let mut lhs = self.parse_prefix_expr(opts)?;
122
123 loop {
124 if let Some(bp) = self.current_postfix_bp() {
126 if bp < min_bp {
127 break;
128 }
129 lhs = self.parse_postfix_expr(lhs, opts)?;
130 continue;
131 }
132
133 if self.at(QUESTION) && min_bp <= 2 {
135 lhs = self.parse_ternary_expr(lhs)?;
136 continue;
137 }
138
139 let op = self.current();
141 if let Some((l_bp, r_bp)) = infix_binding_power(op) {
142 if l_bp < min_bp {
143 break;
144 }
145 lhs = self.parse_infix_expr(lhs, op, r_bp, opts)?;
146 continue;
147 }
148
149 break;
150 }
151
152 Some(lhs)
153 }
154
155 fn current_postfix_bp(&self) -> Option<u8> {
157 postfix_binding_power(self.current())
158 }
159
160 fn parse_prefix_expr(&mut self, opts: ExprOpts) -> Option<CompletedMarker> {
162 self.skip_trivia();
163
164 if let Some(bp) = prefix_binding_power(self.current()) {
166 let m = self.start();
167 self.bump_any(); if self.parse_expr_bp(bp, opts).is_none() {
172 self.error("expected expression after unary operator".to_string());
173 }
174
175 return Some(m.complete(self, UNARY_EXPR));
176 }
177
178 self.parse_primary_expr(opts)
180 }
181
182 fn parse_postfix_expr(&mut self, lhs: CompletedMarker, opts: ExprOpts) -> Option<CompletedMarker> {
184 match self.current() {
185 DOT => self.parse_member_access(lhs),
186 L_BRACKET => self.parse_index_expr(lhs),
187 L_PAREN => self.parse_call_expr(lhs, opts),
188 _ => Some(lhs),
189 }
190 }
191
192 fn parse_infix_expr(
194 &mut self,
195 lhs: CompletedMarker,
196 op: SyntaxKind,
197 r_bp: u8,
198 opts: ExprOpts,
199 ) -> Option<CompletedMarker> {
200 let m = lhs.precede(self);
201 self.bump_any(); if op == KW_AS {
205 if self.parse_type().is_none() {
206 self.error("expected type after 'as'".to_string());
207 }
208 return Some(m.complete(self, CAST_EXPR));
209 }
210
211 if self.parse_expr_bp(r_bp, opts).is_none() {
214 self.error("expected expression after operator".to_string());
215 }
216
217 Some(m.complete(self, BINARY_EXPR))
218 }
219
220 fn parse_ternary_expr(&mut self, condition: CompletedMarker) -> Option<CompletedMarker> {
222 let m = condition.precede(self);
223 self.bump_any(); if self.parse_expr().is_none() {
227 self.error("expected expression after '?'".to_string());
228 }
229
230 self.expect(COLON);
231
232 if self.parse_expr_bp(2, ExprOpts::default()).is_none() {
234 self.error("expected expression after ':'".to_string());
235 }
236
237 Some(m.complete(self, TERNARY_EXPR))
238 }
239
240 fn parse_member_access(&mut self, lhs: CompletedMarker) -> Option<CompletedMarker> {
242 let m = lhs.precede(self);
243 self.bump_any(); self.skip_trivia();
246
247 if self.at(IDENT) || self.at(INTEGER) || self.current().is_keyword() {
250 self.bump_any();
251 } else {
252 self.error("expected field name or tuple index".to_string());
253 }
254
255 Some(m.complete(self, FIELD_EXPR))
256 }
257
258 fn parse_index_expr(&mut self, lhs: CompletedMarker) -> Option<CompletedMarker> {
260 let m = lhs.precede(self);
261 self.bump_any(); if self.parse_expr().is_none() {
264 self.error("expected index expression".to_string());
265 }
266
267 self.expect(R_BRACKET);
268
269 Some(m.complete(self, INDEX_EXPR))
270 }
271
272 fn parse_call_expr(&mut self, lhs: CompletedMarker, _opts: ExprOpts) -> Option<CompletedMarker> {
274 let m = lhs.precede(self);
275 self.bump_any(); if !self.at(R_PAREN) {
279 if self.parse_expr().is_none() && !self.at(R_PAREN) && !self.at(COMMA) {
280 self.error_recover("expected argument expression", EXPR_RECOVERY);
282 }
283 while self.eat(COMMA) {
284 if self.at(R_PAREN) {
285 break;
286 }
287 if self.parse_expr().is_none() && !self.at(R_PAREN) && !self.at(COMMA) {
288 self.error_recover("expected argument expression", EXPR_RECOVERY);
289 }
290 }
291 }
292
293 self.expect(R_PAREN);
294
295 Some(m.complete(self, CALL_EXPR))
296 }
297
298 fn parse_primary_expr(&mut self, opts: ExprOpts) -> Option<CompletedMarker> {
304 self.skip_trivia();
305
306 match self.current() {
307 INTEGER => self.parse_integer_literal(),
309 STRING => self.parse_string_literal(),
310 ADDRESS_LIT => self.parse_address_literal(),
311 KW_TRUE | KW_FALSE => self.parse_bool_literal(),
312 KW_NONE => self.parse_none_literal(),
313
314 L_PAREN => self.parse_paren_or_tuple_expr(),
316
317 L_BRACKET => self.parse_array_expr(),
319
320 IDENT => self.parse_ident_expr(opts),
322
323 KW_SELF => self.parse_self_expr(),
325
326 KW_BLOCK => self.parse_block_access(),
328 KW_NETWORK => self.parse_network_access(),
329
330 KW_ASYNC => self.parse_async_block_expr(),
332
333 _ => {
334 self.error(format!("expected expression, found {:?}", self.current()));
335 None
336 }
337 }
338 }
339
340 fn parse_integer_literal(&mut self) -> Option<CompletedMarker> {
342 let m = self.start();
343 self.bump_any();
344 Some(m.complete(self, LITERAL))
345 }
346
347 fn parse_string_literal(&mut self) -> Option<CompletedMarker> {
349 let m = self.start();
350 self.bump_any();
351 Some(m.complete(self, LITERAL))
352 }
353
354 fn parse_address_literal(&mut self) -> Option<CompletedMarker> {
356 let m = self.start();
357 self.bump_any();
358 Some(m.complete(self, LITERAL))
359 }
360
361 fn parse_bool_literal(&mut self) -> Option<CompletedMarker> {
363 let m = self.start();
364 self.bump_any();
365 Some(m.complete(self, LITERAL))
366 }
367
368 fn parse_none_literal(&mut self) -> Option<CompletedMarker> {
370 let m = self.start();
371 self.bump_any();
372 Some(m.complete(self, LITERAL))
373 }
374
375 fn parse_paren_or_tuple_expr(&mut self) -> Option<CompletedMarker> {
377 let m = self.start();
378 self.bump_any(); if self.eat(R_PAREN) {
382 return Some(m.complete(self, TUPLE_EXPR));
383 }
384
385 if self.parse_expr().is_none() && !self.at(R_PAREN) && !self.at(COMMA) {
387 self.error_recover("expected expression", EXPR_RECOVERY);
388 }
389
390 if self.eat(COMMA) {
392 if !self.at(R_PAREN) {
394 if self.parse_expr().is_none() && !self.at(R_PAREN) && !self.at(COMMA) {
395 self.error_recover("expected tuple element", EXPR_RECOVERY);
396 }
397 while self.eat(COMMA) {
398 if self.at(R_PAREN) {
399 break;
400 }
401 if self.parse_expr().is_none() && !self.at(R_PAREN) && !self.at(COMMA) {
402 self.error_recover("expected tuple element", EXPR_RECOVERY);
403 }
404 }
405 }
406 self.expect(R_PAREN);
407 return Some(m.complete(self, TUPLE_EXPR));
408 }
409
410 self.expect(R_PAREN);
412 Some(m.complete(self, PAREN_EXPR))
413 }
414
415 fn parse_array_expr(&mut self) -> Option<CompletedMarker> {
417 let m = self.start();
418 self.bump_any(); if self.eat(R_BRACKET) {
422 return Some(m.complete(self, ARRAY_EXPR));
423 }
424
425 if self.parse_expr().is_none() && !self.at(R_BRACKET) && !self.at(COMMA) && !self.at(SEMICOLON) {
427 self.error_recover("expected array element", EXPR_RECOVERY);
428 }
429
430 if self.eat(SEMICOLON) {
432 if self.parse_expr().is_none() && !self.at(R_BRACKET) {
433 self.error("expected repeat count".to_string());
434 }
435 self.expect(R_BRACKET);
436 return Some(m.complete(self, ARRAY_EXPR));
437 }
438
439 while self.eat(COMMA) {
441 if self.at(R_BRACKET) {
442 break;
443 }
444 if self.parse_expr().is_none() && !self.at(R_BRACKET) && !self.at(COMMA) {
445 self.error_recover("expected array element", EXPR_RECOVERY);
446 }
447 }
448
449 self.expect(R_BRACKET);
450 Some(m.complete(self, ARRAY_EXPR))
451 }
452
453 fn parse_ident_expr(&mut self, opts: ExprOpts) -> Option<CompletedMarker> {
455 let m = self.start();
456 self.bump_any(); if self.at(DOT) && self.nth(1) == KW_ALEO {
460 self.bump_any(); self.bump_any(); if self.eat(SLASH) {
464 if self.at(IDENT) {
466 self.bump_any();
467 }
468 }
469
470 if self.at(COLON_COLON) && self.nth(1) == L_BRACKET {
472 self.bump_any(); self.parse_const_generic_args_bracket();
474 }
475
476 if !opts.no_struct && self.at(L_BRACE) {
478 self.bump_any(); if !self.at(R_BRACE) {
480 self.parse_struct_field();
481 while self.eat(COMMA) {
482 if self.at(R_BRACE) {
483 break;
484 }
485 self.parse_struct_field();
486 }
487 }
488 self.expect(R_BRACE);
489 return Some(m.complete(self, STRUCT_EXPR));
490 }
491
492 if self.at(L_PAREN) {
494 let cm = m.complete(self, PATH_EXPR);
495 return self.parse_call_expr(cm, opts);
496 }
497
498 return Some(m.complete(self, PATH_EXPR));
499 }
500
501 while self.eat(COLON_COLON) {
503 if self.at(L_BRACKET) {
504 self.parse_const_generic_args_bracket();
506 break;
507 } else if self.at(LT) {
508 self.parse_const_generic_args_angle();
511 break;
512 } else if self.at(IDENT) {
513 self.bump_any();
514 } else {
515 self.error("expected identifier after ::".to_string());
516 break;
517 }
518 }
519
520 if !opts.no_struct && self.at(L_BRACE) {
522 self.bump_any(); if !self.at(R_BRACE) {
526 self.parse_struct_field();
527 while self.eat(COMMA) {
528 if self.at(R_BRACE) {
529 break;
530 }
531 self.parse_struct_field();
532 }
533 }
534
535 self.expect(R_BRACE);
536 return Some(m.complete(self, STRUCT_EXPR));
537 }
538
539 if self.at(L_PAREN) {
541 let cm = m.complete(self, PATH_EXPR);
542 return self.parse_call_expr(cm, opts);
543 }
544
545 Some(m.complete(self, PATH_EXPR))
546 }
547
548 fn parse_struct_field(&mut self) {
550 let m = self.start();
551 self.skip_trivia();
552
553 if self.at(IDENT) {
554 self.bump_any(); if self.eat(COLON) {
557 if self.parse_expr().is_none() && !self.at(R_BRACE) && !self.at(COMMA) {
559 self.error("expected field value".to_string());
560 }
561 }
562 } else {
564 self.error("expected field name".to_string());
565 }
566
567 m.complete(self, STRUCT_FIELD_INIT);
568 }
569
570 fn parse_self_expr(&mut self) -> Option<CompletedMarker> {
572 let m = self.start();
573 self.bump_any(); Some(m.complete(self, PATH_EXPR))
575 }
576
577 fn parse_block_access(&mut self) -> Option<CompletedMarker> {
579 let m = self.start();
580 self.bump_any(); Some(m.complete(self, PATH_EXPR))
582 }
583
584 fn parse_network_access(&mut self) -> Option<CompletedMarker> {
586 let m = self.start();
587 self.bump_any(); Some(m.complete(self, PATH_EXPR))
589 }
590
591 fn parse_async_block_expr(&mut self) -> Option<CompletedMarker> {
593 let m = self.start();
594 self.bump_any(); self.skip_trivia();
596 if self.parse_block().is_none() {
597 self.error("expected block after 'async'".to_string());
598 }
599 Some(m.complete(self, ASYNC_EXPR))
600 }
601}
602
603#[cfg(test)]
604mod tests {
605 use super::*;
606 use crate::{lexer::lex, parser::Parse};
607 use expect_test::{Expect, expect};
608
609 fn check_expr(input: &str, expect: Expect) {
610 let (tokens, _) = lex(input);
611 let mut parser = Parser::new(input, &tokens);
612 let root = parser.start();
613 parser.parse_expr();
614 parser.skip_trivia();
615 root.complete(&mut parser, ROOT);
616 let parse: Parse = parser.finish();
617 let output = format!("{:#?}", parse.syntax());
618 expect.assert_eq(&output);
619 }
620
621 #[test]
626 fn parse_expr_integer() {
627 check_expr("42", expect![[r#"
628 ROOT@0..2
629 LITERAL@0..2
630 INTEGER@0..2 "42"
631 "#]]);
632 }
633
634 #[test]
635 fn parse_expr_bool_true() {
636 check_expr("true", expect![[r#"
637 ROOT@0..4
638 LITERAL@0..4
639 KW_TRUE@0..4 "true"
640 "#]]);
641 }
642
643 #[test]
644 fn parse_expr_bool_false() {
645 check_expr("false", expect![[r#"
646 ROOT@0..5
647 LITERAL@0..5
648 KW_FALSE@0..5 "false"
649 "#]]);
650 }
651
652 #[test]
653 fn parse_expr_none() {
654 check_expr("none", expect![[r#"
655 ROOT@0..4
656 LITERAL@0..4
657 KW_NONE@0..4 "none"
658 "#]]);
659 }
660
661 #[test]
666 fn parse_expr_ident() {
667 check_expr("foo", expect![[r#"
668 ROOT@0..3
669 PATH_EXPR@0..3
670 IDENT@0..3 "foo"
671 "#]]);
672 }
673
674 #[test]
675 fn parse_expr_path() {
676 check_expr("Foo::bar", expect![[r#"
677 ROOT@0..8
678 PATH_EXPR@0..8
679 IDENT@0..3 "Foo"
680 COLON_COLON@3..5 "::"
681 IDENT@5..8 "bar"
682 "#]]);
683 }
684
685 #[test]
686 fn parse_expr_self() {
687 check_expr("self", expect![[r#"
688 ROOT@0..4
689 PATH_EXPR@0..4
690 KW_SELF@0..4 "self"
691 "#]]);
692 }
693
694 #[test]
699 fn parse_expr_add() {
700 check_expr("1 + 2", expect![[r#"
701 ROOT@0..5
702 BINARY_EXPR@0..5
703 LITERAL@0..1
704 INTEGER@0..1 "1"
705 WHITESPACE@1..2 " "
706 PLUS@2..3 "+"
707 WHITESPACE@3..4 " "
708 LITERAL@4..5
709 INTEGER@4..5 "2"
710 "#]]);
711 }
712
713 #[test]
714 fn parse_expr_mul() {
715 check_expr("a * b", expect![[r#"
716 ROOT@0..5
717 BINARY_EXPR@0..5
718 PATH_EXPR@0..2
719 IDENT@0..1 "a"
720 WHITESPACE@1..2 " "
721 STAR@2..3 "*"
722 WHITESPACE@3..4 " "
723 PATH_EXPR@4..5
724 IDENT@4..5 "b"
725 "#]]);
726 }
727
728 #[test]
729 fn parse_expr_precedence() {
730 check_expr("1 + 2 * 3", expect![[r#"
732 ROOT@0..9
733 BINARY_EXPR@0..9
734 BINARY_EXPR@0..5
735 LITERAL@0..1
736 INTEGER@0..1 "1"
737 WHITESPACE@1..2 " "
738 PLUS@2..3 "+"
739 WHITESPACE@3..4 " "
740 LITERAL@4..5
741 INTEGER@4..5 "2"
742 WHITESPACE@5..6 " "
743 STAR@6..7 "*"
744 WHITESPACE@7..8 " "
745 LITERAL@8..9
746 INTEGER@8..9 "3"
747 "#]]);
748 }
749
750 #[test]
751 fn parse_expr_power_right_assoc() {
752 check_expr("a ** b ** c", expect![[r#"
754 ROOT@0..11
755 BINARY_EXPR@0..11
756 PATH_EXPR@0..2
757 IDENT@0..1 "a"
758 WHITESPACE@1..2 " "
759 STAR2@2..4 "**"
760 WHITESPACE@4..5 " "
761 BINARY_EXPR@5..11
762 PATH_EXPR@5..7
763 IDENT@5..6 "b"
764 WHITESPACE@6..7 " "
765 STAR2@7..9 "**"
766 WHITESPACE@9..10 " "
767 PATH_EXPR@10..11
768 IDENT@10..11 "c"
769 "#]]);
770 }
771
772 #[test]
777 fn parse_expr_unary_neg() {
778 check_expr("-x", expect![[r#"
779 ROOT@0..2
780 UNARY_EXPR@0..2
781 MINUS@0..1 "-"
782 PATH_EXPR@1..2
783 IDENT@1..2 "x"
784 "#]]);
785 }
786
787 #[test]
788 fn parse_expr_unary_not() {
789 check_expr("!flag", expect![[r#"
790 ROOT@0..5
791 UNARY_EXPR@0..5
792 BANG@0..1 "!"
793 PATH_EXPR@1..5
794 IDENT@1..5 "flag"
795 "#]]);
796 }
797
798 #[test]
803 fn parse_expr_comparison() {
804 check_expr("a < b", expect![[r#"
805 ROOT@0..5
806 BINARY_EXPR@0..5
807 PATH_EXPR@0..2
808 IDENT@0..1 "a"
809 WHITESPACE@1..2 " "
810 LT@2..3 "<"
811 WHITESPACE@3..4 " "
812 PATH_EXPR@4..5
813 IDENT@4..5 "b"
814 "#]]);
815 }
816
817 #[test]
818 fn parse_expr_logical_and() {
819 check_expr("a && b", expect![[r#"
820 ROOT@0..6
821 BINARY_EXPR@0..6
822 PATH_EXPR@0..2
823 IDENT@0..1 "a"
824 WHITESPACE@1..2 " "
825 AMP2@2..4 "&&"
826 WHITESPACE@4..5 " "
827 PATH_EXPR@5..6
828 IDENT@5..6 "b"
829 "#]]);
830 }
831
832 #[test]
833 fn parse_expr_logical_or() {
834 check_expr("a || b", expect![[r#"
835 ROOT@0..6
836 BINARY_EXPR@0..6
837 PATH_EXPR@0..2
838 IDENT@0..1 "a"
839 WHITESPACE@1..2 " "
840 PIPE2@2..4 "||"
841 WHITESPACE@4..5 " "
842 PATH_EXPR@5..6
843 IDENT@5..6 "b"
844 "#]]);
845 }
846
847 #[test]
852 fn parse_expr_ternary() {
853 check_expr("a ? b : c", expect![[r#"
854 ROOT@0..9
855 TERNARY_EXPR@0..9
856 PATH_EXPR@0..2
857 IDENT@0..1 "a"
858 WHITESPACE@1..2 " "
859 QUESTION@2..3 "?"
860 WHITESPACE@3..4 " "
861 PATH_EXPR@4..6
862 IDENT@4..5 "b"
863 WHITESPACE@5..6 " "
864 COLON@6..7 ":"
865 WHITESPACE@7..8 " "
866 PATH_EXPR@8..9
867 IDENT@8..9 "c"
868 "#]]);
869 }
870
871 #[test]
876 fn parse_expr_member_access() {
877 check_expr("foo.bar", expect![[r#"
878 ROOT@0..7
879 FIELD_EXPR@0..7
880 PATH_EXPR@0..3
881 IDENT@0..3 "foo"
882 DOT@3..4 "."
883 IDENT@4..7 "bar"
884 "#]]);
885 }
886
887 #[test]
888 fn parse_expr_tuple_access() {
889 check_expr("tuple.0", expect![[r#"
890 ROOT@0..7
891 FIELD_EXPR@0..7
892 PATH_EXPR@0..5
893 IDENT@0..5 "tuple"
894 DOT@5..6 "."
895 INTEGER@6..7 "0"
896 "#]]);
897 }
898
899 #[test]
900 fn parse_expr_index() {
901 check_expr("arr[0]", expect![[r#"
902 ROOT@0..6
903 INDEX_EXPR@0..6
904 PATH_EXPR@0..3
905 IDENT@0..3 "arr"
906 L_BRACKET@3..4 "["
907 LITERAL@4..5
908 INTEGER@4..5 "0"
909 R_BRACKET@5..6 "]"
910 "#]]);
911 }
912
913 #[test]
914 fn parse_expr_call() {
915 check_expr("foo(a, b)", expect![[r#"
916 ROOT@0..9
917 CALL_EXPR@0..9
918 PATH_EXPR@0..3
919 IDENT@0..3 "foo"
920 L_PAREN@3..4 "("
921 PATH_EXPR@4..5
922 IDENT@4..5 "a"
923 COMMA@5..6 ","
924 WHITESPACE@6..7 " "
925 PATH_EXPR@7..8
926 IDENT@7..8 "b"
927 R_PAREN@8..9 ")"
928 "#]]);
929 }
930
931 #[test]
932 fn parse_expr_method_call() {
933 check_expr("x.foo()", expect![[r#"
934 ROOT@0..7
935 CALL_EXPR@0..7
936 FIELD_EXPR@0..5
937 PATH_EXPR@0..1
938 IDENT@0..1 "x"
939 DOT@1..2 "."
940 IDENT@2..5 "foo"
941 L_PAREN@5..6 "("
942 R_PAREN@6..7 ")"
943 "#]]);
944 }
945
946 #[test]
951 fn parse_expr_cast() {
952 check_expr("x as u64", expect![[r#"
953 ROOT@0..8
954 CAST_EXPR@0..8
955 PATH_EXPR@0..2
956 IDENT@0..1 "x"
957 WHITESPACE@1..2 " "
958 KW_AS@2..4 "as"
959 WHITESPACE@4..5 " "
960 TYPE_PATH@5..8
961 KW_U64@5..8 "u64"
962 "#]]);
963 }
964
965 #[test]
970 fn parse_expr_paren() {
971 check_expr("(a + b)", expect![[r#"
972 ROOT@0..7
973 PAREN_EXPR@0..7
974 L_PAREN@0..1 "("
975 BINARY_EXPR@1..6
976 PATH_EXPR@1..3
977 IDENT@1..2 "a"
978 WHITESPACE@2..3 " "
979 PLUS@3..4 "+"
980 WHITESPACE@4..5 " "
981 PATH_EXPR@5..6
982 IDENT@5..6 "b"
983 R_PAREN@6..7 ")"
984 "#]]);
985 }
986
987 #[test]
988 fn parse_expr_tuple() {
989 check_expr("(a, b)", expect![[r#"
990 ROOT@0..6
991 TUPLE_EXPR@0..6
992 L_PAREN@0..1 "("
993 PATH_EXPR@1..2
994 IDENT@1..2 "a"
995 COMMA@2..3 ","
996 WHITESPACE@3..4 " "
997 PATH_EXPR@4..5
998 IDENT@4..5 "b"
999 R_PAREN@5..6 ")"
1000 "#]]);
1001 }
1002
1003 #[test]
1004 fn parse_expr_unit() {
1005 check_expr("()", expect![[r#"
1006 ROOT@0..2
1007 TUPLE_EXPR@0..2
1008 L_PAREN@0..1 "("
1009 R_PAREN@1..2 ")"
1010 "#]]);
1011 }
1012
1013 #[test]
1018 fn parse_expr_array() {
1019 check_expr("[1, 2, 3]", expect![[r#"
1020 ROOT@0..9
1021 ARRAY_EXPR@0..9
1022 L_BRACKET@0..1 "["
1023 LITERAL@1..2
1024 INTEGER@1..2 "1"
1025 COMMA@2..3 ","
1026 WHITESPACE@3..4 " "
1027 LITERAL@4..5
1028 INTEGER@4..5 "2"
1029 COMMA@5..6 ","
1030 WHITESPACE@6..7 " "
1031 LITERAL@7..8
1032 INTEGER@7..8 "3"
1033 R_BRACKET@8..9 "]"
1034 "#]]);
1035 }
1036
1037 #[test]
1038 fn parse_expr_array_repeat() {
1039 check_expr("[0; 10]", expect![[r#"
1040 ROOT@0..7
1041 ARRAY_EXPR@0..7
1042 L_BRACKET@0..1 "["
1043 LITERAL@1..2
1044 INTEGER@1..2 "0"
1045 SEMICOLON@2..3 ";"
1046 WHITESPACE@3..4 " "
1047 LITERAL@4..6
1048 INTEGER@4..6 "10"
1049 R_BRACKET@6..7 "]"
1050 "#]]);
1051 }
1052
1053 #[test]
1058 fn parse_expr_struct_init() {
1059 check_expr("Point { x: 1, y: 2 }", expect![[r#"
1060 ROOT@0..20
1061 STRUCT_EXPR@0..20
1062 IDENT@0..5 "Point"
1063 WHITESPACE@5..6 " "
1064 L_BRACE@6..7 "{"
1065 STRUCT_FIELD_INIT@7..12
1066 WHITESPACE@7..8 " "
1067 IDENT@8..9 "x"
1068 COLON@9..10 ":"
1069 WHITESPACE@10..11 " "
1070 LITERAL@11..12
1071 INTEGER@11..12 "1"
1072 COMMA@12..13 ","
1073 STRUCT_FIELD_INIT@13..18
1074 WHITESPACE@13..14 " "
1075 IDENT@14..15 "y"
1076 COLON@15..16 ":"
1077 WHITESPACE@16..17 " "
1078 LITERAL@17..18
1079 INTEGER@17..18 "2"
1080 WHITESPACE@18..19 " "
1081 R_BRACE@19..20 "}"
1082 "#]]);
1083 }
1084
1085 #[test]
1086 fn parse_expr_struct_shorthand() {
1087 check_expr("Point { x, y }", expect![[r#"
1088 ROOT@0..14
1089 STRUCT_EXPR@0..14
1090 IDENT@0..5 "Point"
1091 WHITESPACE@5..6 " "
1092 L_BRACE@6..7 "{"
1093 STRUCT_FIELD_INIT@7..9
1094 WHITESPACE@7..8 " "
1095 IDENT@8..9 "x"
1096 COMMA@9..10 ","
1097 STRUCT_FIELD_INIT@10..13
1098 WHITESPACE@10..11 " "
1099 IDENT@11..12 "y"
1100 WHITESPACE@12..13 " "
1101 R_BRACE@13..14 "}"
1102 "#]]);
1103 }
1104
1105 fn check_expr_no_errors(input: &str) {
1114 let (tokens, _) = lex(input);
1115 let mut parser = Parser::new(input, &tokens);
1116 let root = parser.start();
1117 parser.parse_expr();
1118 parser.skip_trivia();
1119 root.complete(&mut parser, ROOT);
1120 let parse: Parse = parser.finish();
1121 if !parse.errors().is_empty() {
1122 for err in parse.errors() {
1123 eprintln!("error at {:?}: {}", err.range, err.message);
1124 }
1125 eprintln!("tree:\n{:#?}", parse.syntax());
1126 panic!("expression parse had {} error(s)", parse.errors().len());
1127 }
1128 }
1129
1130 #[test]
1131 fn parse_expr_call_const_generic_simple() {
1132 check_expr_no_errors("foo::[5]()");
1134 }
1135
1136 #[test]
1137 fn parse_expr_call_const_generic_expr() {
1138 check_expr_no_errors("foo::[N + 1]()");
1140 }
1141
1142 #[test]
1143 fn parse_expr_call_const_generic_multi() {
1144 check_expr_no_errors("bar::[M, K, N]()");
1146 }
1147
1148 #[test]
1149 fn parse_expr_struct_lit_const_generic() {
1150 check_expr_no_errors("Foo::[8u32] { arr: x }");
1152 }
1153
1154 #[test]
1155 fn parse_expr_locator_call_const_generic() {
1156 check_expr_no_errors("child.aleo/foo::[3]()");
1158 }
1159
1160 #[test]
1161 fn parse_expr_assoc_fn_const_generic() {
1162 check_expr_no_errors("Foo::bar::[N]()");
1164 }
1165
1166 #[test]
1171 fn parse_expr_complex() {
1172 check_expr("a.b[c](d) + e", expect![[r#"
1173 ROOT@0..13
1174 BINARY_EXPR@0..13
1175 CALL_EXPR@0..9
1176 INDEX_EXPR@0..6
1177 FIELD_EXPR@0..3
1178 PATH_EXPR@0..1
1179 IDENT@0..1 "a"
1180 DOT@1..2 "."
1181 IDENT@2..3 "b"
1182 L_BRACKET@3..4 "["
1183 PATH_EXPR@4..5
1184 IDENT@4..5 "c"
1185 R_BRACKET@5..6 "]"
1186 L_PAREN@6..7 "("
1187 PATH_EXPR@7..8
1188 IDENT@7..8 "d"
1189 R_PAREN@8..9 ")"
1190 WHITESPACE@9..10 " "
1191 PLUS@10..11 "+"
1192 WHITESPACE@11..12 " "
1193 PATH_EXPR@12..13
1194 IDENT@12..13 "e"
1195 "#]]);
1196 }
1197}