1use super::{
4 ast::{
5 BinOp, BinOpTy, Expr, ExprTy, Ident, Lit, PostOp, PostOpTy, PreOp,
6 PreOpTy,
7 },
8 SyntaxModifiers, SyntaxToken, SyntaxType, Walker,
9};
10use crate::{
11 diag::{ExprDiag, Semantic, Syntax},
12 lexer::{self, Token},
13 Either, Span,
14};
15use std::collections::VecDeque;
16
17pub(super) fn expr_parser<'a, P: super::TokenStreamProvider<'a>>(
40 walker: &mut Walker<'a, P>,
41 mode: Mode,
42 end_tokens: impl AsRef<[Token]>,
43) -> (Option<Expr>, Vec<Syntax>, Vec<Semantic>, Vec<SyntaxToken>) {
44 let start_position = match walker.peek() {
45 Some((_, span)) => span.start,
46 None => return (None, vec![], vec![], vec![]),
48 };
49
50 let mut parser = ShuntingYard {
51 stack: VecDeque::new(),
52 operators: VecDeque::new(),
53 groups: Vec::new(),
54 start_position,
55 mode,
56 syntax_diags: Vec::new(),
57 semantic_diags: Vec::new(),
58 syntax_tokens: Vec::new(),
59 };
60 parser.parse(walker, end_tokens.as_ref());
61
62 (
63 parser.create_ast(),
64 parser.syntax_diags,
65 parser.semantic_diags,
66 parser.syntax_tokens,
67 )
68}
69
70#[derive(Debug, PartialEq, Eq)]
72pub(super) enum Mode {
73 Default,
76 DisallowTopLevelList,
79 BreakAtEq,
82 TakeOneUnit,
107}
108
109#[derive(Debug, Clone, PartialEq)]
111struct Node {
112 ty: NodeTy,
113 span: Span,
114}
115
116#[derive(Debug, Clone, PartialEq)]
117enum NodeTy {
118 Lit(Lit),
119 Ident(Ident),
120 Separator,
121}
122
123#[derive(Debug, Clone, PartialEq)]
125struct Op {
126 ty: OpTy,
127 span: Span,
128}
129
130#[derive(Debug, Clone, PartialEq)]
131enum OpTy {
132 Add(bool),
135 Sub(bool),
136 Mul(bool),
137 Div(bool),
138 Rem(bool),
139 And(bool),
140 Or(bool),
141 Xor(bool),
142 LShift(bool),
143 RShift(bool),
144 Eq(bool),
145 AddEq(bool),
146 SubEq(bool),
147 MulEq(bool),
148 DivEq(bool),
149 RemEq(bool),
150 AndEq(bool),
151 OrEq(bool),
152 XorEq(bool),
153 LShiftEq(bool),
154 RShiftEq(bool),
155 EqEq(bool),
156 NotEq(bool),
157 AndAnd(bool),
158 OrOr(bool),
159 XorXor(bool),
160 Gt(bool),
161 Lt(bool),
162 Ge(bool),
163 Le(bool),
164 ObjAccess(bool),
166 TernaryQ(bool),
168 TernaryC(bool),
170 AddPre(bool),
173 SubPre(bool),
174 Neg(bool),
175 Flip(bool),
176 Not(bool),
177 AddPost,
179 SubPost,
180 ParenStart,
183 FnCallStart,
185 IndexStart,
187 InitStart,
189 ArrInitStart,
191 Paren(bool, Span, Span),
199 FnCall(usize, Span, Span),
207 Index(bool, Span, Span),
213 Init(usize, Span, Span),
219 ArrInit(usize, Span, Span),
227 List(usize),
231}
232
233impl Op {
234 fn from_token(token: lexer::OpTy, span: Span) -> Self {
236 Self {
237 span,
238 ty: match token {
239 lexer::OpTy::Add => OpTy::Add(false),
240 lexer::OpTy::Sub => OpTy::Sub(false),
241 lexer::OpTy::Mul => OpTy::Mul(false),
242 lexer::OpTy::Div => OpTy::Div(false),
243 lexer::OpTy::Rem => OpTy::Rem(false),
244 lexer::OpTy::And => OpTy::And(false),
245 lexer::OpTy::Or => OpTy::Or(false),
246 lexer::OpTy::Xor => OpTy::Xor(false),
247 lexer::OpTy::LShift => OpTy::LShift(false),
248 lexer::OpTy::RShift => OpTy::RShift(false),
249 lexer::OpTy::Eq => OpTy::Eq(false),
250 lexer::OpTy::AddEq => OpTy::AddEq(false),
251 lexer::OpTy::SubEq => OpTy::SubEq(false),
252 lexer::OpTy::MulEq => OpTy::MulEq(false),
253 lexer::OpTy::DivEq => OpTy::DivEq(false),
254 lexer::OpTy::RemEq => OpTy::RemEq(false),
255 lexer::OpTy::AndEq => OpTy::AndEq(false),
256 lexer::OpTy::OrEq => OpTy::OrEq(false),
257 lexer::OpTy::XorEq => OpTy::XorEq(false),
258 lexer::OpTy::LShiftEq => OpTy::LShiftEq(false),
259 lexer::OpTy::RShiftEq => OpTy::RShiftEq(false),
260 lexer::OpTy::EqEq => OpTy::EqEq(false),
261 lexer::OpTy::NotEq => OpTy::NotEq(false),
262 lexer::OpTy::AndAnd => OpTy::AndAnd(false),
263 lexer::OpTy::OrOr => OpTy::OrOr(false),
264 lexer::OpTy::XorXor => OpTy::XorXor(false),
265 lexer::OpTy::Gt => OpTy::Gt(false),
266 lexer::OpTy::Lt => OpTy::Lt(false),
267 lexer::OpTy::Ge => OpTy::Ge(false),
268 lexer::OpTy::Le => OpTy::Le(false),
269 lexer::OpTy::Not
270 | lexer::OpTy::Flip
271 | lexer::OpTy::AddAdd
272 | lexer::OpTy::SubSub => {
273 unreachable!("[Op::from_token] Given a `token` which should never be handled by this function.")
275 }
276 },
277 }
278 }
279
280 #[rustfmt::skip]
282 fn precedence(&self) -> usize {
283 match &self.ty {
284 OpTy::ObjAccess(_) => 33,
285 OpTy::AddPost | OpTy::SubPost => 31,
286 OpTy::AddPre(_)
287 | OpTy::SubPre(_)
288 | OpTy::Neg(_)
289 | OpTy::Flip(_)
290 | OpTy::Not(_) => 29,
291 OpTy::Mul(_) | OpTy::Div(_) | OpTy::Rem(_) => 27,
292 OpTy::Add(_) | OpTy::Sub(_) => 25,
293 OpTy::LShift(_) | OpTy::RShift(_) => 23,
294 OpTy::Lt(_) | OpTy::Gt(_) | OpTy::Le(_) | OpTy::Ge(_) => 21,
295 OpTy::EqEq(_) | OpTy::NotEq(_) => 19,
296 OpTy::And(_) => 17,
297 OpTy::Xor(_) => 15,
298 OpTy::Or(_) => 13,
299 OpTy::AndAnd(_) => 11,
300 OpTy::XorXor(_) => 9,
301 OpTy::OrOr(_) => 7,
302 OpTy::TernaryQ(_) => 5,
303 OpTy::TernaryC(_) => 3,
304 OpTy::Eq(_)
305 | OpTy::AddEq(_)
306 | OpTy::SubEq(_)
307 | OpTy::MulEq(_)
308 | OpTy::DivEq(_)
309 | OpTy::RemEq(_)
310 | OpTy::AndEq(_)
311 | OpTy::XorEq(_)
312 | OpTy::OrEq(_)
313 | OpTy::LShiftEq(_)
314 | OpTy::RShiftEq(_) => 1,
315 _ => unreachable!("The operator {self:?} does not have a precedence value because it should never be passed into this function. Something has gone wrong!"),
317 }
318 }
319
320 fn to_bin_op(self) -> BinOp {
321 let ty = match self.ty {
322 OpTy::Add(_) => BinOpTy::Add,
323 OpTy::Sub(_) => BinOpTy::Sub,
324 OpTy::Mul(_) => BinOpTy::Mul,
325 OpTy::Div(_) => BinOpTy::Div,
326 OpTy::Rem(_) => BinOpTy::Rem,
327 OpTy::And(_) => BinOpTy::And,
328 OpTy::Or(_) => BinOpTy::Or,
329 OpTy::Xor(_) => BinOpTy::Xor,
330 OpTy::LShift(_) => BinOpTy::LShift,
331 OpTy::RShift(_) => BinOpTy::RShift,
332 OpTy::Eq(_) => BinOpTy::Eq,
333 OpTy::AddEq(_) => BinOpTy::AddEq,
334 OpTy::SubEq(_) => BinOpTy::SubEq,
335 OpTy::MulEq(_) => BinOpTy::MulEq,
336 OpTy::DivEq(_) => BinOpTy::DivEq,
337 OpTy::RemEq(_) => BinOpTy::RemEq,
338 OpTy::AndEq(_) => BinOpTy::AndEq,
339 OpTy::OrEq(_) => BinOpTy::OrEq,
340 OpTy::XorEq(_) => BinOpTy::XorEq,
341 OpTy::LShiftEq(_) => BinOpTy::LShiftEq,
342 OpTy::RShiftEq(_) => BinOpTy::RShiftEq,
343 OpTy::EqEq(_) => BinOpTy::EqEq,
344 OpTy::NotEq(_) => BinOpTy::NotEq,
345 OpTy::AndAnd(_) => BinOpTy::AndAnd,
346 OpTy::OrOr(_) => BinOpTy::OrOr,
347 OpTy::XorXor(_) => BinOpTy::XorXor,
348 OpTy::Gt(_) => BinOpTy::Gt,
349 OpTy::Lt(_) => BinOpTy::Lt,
350 OpTy::Ge(_) => BinOpTy::Ge,
351 OpTy::Le(_) => BinOpTy::Le,
352 _ => unreachable!("[Op::to_bin_op] Given a `ty` which should not be handled here.")
353 };
354
355 BinOp {
356 span: self.span,
357 ty,
358 }
359 }
360}
361
362#[derive(Debug, PartialEq)]
364enum Group {
365 Paren(bool, Span),
370 FnCall(usize, Span),
375 Index(bool, Span),
380 Init(usize, Span),
385 ArrInit(usize, Span),
390 List(usize, usize),
400 Ternary,
402}
403
404struct ShuntingYard {
406 stack: VecDeque<Either<Node, Op>>,
408 operators: VecDeque<Op>,
410 groups: Vec<Group>,
412 start_position: usize,
414 mode: Mode,
416
417 syntax_diags: Vec<Syntax>,
419 semantic_diags: Vec<Semantic>,
421
422 syntax_tokens: Vec<SyntaxToken>,
424}
425
426impl ShuntingYard {
427 fn push_operator(&mut self, op: Op) {
430 if let OpTy::TernaryC(_) = op.ty {
431 match self.groups.pop() {
433 Some(group) => match group {
434 Group::Ternary => {}
435 _ => unreachable!("Should be in ternary group"),
436 },
437 None => unreachable!("Should be in ternary group"),
438 };
439 }
440
441 while self.operators.back().is_some() {
442 let back = self.operators.back().unwrap();
443
444 match back.ty {
445 OpTy::ParenStart
448 | OpTy::IndexStart
449 | OpTy::FnCallStart
450 | OpTy::InitStart
451 | OpTy::ArrInitStart => break,
452 _ => {}
453 }
454
455 match (&op.ty, &back.ty) {
456 (OpTy::ObjAccess(_), OpTy::ObjAccess(_)) => {
458 let moved = self.operators.pop_back().unwrap();
459 self.stack.push_back(Either::Right(moved));
460 break;
461 }
462 (OpTy::TernaryC(_), OpTy::TernaryQ(_)) => {
465 let moved = self.operators.pop_back().unwrap();
466 self.stack.push_back(Either::Right(moved));
467 break;
468 }
469 (OpTy::TernaryC(_), OpTy::TernaryC(_)) => {
470 let moved = self.operators.pop_back().unwrap();
471 self.stack.push_back(Either::Right(moved));
472 continue;
473 }
474 (_, _) => {}
475 }
476
477 if op.precedence() < back.precedence() {
481 let moved = self.operators.pop_back().unwrap();
482 self.stack.push_back(Either::Right(moved));
483 } else {
484 break;
487 }
488 }
489 self.operators.push_back(op);
490 }
491
492 fn collapse_paren(&mut self, group: Group, end_span: Span) {
498 if let Group::Paren(has_inner, l_paren) = group {
499 while self.operators.back().is_some() {
500 let op = self.operators.pop_back().unwrap();
501
502 #[cfg(debug_assertions)]
503 {
504 match op.ty {
505 OpTy::FnCallStart => unreachable!("Mismatch between operator stack (Op::FnCallStart) and group stack (Group::Paren)!"),
506 OpTy::IndexStart => unreachable!("Mismatch between operator stack (Op::IndexStart) and group stack (Group::Paren)!"),
507 OpTy::InitStart => unreachable!("Mismatch between operator stack (Op::InitStart) and group stack (Group::Paren)!"),
508 OpTy::ArrInitStart => unreachable!("Mismatch between operator stack (Op::ArrInitStart) and group stack (Group::Paren)!"),
509 _ => {}
510 }
511 }
512
513 if let OpTy::ParenStart = op.ty {
514 self.stack.push_back(Either::Right(Op {
515 span: Span::new(l_paren.start, end_span.end),
516 ty: OpTy::Paren(has_inner, l_paren, end_span),
517 }));
518 break;
519 } else {
520 self.stack.push_back(Either::Right(op));
523 }
524 }
525 } else {
526 unreachable!()
527 }
528 }
529
530 fn collapse_fn(&mut self, group: Group, end_span: Span) {
536 if let Group::FnCall(count, l_paren) = group {
537 while self.operators.back().is_some() {
538 let op = self.operators.pop_back().unwrap();
539
540 #[cfg(debug_assertions)]
541 {
542 match op.ty {
543 OpTy::ParenStart => unreachable!("Mismatch between operator stack (Op::ParenStart) and group stack (Group::Fn)!"),
544 OpTy::IndexStart => unreachable!("Mismatch between operator stack (Op::IndexStart) and group stack (Group::Fn)!"),
545 OpTy::InitStart => unreachable!("Mismatch between operator stack (Op::InitStart) and group stack (Group::Fn)!"),
546 OpTy::ArrInitStart => unreachable!("Mismatch between operator stack (Op::ArrInitStart) and group stack (Group::Fn)!"),
547 _ => {}
548 }
549 }
550
551 if let OpTy::FnCallStart = op.ty {
552 self.stack.push_back(Either::Right(Op {
555 span: Span::new(l_paren.start, end_span.end),
556 ty: OpTy::FnCall(count + 1, l_paren, end_span),
557 }));
558 break;
559 } else {
560 self.stack.push_back(Either::Right(op));
563 }
564 }
565 } else {
566 unreachable!()
567 }
568 }
569
570 fn collapse_index(&mut self, group: Group, end_span: Span) {
576 if let Group::Index(contains_i, l_bracket) = group {
577 while self.operators.back().is_some() {
578 let op = self.operators.pop_back().unwrap();
579
580 #[cfg(debug_assertions)]
581 {
582 match op .ty{
583 OpTy::ParenStart => unreachable!("Mismatch between operator stack (Op::ParenStart) and group stack (Group::Index)!"),
584 OpTy::FnCallStart => unreachable!("Mismatch between operator stack (Op::FnCallStart) and group stack (Group::Index)!"),
585 OpTy::InitStart=> unreachable!("Mismatch between operator stack (Op::InitStart) and group stack (Group::Index)!"),
586 OpTy::ArrInitStart => unreachable!("Mismatch between operator stack (Op::ArrInitStart) and group stack (Group::Index)!"),
587 _ => {}
588 }
589 }
590
591 if let OpTy::IndexStart = op.ty {
592 self.stack.push_back(Either::Right(Op {
593 span: Span::new(l_bracket.start, end_span.end),
594 ty: OpTy::Index(contains_i, l_bracket, end_span),
595 }));
596 break;
597 } else {
598 self.stack.push_back(Either::Right(op));
601 }
602 }
603 } else {
604 unreachable!()
605 }
606 }
607
608 fn collapse_init(&mut self, group: Group, end_span: Span) {
614 if let Group::Init(count, l_brace) = group {
615 while self.operators.back().is_some() {
616 let op = self.operators.pop_back().unwrap();
617
618 #[cfg(debug_assertions)]
619 {
620 match op.ty {
621 OpTy::ParenStart => unreachable!("Mismatch between operator stack (Op::ParenStart) and group stack (Group::Init)!"),
622 OpTy::IndexStart => unreachable!("Mismatch between operator stack (Op::IndexStart) and group stack (Group::Init)!"),
623 OpTy::FnCallStart => unreachable!("Mismatch between operator stack (Op::FnCallStart) and group stack (Group::Init)!"),
624 OpTy::ArrInitStart => unreachable!("Mismatch between operator stack (Op::ArrInitStart) and group stack (Group::Init)!"),
625 _ => {}
626 }
627 }
628
629 if let OpTy::InitStart = op.ty {
630 self.stack.push_back(Either::Right(Op {
631 span: Span::new(l_brace.start, end_span.end),
632 ty: OpTy::Init(count, l_brace, end_span),
633 }));
634 break;
635 } else {
636 self.stack.push_back(Either::Right(op));
639 }
640 }
641 } else {
642 unreachable!()
643 }
644 }
645
646 fn collapse_arr_init(&mut self, group: Group, end_span: Span) {
652 if let Group::ArrInit(count, l_paren) = group {
653 while self.operators.back().is_some() {
654 let op = self.operators.pop_back().unwrap();
655
656 #[cfg(debug_assertions)]
657 {
658 match op.ty {
659 OpTy::ParenStart => unreachable!("Mismatch between operator stack (Op::ParenStart) and group stack (Group::ArrInit)!"),
660 OpTy::IndexStart => unreachable!("Mismatch between operator stack (Op::IndexStart) and group stack (Group::ArrInit)!"),
661 OpTy::FnCallStart => unreachable!("Mismatch between operator stack (Op::FnCallStart) and group stack (Group::ArrInit)!"),
662 OpTy::InitStart => unreachable!("Mismatch between operator stack (Op::InitStart) and group stack (Group::ArrInit)!"),
663 _ => {}
664 }
665 }
666
667 if let OpTy::ArrInitStart = op.ty {
668 self.stack.push_back(Either::Right(Op {
671 span: Span::new(l_paren.start, end_span.end),
672 ty: OpTy::ArrInit(count + 1, l_paren, end_span),
673 }));
674 break;
675 } else {
676 self.stack.push_back(Either::Right(op));
679 }
680 }
681 } else {
682 unreachable!()
683 }
684 }
685
686 fn collapse_list(&mut self, group: Group, span_end: usize) {
691 if let Group::List(count, start_pos) = group {
692 while self.operators.back().is_some() {
693 let op = self.operators.back().unwrap();
694
695 #[cfg(debug_assertions)]
696 {
697 match op.ty {
698 OpTy::FnCallStart => unreachable!("Mismatch between operator stack (Op::FnCallStart) and group stack (Group::List)!"),
699 OpTy::InitStart => unreachable!("Mismatch between operator stack (Op::InitStart) and group stack (Group::List)!"),
700 OpTy::ArrInitStart => unreachable!("Mismatch between operator stack (Op::ArrInitStart) and group stack (Group::List)!"),
701 _ => {}
702 }
703 }
704
705 match op.ty {
710 OpTy::ParenStart | OpTy::IndexStart => break,
711 _ => {
712 let moved = self.operators.pop_back().unwrap();
715 self.stack.push_back(Either::Right(moved));
716 }
717 }
718 }
719 self.stack.push_back(Either::Right(Op {
720 span: Span::new(start_pos, span_end),
721 ty: OpTy::List(count),
722 }));
723 } else {
724 unreachable!()
725 }
726 }
727
728 fn end_paren_fn(&mut self, end_span: Span) -> Result<(), ()> {
731 let current_group = match self.groups.last() {
732 Some(t) => t,
733 None => {
734 return Err(());
737 }
738 };
739
740 match current_group {
741 Group::Paren(_, _) => {}
742 Group::FnCall(_, _) | Group::ArrInit(_, _) => {}
743 _ => {
744 if self.exists_paren_fn_group() {
748 'inner: while let Some(current_group) = self.groups.last() {
751 match current_group {
752 Group::Init(_, _) => {
753 let current_group = self.groups.pop().unwrap();
754 self.collapse_init(
755 current_group,
756 Span::new(
757 end_span.end_at_previous().end,
758 end_span.end_at_previous().end,
759 ),
760 );
761 }
762 Group::Index(_, _) => {
763 let current_group = self.groups.pop().unwrap();
764 self.collapse_index(
765 current_group,
766 end_span.start_zero_width(),
767 )
768 }
769 Group::List(_, _) => {
770 let current_group = self.groups.pop().unwrap();
771
772 self.collapse_list(
773 current_group,
774 end_span.end_at_previous().end,
775 );
776 }
777 Group::Ternary => {
778 'tern: while let Some(op) =
779 self.operators.back()
780 {
781 if let OpTy::TernaryQ(_) = op.ty {
782 let moved =
783 self.operators.pop_back().unwrap();
784 self.stack
785 .push_back(Either::Right(moved));
786 break 'tern;
787 } else {
788 let moved =
789 self.operators.pop_back().unwrap();
790 self.stack
791 .push_back(Either::Right(moved));
792 }
793 }
794
795 self.groups.pop();
796 }
797 Group::Paren(_, _)
798 | Group::FnCall(_, _)
799 | Group::ArrInit(_, _) => break 'inner,
800 }
801 }
802 } else {
803 return Err(());
806 }
807 }
808 }
809
810 let group = self.groups.pop().unwrap();
811 match group {
812 Group::Paren(_, _) => self.collapse_paren(group, end_span),
813 Group::FnCall(_, _) => self.collapse_fn(group, end_span),
814 Group::ArrInit(_, _) => self.collapse_arr_init(group, end_span),
815 _ => unreachable!(),
818 }
819 Ok(())
820 }
821
822 fn end_index(&mut self, end_span: Span) -> Result<(), ()> {
827 let current_group = match self.groups.last() {
828 Some(t) => t,
829 None => {
830 return Err(());
833 }
834 };
835
836 if std::mem::discriminant(current_group)
837 != std::mem::discriminant(&Group::Index(
838 false,
839 Span::new_zero_width(0),
840 )) {
841 if self.exists_index_group() {
844 'inner: while let Some(current_group) = self.groups.last() {
846 match current_group {
847 Group::Paren(_, _) => {
848 let current_group = self.groups.pop().unwrap();
849 self.collapse_paren(
850 current_group,
851 Span::new(
852 end_span.end_at_previous().end,
853 end_span.end_at_previous().end,
854 ),
855 );
856 }
857 Group::FnCall(_, _) => {
858 let current_group = self.groups.pop().unwrap();
859 self.collapse_fn(
860 current_group,
861 Span::new(
862 end_span.end_at_previous().end,
863 end_span.end_at_previous().end,
864 ),
865 );
866 }
867 Group::Init(_, _) => {
868 let current_group = self.groups.pop().unwrap();
869 self.collapse_init(
870 current_group,
871 Span::new(
872 end_span.end_at_previous().end,
873 end_span.end_at_previous().end,
874 ),
875 );
876 }
877 Group::ArrInit(_, _) => {
878 let current_group = self.groups.pop().unwrap();
879 self.collapse_arr_init(
880 current_group,
881 Span::new(
882 end_span.end_at_previous().end,
883 end_span.end_at_previous().end,
884 ),
885 );
886 }
887 Group::Ternary => {
888 'tern: while let Some(op) = self.operators.back() {
889 if let OpTy::TernaryQ(_) = op.ty {
890 let moved =
891 self.operators.pop_back().unwrap();
892 self.stack.push_back(Either::Right(moved));
893 break 'tern;
894 } else {
895 let moved =
896 self.operators.pop_back().unwrap();
897 self.stack.push_back(Either::Right(moved));
898 }
899 }
900
901 self.groups.pop();
902 }
903 Group::List(_, _) => {
904 let current_group = self.groups.pop().unwrap();
905 self.collapse_list(
906 current_group,
907 end_span.end_at_previous().end,
908 )
909 }
910 Group::Index(_, _) => break 'inner,
911 }
912 }
913 } else {
914 return Err(());
917 }
918 }
919
920 let group = self.groups.pop().unwrap();
921 self.collapse_index(group, end_span);
922 Ok(())
923 }
924
925 fn end_init(&mut self, end_span: Span) -> Result<(), ()> {
928 let current_group = match self.groups.last() {
929 Some(t) => t,
930 None => {
931 return Err(());
934 }
935 };
936
937 if std::mem::discriminant(current_group)
938 != std::mem::discriminant(&Group::Init(0, Span::new_zero_width(0)))
939 {
940 if self.exists_init_group() {
943 'inner: while let Some(current_group) = self.groups.last() {
945 match current_group {
946 Group::Paren(_, _) => {
947 let current_group = self.groups.pop().unwrap();
948 self.collapse_paren(
949 current_group,
950 Span::new(
951 end_span.end_at_previous().end,
952 end_span.end_at_previous().end,
953 ),
954 );
955 }
956 Group::Index(_, _) => {
957 let current_group = self.groups.pop().unwrap();
958 self.collapse_index(
959 current_group,
960 end_span.start_zero_width(),
961 );
962 }
963 Group::FnCall(_, _) => {
964 let current_group = self.groups.pop().unwrap();
965 self.collapse_fn(
966 current_group,
967 Span::new(
968 end_span.end_at_previous().end,
969 end_span.end_at_previous().end,
970 ),
971 );
972 }
973 Group::ArrInit(_, _) => {
974 let current_group = self.groups.pop().unwrap();
975 self.collapse_arr_init(
976 current_group,
977 Span::new(
978 end_span.end_at_previous().end,
979 end_span.end_at_previous().end,
980 ),
981 );
982 }
983 Group::Ternary => {
984 'tern: while let Some(op) = self.operators.back() {
985 if let OpTy::TernaryQ(_) = op.ty {
986 let moved =
987 self.operators.pop_back().unwrap();
988 self.stack.push_back(Either::Right(moved));
989 break 'tern;
990 } else {
991 let moved =
992 self.operators.pop_back().unwrap();
993 self.stack.push_back(Either::Right(moved));
994 }
995 }
996
997 self.groups.pop();
998 }
999 Group::List(_, _) => unreachable!(),
1001 Group::Init(_, _) => break 'inner,
1002 }
1003 }
1004 } else {
1005 return Err(());
1008 }
1009 }
1010
1011 let group = self.groups.pop().unwrap();
1012 self.collapse_init(group, end_span);
1013 Ok(())
1014 }
1015
1016 fn register_arity_argument(&mut self, end_span: Span) {
1019 while let Some(group) = self.groups.last_mut() {
1020 match group {
1021 Group::FnCall(count, _)
1022 | Group::Init(count, _)
1023 | Group::ArrInit(count, _) => {
1024 while self.operators.back().is_some() {
1027 let back = self.operators.back().unwrap();
1028 match back.ty {
1029 OpTy::FnCallStart
1030 | OpTy::InitStart
1031 | OpTy::ArrInitStart => break,
1032 _ => {}
1033 }
1034
1035 let moved = self.operators.pop_back().unwrap();
1036 self.stack.push_back(Either::Right(moved));
1037 }
1038
1039 *count += 1;
1040 return;
1041 }
1042 Group::List(count, _) => {
1043 while self.operators.back().is_some() {
1044 let moved = self.operators.pop_back().unwrap();
1045 self.stack.push_back(Either::Right(moved));
1046 }
1047
1048 *count += 1;
1049 return;
1050 }
1051 Group::Paren(_, _) => {
1057 let group = self.groups.pop().unwrap();
1058 self.collapse_paren(group, end_span);
1059 }
1060 Group::Index(_, _) => {
1061 let group = self.groups.pop().unwrap();
1062 self.collapse_index(group, end_span);
1063 }
1064 Group::Ternary => {
1065 'tern: while let Some(op) = self.operators.back() {
1066 if let OpTy::TernaryQ(_) = op.ty {
1067 let moved = self.operators.pop_back().unwrap();
1068 self.stack.push_back(Either::Right(moved));
1069 break 'tern;
1070 } else {
1071 let moved = self.operators.pop_back().unwrap();
1072 self.stack.push_back(Either::Right(moved));
1073 }
1074 }
1075
1076 self.groups.pop();
1077 }
1078 }
1079 }
1080
1081 while self.operators.back().is_some() {
1085 let moved = self.operators.pop_back().unwrap();
1086 self.stack.push_back(Either::Right(moved));
1087 }
1088 self.groups.push(Group::List(
1089 if self.stack.is_empty() && self.operators.is_empty() {
1090 0
1091 } else {
1092 1
1093 },
1094 self.start_position,
1095 ))
1096 }
1097
1098 fn set_op_rhs_toggle(&mut self) {
1100 if let Some(op) = self.operators.back_mut() {
1101 match &mut op.ty {
1102 OpTy::Add(b)
1103 | OpTy::Sub(b)
1104 | OpTy::Mul(b)
1105 | OpTy::Div(b)
1106 | OpTy::Rem(b)
1107 | OpTy::And(b)
1108 | OpTy::Or(b)
1109 | OpTy::Xor(b)
1110 | OpTy::LShift(b)
1111 | OpTy::RShift(b)
1112 | OpTy::Eq(b)
1113 | OpTy::AddEq(b)
1114 | OpTy::SubEq(b)
1115 | OpTy::MulEq(b)
1116 | OpTy::DivEq(b)
1117 | OpTy::RemEq(b)
1118 | OpTy::AndEq(b)
1119 | OpTy::OrEq(b)
1120 | OpTy::XorEq(b)
1121 | OpTy::LShiftEq(b)
1122 | OpTy::RShiftEq(b)
1123 | OpTy::EqEq(b)
1124 | OpTy::NotEq(b)
1125 | OpTy::AndAnd(b)
1126 | OpTy::OrOr(b)
1127 | OpTy::XorXor(b)
1128 | OpTy::Gt(b)
1129 | OpTy::Lt(b)
1130 | OpTy::Ge(b)
1131 | OpTy::Le(b)
1132 | OpTy::AddPre(b)
1133 | OpTy::SubPre(b)
1134 | OpTy::Neg(b)
1135 | OpTy::Flip(b)
1136 | OpTy::Not(b)
1137 | OpTy::TernaryQ(b)
1138 | OpTy::TernaryC(b)
1139 | OpTy::ObjAccess(b) => *b = true,
1140 _ => {}
1141 }
1142 }
1143 if let Some(group) = self.groups.last_mut() {
1144 match group {
1145 Group::Paren(b, _) | Group::Index(b, _) => *b = true,
1146 _ => {}
1147 }
1148 }
1149 }
1150
1151 fn just_started_paren(&self) -> bool {
1153 if let Some(current_group) = self.groups.last() {
1154 match current_group {
1155 Group::Paren(has_inner, _) => *has_inner == false,
1156 _ => false,
1157 }
1158 } else {
1159 false
1160 }
1161 }
1162
1163 fn just_started_fn_arr_init(&self) -> bool {
1165 let stack_span = self.stack.back().map(|i| match i {
1166 Either::Left(e) => e.span,
1167 Either::Right(op) => op.span,
1168 });
1169 let op_span = match self.operators.back() {
1170 Some(op) => match op.ty {
1171 OpTy::FnCallStart | OpTy::ArrInitStart => op.span,
1172 _ => return false,
1173 },
1174 None => return false,
1175 };
1176
1177 match (stack_span, op_span) {
1178 (Some(stack), op_span) => op_span.is_after(&stack),
1179 (None, _op_span) => true,
1180 }
1181 }
1182
1183 fn just_started_init(&self) -> bool {
1185 if let Some(current_group) = self.groups.last() {
1186 match current_group {
1187 Group::Init(count, _) => *count == 0,
1188 _ => false,
1189 }
1190 } else {
1191 false
1192 }
1193 }
1194
1195 fn is_in_ternary(&self) -> bool {
1197 if let Some(current_group) = self.groups.last() {
1198 match current_group {
1199 Group::Ternary => true,
1200 _ => false,
1201 }
1202 } else {
1203 false
1204 }
1205 }
1206
1207 fn is_in_variable_arg_group(&self) -> bool {
1210 if let Some(current_group) = self.groups.last() {
1211 match current_group {
1212 Group::FnCall(_, _)
1213 | Group::Init(_, _)
1214 | Group::ArrInit(_, _)
1215 | Group::List(_, _) => true,
1216 Group::Ternary => {
1217 for group in self.groups.iter().rev() {
1218 match group {
1219 Group::FnCall(_, _)
1220 | Group::Init(_, _)
1221 | Group::ArrInit(_, _)
1222 | Group::List(_, _) => return true,
1223 _ => {}
1224 }
1225 }
1226 false
1227 }
1228 _ => false,
1229 }
1230 } else {
1231 false
1232 }
1233 }
1234
1235 fn exists_paren_fn_group(&self) -> bool {
1237 for group in self.groups.iter() {
1238 match group {
1239 Group::Paren(_, _)
1240 | Group::FnCall(_, _)
1241 | Group::ArrInit(_, _) => return true,
1242 _ => {}
1243 }
1244 }
1245 false
1246 }
1247
1248 fn exists_index_group(&self) -> bool {
1250 for group in self.groups.iter() {
1251 if let Group::Index(_, _) = group {
1252 return true;
1253 }
1254 }
1255 false
1256 }
1257
1258 fn exists_init_group(&self) -> bool {
1260 for group in self.groups.iter() {
1261 if let Group::Init(_, _) = group {
1262 return true;
1263 }
1264 }
1265 false
1266 }
1267
1268 fn get_previous_span(&self) -> Option<Span> {
1270 let stack_span = self.stack.back().map(|i| match i {
1271 Either::Left(e) => e.span,
1272 Either::Right(op) => op.span,
1273 });
1274 let op_span = self.operators.back().map(|op| op.span);
1275
1276 match (stack_span, op_span) {
1277 (Some(stack), Some(op)) => {
1278 if stack.is_after(&op) {
1279 stack_span
1280 } else {
1281 op_span
1282 }
1283 }
1284 (Some(_), None) => stack_span,
1285 (None, Some(_)) => op_span,
1286 (None, None) => None,
1287 }
1288 }
1289
1290 fn colour<'a, P: super::TokenStreamProvider<'a>>(
1292 &mut self,
1293 walker: &Walker<'a, P>,
1294 span: Span,
1295 token: SyntaxType,
1296 ) {
1297 if walker.streams.len() == 1 {
1299 self.syntax_tokens.push(SyntaxToken {
1300 ty: token,
1301 modifiers: SyntaxModifiers::empty(),
1302 span,
1303 });
1304 }
1305 }
1306
1307 fn parse<'a, P: super::TokenStreamProvider<'a>>(
1309 &mut self,
1310 walker: &mut Walker<'a, P>,
1311 end_tokens: &[Token],
1312 ) {
1313 #[derive(PartialEq)]
1314 enum State {
1315 Operand,
1318 AfterOperand,
1322 }
1323 let mut state = State::Operand;
1324
1325 #[derive(PartialEq)]
1326 enum Start {
1327 None,
1329 FnOrArr,
1333 ArrInit,
1335 EmptyIndex,
1337 }
1338 let mut can_start = Start::None;
1339
1340 #[derive(PartialEq)]
1341 enum Arity {
1342 None,
1344 PotentialEnd,
1355 Operator,
1364 }
1365 let mut arity_state = Arity::None;
1367
1368 let mut just_started_arity_group = true;
1372
1373 'main: while !walker.is_done() {
1374 let (token, span) = match walker.peek() {
1375 Some(t) => t,
1376 None => break 'main,
1378 };
1379
1380 if end_tokens.contains(token) {
1382 if *token == Token::RParen && self.exists_paren_fn_group() {
1391 } else if *token == Token::RBracket && self.exists_index_group()
1392 {
1393 } else if *token == Token::RBrace && self.exists_init_group() {
1394 } else {
1395 break 'main;
1397 }
1398 }
1399
1400 match token {
1401 Token::Num { .. } | Token::Bool(_)
1402 if state == State::Operand =>
1403 {
1404 if self.is_in_variable_arg_group()
1410 && arity_state == Arity::PotentialEnd
1411 {
1412 self.register_arity_argument(span.start_zero_width());
1413 }
1414 arity_state = Arity::PotentialEnd;
1415
1416 match Lit::parse(token, span) {
1417 Ok(l) => self.stack.push_back(Either::Left(Node {
1418 ty: NodeTy::Lit(l),
1419 span,
1420 })),
1421 Err((l, d)) => {
1422 self.stack.push_back(Either::Left(Node {
1423 ty: NodeTy::Lit(l),
1424 span,
1425 }));
1426 self.syntax_diags.push(d);
1427 }
1428 }
1429
1430 state = State::AfterOperand;
1433
1434 can_start = Start::None;
1435
1436 self.set_op_rhs_toggle();
1437
1438 self.colour(
1439 walker,
1440 span,
1441 match token {
1442 Token::Num { .. } => SyntaxType::Number,
1443 Token::Bool(_) => SyntaxType::Boolean,
1444 _ => unreachable!(),
1445 },
1446 );
1447 }
1448 Token::Num { .. } | Token::Bool(_)
1449 if state == State::AfterOperand =>
1450 {
1451 if self.mode == Mode::TakeOneUnit {
1452 break 'main;
1453 }
1454
1455 if self.is_in_variable_arg_group()
1461 && arity_state == Arity::PotentialEnd
1462 {
1463 self.register_arity_argument(span.start_zero_width());
1464 } else {
1465 self.syntax_diags.push(Syntax::Expr(
1468 ExprDiag::FoundOperandAfterOperand(
1469 self.get_previous_span().unwrap(),
1470 span,
1471 ),
1472 ));
1473 break 'main;
1474 }
1475 arity_state = Arity::PotentialEnd;
1476
1477 match Lit::parse(token, span) {
1478 Ok(l) => self.stack.push_back(Either::Left(Node {
1479 ty: NodeTy::Lit(l),
1480 span,
1481 })),
1482 Err((l, d)) => {
1483 self.stack.push_back(Either::Left(Node {
1484 ty: NodeTy::Lit(l),
1485 span,
1486 }));
1487 self.syntax_diags.push(d);
1488 }
1489 }
1490
1491 can_start = Start::None;
1492
1493 self.colour(
1494 walker,
1495 span,
1496 match token {
1497 Token::Num { .. } => SyntaxType::Number,
1498 Token::Bool(_) => SyntaxType::Boolean,
1499 _ => unreachable!(),
1500 },
1501 );
1502
1503 }
1506 Token::Ident(s) if state == State::Operand => {
1507 if self.is_in_variable_arg_group()
1513 && arity_state == Arity::PotentialEnd
1514 {
1515 self.register_arity_argument(span.start_zero_width());
1516 }
1517 arity_state = Arity::PotentialEnd;
1518
1519 self.stack.push_back(Either::Left(Node {
1520 ty: NodeTy::Ident(Ident {
1521 name: s.clone(),
1522 span,
1523 }),
1524 span,
1525 }));
1526
1527 state = State::AfterOperand;
1530
1531 can_start = Start::FnOrArr;
1533
1534 self.set_op_rhs_toggle();
1535
1536 self.colour(walker, span, SyntaxType::UncheckedIdent);
1537 }
1538 Token::Ident(s) if state == State::AfterOperand => {
1539 if self.mode == Mode::TakeOneUnit {
1540 break 'main;
1541 }
1542
1543 if self.is_in_variable_arg_group()
1549 && arity_state == Arity::PotentialEnd
1550 {
1551 self.register_arity_argument(span.start_zero_width());
1552 } else {
1553 self.syntax_diags.push(Syntax::Expr(
1556 ExprDiag::FoundOperandAfterOperand(
1557 self.get_previous_span().unwrap(),
1558 span,
1559 ),
1560 ));
1561 break 'main;
1562 }
1563 arity_state = Arity::PotentialEnd;
1564
1565 self.stack.push_back(Either::Left(Node {
1566 ty: NodeTy::Ident(Ident {
1567 name: s.clone(),
1568 span,
1569 }),
1570 span,
1571 }));
1572
1573 can_start = Start::FnOrArr;
1575
1576 self.colour(walker, span, SyntaxType::UncheckedIdent);
1577
1578 }
1581 Token::Op(op) if state == State::Operand => {
1582 if (self.mode == Mode::BreakAtEq
1583 || self.mode == Mode::TakeOneUnit)
1584 && *op == lexer::OpTy::Eq
1585 {
1586 break 'main;
1587 }
1588
1589 match op {
1590 lexer::OpTy::Sub
1591 | lexer::OpTy::Not
1592 | lexer::OpTy::Flip
1593 | lexer::OpTy::AddAdd
1594 | lexer::OpTy::SubSub => {
1595 if self.is_in_variable_arg_group()
1601 && arity_state == Arity::PotentialEnd
1602 {
1603 self.register_arity_argument(
1604 span.start_zero_width(),
1605 );
1606 arity_state = Arity::Operator;
1607 }
1608
1609 self.set_op_rhs_toggle();
1610 }
1611 _ => {
1612 self.syntax_diags.push(Syntax::Expr(
1613 ExprDiag::InvalidPrefixOperator(span),
1614 ));
1615 break 'main;
1616 }
1617 }
1618
1619 match op {
1620 lexer::OpTy::Sub => self.push_operator(Op {
1623 span,
1624 ty: OpTy::Neg(false),
1625 }),
1626 lexer::OpTy::Not => self.push_operator(Op {
1627 span,
1628 ty: OpTy::Not(false),
1629 }),
1630 lexer::OpTy::Flip => self.push_operator(Op {
1631 span,
1632 ty: OpTy::Flip(false),
1633 }),
1634 lexer::OpTy::AddAdd => self.push_operator(Op {
1635 span,
1636 ty: OpTy::AddPre(false),
1637 }),
1638 lexer::OpTy::SubSub => self.push_operator(Op {
1639 span,
1640 ty: OpTy::SubPre(false),
1641 }),
1642 _ => {
1643 unreachable!()
1644 }
1645 }
1646
1647 can_start = Start::None;
1648
1649 self.colour(walker, span, SyntaxType::Operator);
1650 }
1651 Token::Op(op) if state == State::AfterOperand => {
1652 if (self.mode == Mode::BreakAtEq
1653 || self.mode == Mode::TakeOneUnit)
1654 && *op == lexer::OpTy::Eq
1655 {
1656 break 'main;
1657 }
1658
1659 match op {
1660 lexer::OpTy::Flip | lexer::OpTy::Not => {
1661 self.syntax_diags.push(Syntax::Expr(
1662 ExprDiag::InvalidBinOrPostOperator(span),
1663 ));
1664 break 'main;
1665 }
1666 lexer::OpTy::AddAdd => {
1670 self.push_operator(Op {
1671 span,
1672 ty: OpTy::AddPost,
1673 });
1674 }
1675 lexer::OpTy::SubSub => {
1676 self.push_operator(Op {
1677 span,
1678 ty: OpTy::SubPost,
1679 });
1680 }
1681 _ => {
1684 self.push_operator(Op::from_token(*op, span));
1685 state = State::Operand;
1686 }
1687 }
1688
1689 arity_state = Arity::Operator;
1690
1691 can_start = Start::None;
1692
1693 self.colour(walker, span, SyntaxType::Operator);
1694 }
1695 Token::LParen if state == State::Operand => {
1696 if self.is_in_variable_arg_group()
1702 && arity_state == Arity::PotentialEnd
1703 {
1704 self.register_arity_argument(span.start_zero_width());
1705 }
1706 arity_state = Arity::Operator;
1707
1708 self.set_op_rhs_toggle();
1709
1710 self.operators.push_back(Op {
1711 span,
1712 ty: OpTy::ParenStart,
1713 });
1714 self.groups.push(Group::Paren(false, span));
1715
1716 can_start = Start::None;
1717
1718 self.colour(walker, span, SyntaxType::Punctuation);
1719
1720 }
1723 Token::LParen if state == State::AfterOperand => {
1724 if can_start == Start::FnOrArr {
1725 self.operators.push_back(Op {
1727 span,
1728 ty: OpTy::FnCallStart,
1729 });
1730 self.groups.push(Group::FnCall(0, span));
1731
1732 state = State::Operand;
1735
1736 can_start = Start::None;
1739
1740 just_started_arity_group = true;
1741 } else if can_start == Start::ArrInit {
1742 self.operators.push_back(Op {
1744 span,
1745 ty: OpTy::ArrInitStart,
1746 });
1747 self.groups.push(Group::ArrInit(0, span));
1748
1749 state = State::Operand;
1752
1753 can_start = Start::None;
1755
1756 just_started_arity_group = true;
1757 } else {
1758 if self.is_in_variable_arg_group()
1760 && arity_state == Arity::PotentialEnd
1761 {
1762 self.register_arity_argument(
1763 span.start_zero_width(),
1764 );
1765 } else {
1766 if self.mode != Mode::TakeOneUnit {
1770 self.syntax_diags.push(Syntax::Expr(
1771 ExprDiag::FoundOperandAfterOperand(
1772 self.get_previous_span().unwrap(),
1773 span,
1774 ),
1775 ));
1776 }
1777 break 'main;
1778 }
1779
1780 self.set_op_rhs_toggle();
1781
1782 self.operators.push_back(Op {
1783 span,
1784 ty: OpTy::ParenStart,
1785 });
1786 self.groups.push(Group::Paren(false, span));
1787
1788 state = State::Operand;
1789
1790 can_start = Start::None;
1791 }
1792 arity_state = Arity::Operator;
1793
1794 self.colour(walker, span, SyntaxType::Punctuation);
1795 }
1796 Token::RParen if state == State::AfterOperand => {
1797 if !self.just_started_fn_arr_init()
1798 && self.is_in_variable_arg_group()
1799 {
1800 self.register_arity_argument(span.start_zero_width());
1801 }
1802 arity_state = Arity::PotentialEnd;
1803
1804 match self.end_paren_fn(span) {
1805 Ok(_) => {}
1806 Err(_) => {
1807 break 'main;
1808 }
1809 }
1810
1811 can_start = Start::None;
1812
1813 self.colour(walker, span, SyntaxType::Punctuation);
1814
1815 }
1818 Token::RParen if state == State::Operand => {
1819 if self.is_in_variable_arg_group()
1820 && !just_started_arity_group
1821 {
1822 self.register_arity_argument(span.start_zero_width());
1823 }
1824 arity_state = Arity::PotentialEnd;
1825
1826 let prev_op_span = self.get_previous_span();
1827 let just_started_paren = self.just_started_paren();
1828 let just_started_fn_arr_init =
1829 self.just_started_fn_arr_init();
1830
1831 match self.end_paren_fn(span) {
1832 Ok(_) => {}
1833 Err(_) => {
1834 break 'main;
1835 }
1836 }
1837
1838 if just_started_paren {
1839 self.syntax_diags.push(Syntax::Expr(
1840 ExprDiag::FoundEmptyParens(Span::new(
1841 prev_op_span.unwrap().start,
1842 span.end,
1843 )),
1844 ));
1845 } else if just_started_fn_arr_init {
1846 } else {
1847 self.syntax_diags.push(Syntax::Expr(
1848 ExprDiag::FoundRParenInsteadOfOperand(
1849 prev_op_span.unwrap(),
1850 span,
1851 ),
1852 ))
1853 }
1854
1855 state = State::AfterOperand;
1856
1857 can_start = Start::None;
1858
1859 self.colour(walker, span, SyntaxType::Punctuation);
1860 }
1861 Token::LBracket if state == State::AfterOperand => {
1862 self.operators.push_back(Op {
1865 span,
1866 ty: OpTy::IndexStart,
1867 });
1868 self.groups.push(Group::Index(false, span));
1869
1870 state = State::Operand;
1871
1872 arity_state = Arity::Operator;
1873
1874 can_start = Start::EmptyIndex;
1875
1876 self.colour(walker, span, SyntaxType::Punctuation);
1877 }
1878 Token::LBracket if state == State::Operand => {
1879 if self.mode != Mode::TakeOneUnit {
1880 self.syntax_diags.push(Syntax::Expr(
1881 ExprDiag::FoundLBracketInsteadOfOperand(
1882 self.get_previous_span(),
1883 span,
1884 ),
1885 ));
1886 }
1887 break 'main;
1888 }
1889 Token::RBracket if state == State::AfterOperand => {
1890 match self.end_index(span) {
1893 Ok(_) => {}
1894 Err(_) => {
1895 break 'main;
1896 }
1897 }
1898
1899 can_start = Start::ArrInit;
1901
1902 arity_state = Arity::PotentialEnd;
1903
1904 self.colour(walker, span, SyntaxType::Punctuation);
1905 }
1906 Token::RBracket if state == State::Operand => {
1907 if can_start == Start::EmptyIndex {
1908 match self.end_index(span) {
1909 Ok(_) => {}
1910 Err(_) => {
1911 break 'main;
1912 }
1913 }
1914 } else {
1915 let prev_op_span = self.get_previous_span();
1916
1917 match self.end_index(span) {
1918 Ok(_) => {}
1919 Err(_) => {
1920 break 'main;
1921 }
1922 }
1923
1924 self.syntax_diags.push(Syntax::Expr(
1925 ExprDiag::FoundRBracketInsteadOfOperand(
1926 prev_op_span.unwrap(),
1927 span,
1928 ),
1929 ));
1930 }
1931 state = State::AfterOperand;
1934
1935 arity_state = Arity::PotentialEnd;
1936
1937 self.colour(walker, span, SyntaxType::Punctuation);
1938 }
1939 Token::LBrace if state == State::Operand => {
1940 if self.is_in_variable_arg_group()
1946 && arity_state == Arity::PotentialEnd
1947 {
1948 self.register_arity_argument(span.start_zero_width());
1949 }
1950 arity_state = Arity::Operator;
1951
1952 self.set_op_rhs_toggle();
1953
1954 self.operators.push_back(Op {
1955 span,
1956 ty: OpTy::InitStart,
1957 });
1958 self.groups.push(Group::Init(0, span));
1959
1960 can_start = Start::None;
1961
1962 just_started_arity_group = true;
1963
1964 self.colour(walker, span, SyntaxType::Punctuation);
1965
1966 }
1969 Token::LBrace if state == State::AfterOperand => {
1970 if self.is_in_variable_arg_group()
1976 && arity_state == Arity::PotentialEnd
1977 {
1978 self.register_arity_argument(span.start_zero_width());
1979 } else {
1980 if self.mode != Mode::TakeOneUnit {
1981 self.syntax_diags.push(Syntax::Expr(
1982 ExprDiag::FoundOperandAfterOperand(
1983 self.get_previous_span().unwrap(),
1984 span,
1985 ),
1986 ));
1987 }
1988 break 'main;
1989 }
1990 arity_state = Arity::Operator;
1991
1992 self.set_op_rhs_toggle();
1993
1994 self.operators.push_back(Op {
1995 span,
1996 ty: OpTy::InitStart,
1997 });
1998 self.groups.push(Group::Init(0, span));
1999
2000 state = State::Operand;
2001
2002 can_start = Start::None;
2003
2004 just_started_arity_group = true;
2005
2006 self.colour(walker, span, SyntaxType::Punctuation);
2007 }
2008 Token::RBrace if state == State::AfterOperand => {
2009 if self.is_in_variable_arg_group() {
2010 self.register_arity_argument(span.start_zero_width());
2011 }
2012 arity_state = Arity::PotentialEnd;
2013
2014 match self.end_init(span) {
2015 Ok(_) => {}
2016 Err(_) => {
2017 break 'main;
2018 }
2019 }
2020
2021 can_start = Start::None;
2022
2023 self.colour(walker, span, SyntaxType::Punctuation);
2024
2025 }
2028 Token::RBrace if state == State::Operand => {
2029 if self.is_in_variable_arg_group()
2030 && !just_started_arity_group
2031 {
2032 self.register_arity_argument(span.start_zero_width());
2033 }
2034 let prev_arity = arity_state;
2035 arity_state = Arity::PotentialEnd;
2036
2037 let prev_op_span = self.get_previous_span();
2038 let empty_group = self.just_started_init();
2039
2040 match self.end_init(span) {
2042 Ok(_) => {}
2043 Err(_) => {
2044 break 'main;
2045 }
2046 }
2047
2048 if !empty_group && prev_arity != Arity::PotentialEnd {
2049 self.syntax_diags.push(Syntax::Expr(
2050 ExprDiag::FoundRBraceInsteadOfOperand(
2051 prev_op_span.unwrap(),
2052 span,
2053 ),
2054 ));
2055 }
2056
2057 state = State::AfterOperand;
2060
2061 can_start = Start::None;
2062
2063 self.colour(walker, span, SyntaxType::Punctuation);
2064 }
2065 Token::Comma if state == State::AfterOperand => {
2066 if (self.mode == Mode::DisallowTopLevelList
2067 || self.mode == Mode::TakeOneUnit)
2068 && self.groups.is_empty()
2069 {
2070 break 'main;
2071 }
2072
2073 if arity_state == Arity::PotentialEnd {
2074 self.register_arity_argument(span.start_zero_width());
2075 }
2076 arity_state = Arity::PotentialEnd;
2077
2078 self.stack.push_back(Either::Left(Node {
2079 span,
2080 ty: NodeTy::Separator,
2081 }));
2082
2083 state = State::Operand;
2087
2088 can_start = Start::None;
2089
2090 self.colour(walker, span, SyntaxType::Punctuation);
2091 }
2092 Token::Comma if state == State::Operand => {
2093 if (self.mode == Mode::DisallowTopLevelList
2094 || self.mode == Mode::TakeOneUnit)
2095 && self.groups.is_empty()
2096 {
2097 break 'main;
2098 }
2099
2100 if !self.operators.is_empty() {
2105 self.syntax_diags.push(Syntax::Expr(
2106 ExprDiag::FoundCommaInsteadOfOperand(
2107 self.get_previous_span().unwrap(),
2108 span,
2109 ),
2110 ));
2111 } else if !self.stack.is_empty() {
2112 if let Some(Either::Left(Node {
2113 span: _,
2114 ty: NodeTy::Separator,
2115 })) = self.stack.back()
2116 {
2117 } else {
2118 self.syntax_diags.push(Syntax::Expr(
2119 ExprDiag::FoundCommaInsteadOfOperand(
2120 self.get_previous_span().unwrap(),
2121 span,
2122 ),
2123 ));
2124 }
2125 }
2126
2127 if can_start == Start::EmptyIndex {
2128 match self.groups.last_mut() {
2129 Some(g) => match g {
2130 Group::Index(contains_i, _) => {
2131 *contains_i = false;
2132 }
2133 _ => unreachable!(),
2134 },
2135 _ => unreachable!(),
2136 }
2137 }
2138
2139 if !just_started_arity_group
2140 || self.is_in_variable_arg_group() == false
2141 {
2142 self.register_arity_argument(span.start_zero_width());
2143 }
2144 arity_state = Arity::PotentialEnd;
2145
2146 self.stack.push_back(Either::Left(Node {
2147 span,
2148 ty: NodeTy::Separator,
2149 }));
2150
2151 can_start = Start::None;
2152
2153 self.colour(walker, span, SyntaxType::Punctuation);
2154 }
2155 Token::Dot if state == State::AfterOperand => {
2156 self.push_operator(Op {
2160 span,
2161 ty: OpTy::ObjAccess(false),
2162 });
2163
2164 state = State::Operand;
2167
2168 can_start = Start::None;
2169
2170 arity_state = Arity::Operator;
2171
2172 self.colour(walker, span, SyntaxType::Operator);
2173 }
2174 Token::Dot if state == State::Operand => {
2175 self.syntax_diags.push(Syntax::Expr(
2183 ExprDiag::FoundDotInsteadOfOperand(
2184 self.get_previous_span(),
2185 span,
2186 ),
2187 ));
2188 break 'main;
2189 }
2190 Token::Question => {
2191 if state == State::Operand {
2192 self.syntax_diags.push(Syntax::Expr(
2194 ExprDiag::FoundQuestionInsteadOfOperand(
2195 self.get_previous_span(),
2196 span,
2197 ),
2198 ));
2199 }
2200
2201 self.push_operator(Op {
2202 span,
2203 ty: OpTy::TernaryQ(false),
2204 });
2205 self.groups.push(Group::Ternary);
2206
2207 state = State::Operand;
2210
2211 can_start = Start::None;
2212
2213 arity_state = Arity::Operator;
2214
2215 self.colour(walker, span, SyntaxType::Operator);
2216 }
2217 Token::Colon => {
2218 if !self.is_in_ternary() {
2219 break 'main;
2220 }
2221
2222 if state == State::Operand {
2223 self.syntax_diags.push(Syntax::Expr(
2225 ExprDiag::FoundColonInsteadOfOperand(
2226 self.get_previous_span(),
2227 span,
2228 ),
2229 ));
2230 }
2231
2232 self.push_operator(Op {
2233 span,
2234 ty: OpTy::TernaryC(false),
2235 });
2236
2237 state = State::Operand;
2240
2241 can_start = Start::None;
2242
2243 arity_state = Arity::Operator;
2244
2245 self.colour(walker, span, SyntaxType::Operator);
2246 }
2247 _ => {
2248 self.syntax_diags
2250 .push(Syntax::Expr(ExprDiag::FoundInvalidToken(span)));
2251 break 'main;
2252 }
2253 }
2254
2255 match token {
2258 Token::LParen | Token::LBrace => {}
2259 _ => just_started_arity_group = false,
2260 }
2261
2262 walker.advance_expr_parser(
2263 &mut self.syntax_diags,
2264 &mut self.semantic_diags,
2265 &mut self.syntax_tokens,
2266 );
2267 }
2268
2269 if !self.groups.is_empty() {
2271 let group_end = self.get_previous_span().unwrap().end_zero_width();
2273
2274 while let Some(group) = self.groups.last_mut() {
2276 match group {
2277 Group::FnCall(_, _)
2278 | Group::Init(_, _)
2279 | Group::ArrInit(_, _) => {
2280 if !just_started_arity_group {
2281 self.register_arity_argument(group_end);
2282 }
2283 }
2284 Group::List(count, _) => *count += 1,
2287 _ => {}
2288 }
2289
2290 just_started_arity_group = false;
2293
2294 let group = self.groups.pop().unwrap();
2295 match group {
2296 Group::Paren(_, l_paren) => {
2297 self.syntax_diags.push(Syntax::Expr(
2298 ExprDiag::UnclosedParens(l_paren, group_end),
2299 ));
2300 self.collapse_paren(group, group_end);
2301 }
2302 Group::Index(_, l_bracket) => {
2303 self.syntax_diags.push(Syntax::Expr(
2304 ExprDiag::UnclosedIndexOperator(
2305 l_bracket, group_end,
2306 ),
2307 ));
2308 self.collapse_index(group, group_end)
2309 }
2310 Group::FnCall(_, l_paren) => {
2311 self.syntax_diags.push(Syntax::Expr(
2312 ExprDiag::UnclosedFunctionCall(l_paren, group_end),
2313 ));
2314 self.collapse_fn(group, group_end)
2315 }
2316 Group::Init(_, l_brace) => {
2317 self.syntax_diags.push(Syntax::Expr(
2318 ExprDiag::UnclosedInitializerList(
2319 l_brace, group_end,
2320 ),
2321 ));
2322 self.collapse_init(group, group_end)
2323 }
2324 Group::ArrInit(_, l_paren) => {
2325 self.syntax_diags.push(Syntax::Expr(
2326 ExprDiag::UnclosedArrayConstructor(
2327 l_paren, group_end,
2328 ),
2329 ));
2330 self.collapse_arr_init(group, group_end)
2331 }
2332 Group::List(_, _) => {
2333 self.collapse_list(group, group_end.end)
2334 }
2335 Group::Ternary => {}
2336 }
2337 }
2338 }
2339
2340 while let Some(op) = self.operators.pop_back() {
2344 self.stack.push_back(Either::Right(op));
2345 }
2346 }
2347
2348 fn create_ast(&mut self) -> Option<Expr> {
2350 if self.stack.is_empty() {
2351 return None;
2352 }
2353
2354 let mut stack: VecDeque<Expr> = VecDeque::new();
2355 let pop_back = |stack: &mut VecDeque<Expr>| stack.pop_back().unwrap();
2356
2357 while let Some(item) = self.stack.pop_front() {
2361 match item {
2362 Either::Left(node) => match node.ty {
2363 NodeTy::Lit(lit) => stack.push_back(Expr {
2364 span: node.span,
2365 ty: ExprTy::Lit(lit),
2366 }),
2367 NodeTy::Ident(ident) => stack.push_back(Expr {
2368 span: node.span,
2369 ty: ExprTy::Ident(ident),
2370 }),
2371 NodeTy::Separator => stack.push_back(Expr {
2372 span: node.span,
2373 ty: ExprTy::Separator,
2374 }),
2375 },
2376 Either::Right(op) => match op.ty {
2377 OpTy::AddPre(has_operand) => {
2378 let expr = if has_operand {
2379 Some(pop_back(&mut stack))
2380 } else {
2381 None
2382 };
2383 let span = if let Some(ref expr) = expr {
2384 Span::new(op.span.start, expr.span.end)
2385 } else {
2386 op.span
2387 };
2388
2389 stack.push_back(Expr {
2390 span,
2391 ty: ExprTy::Prefix {
2392 op: PreOp {
2393 span: op.span,
2394 ty: PreOpTy::Add,
2395 },
2396 expr: expr.map(|e| Box::from(e)),
2397 },
2398 });
2399 }
2400 OpTy::SubPre(has_operand) => {
2401 let expr = if has_operand {
2402 Some(pop_back(&mut stack))
2403 } else {
2404 None
2405 };
2406 let span = if let Some(ref expr) = expr {
2407 Span::new(op.span.start, expr.span.end)
2408 } else {
2409 op.span
2410 };
2411
2412 stack.push_back(Expr {
2413 span,
2414 ty: ExprTy::Prefix {
2415 op: PreOp {
2416 span: op.span,
2417 ty: PreOpTy::Sub,
2418 },
2419 expr: expr.map(|e| Box::from(e)),
2420 },
2421 });
2422 }
2423 OpTy::AddPost => {
2424 let expr = pop_back(&mut stack);
2425 let span = Span::new(expr.span.start, op.span.end);
2426
2427 stack.push_back(Expr {
2428 span,
2429 ty: ExprTy::Postfix {
2430 expr: Box::from(expr),
2431 op: PostOp {
2432 ty: PostOpTy::Add,
2433 span: op.span,
2434 },
2435 },
2436 });
2437 }
2438 OpTy::SubPost => {
2439 let expr = pop_back(&mut stack);
2440 let span = Span::new(expr.span.start, op.span.end);
2441
2442 stack.push_back(Expr {
2443 span,
2444 ty: ExprTy::Postfix {
2445 expr: Box::from(expr),
2446 op: PostOp {
2447 ty: PostOpTy::Sub,
2448 span: op.span,
2449 },
2450 },
2451 });
2452 }
2453 OpTy::Neg(has_operand) => {
2454 let expr = if has_operand {
2455 Some(pop_back(&mut stack))
2456 } else {
2457 None
2458 };
2459 let span = if let Some(ref expr) = expr {
2460 Span::new(op.span.start, expr.span.end)
2461 } else {
2462 op.span
2463 };
2464
2465 stack.push_back(Expr {
2466 span,
2467 ty: ExprTy::Prefix {
2468 op: PreOp {
2469 span: op.span,
2470 ty: PreOpTy::Neg,
2471 },
2472 expr: expr.map(|e| Box::from(e)),
2473 },
2474 });
2475 }
2476 OpTy::Flip(has_operand) => {
2477 let expr = if has_operand {
2478 Some(pop_back(&mut stack))
2479 } else {
2480 None
2481 };
2482 let span = if let Some(ref expr) = expr {
2483 Span::new(op.span.start, expr.span.end)
2484 } else {
2485 op.span
2486 };
2487
2488 stack.push_back(Expr {
2489 span,
2490 ty: ExprTy::Prefix {
2491 op: PreOp {
2492 span: op.span,
2493 ty: PreOpTy::Flip,
2494 },
2495 expr: expr.map(|e| Box::from(e)),
2496 },
2497 });
2498 }
2499 OpTy::Not(has_operand) => {
2500 let expr = if has_operand {
2501 Some(pop_back(&mut stack))
2502 } else {
2503 None
2504 };
2505 let span = if let Some(ref expr) = expr {
2506 Span::new(op.span.start, expr.span.end)
2507 } else {
2508 op.span
2509 };
2510
2511 stack.push_back(Expr {
2512 span,
2513 ty: ExprTy::Prefix {
2514 op: PreOp {
2515 span: op.span,
2516 ty: PreOpTy::Not,
2517 },
2518 expr: expr.map(|e| Box::from(e)),
2519 },
2520 });
2521 }
2522 OpTy::TernaryQ(has_rhs) => {
2523 let last = pop_back(&mut stack);
2524 let (cond, true_) = if has_rhs {
2525 (pop_back(&mut stack), Some(last))
2526 } else {
2527 (last, None)
2528 };
2529
2530 let span = if let Some(ref true_) = true_ {
2531 Span::new(cond.span.start, true_.span.end)
2532 } else {
2533 Span::new(cond.span.start, op.span.end)
2534 };
2535
2536 stack.push_back(Expr {
2537 ty: ExprTy::Ternary {
2538 cond: Box::from(cond),
2539 true_: true_.map(|e| Box::from(e)),
2540 false_: None,
2541 },
2542 span,
2543 });
2544 }
2545 OpTy::TernaryC(has_rhs) => {
2546 let last = pop_back(&mut stack);
2547 let (prev, false_) = if has_rhs {
2548 (pop_back(&mut stack), Some(last))
2549 } else {
2550 (last, None)
2551 };
2552
2553 let (cond, true_) = match prev.ty {
2554 ExprTy::Ternary {
2555 cond,
2556 true_,
2557 false_: _,
2558 } => (cond, true_),
2559 _ => unreachable!(),
2562 };
2563
2564 let span = if let Some(ref false_) = false_ {
2565 Span::new(prev.span.start, false_.span.end)
2566 } else {
2567 Span::new(prev.span.start, op.span.end)
2568 };
2569
2570 stack.push_back(Expr {
2571 ty: ExprTy::Ternary {
2572 cond,
2573 true_,
2574 false_: false_.map(|e| Box::from(e)),
2575 },
2576 span,
2577 });
2578 }
2579 OpTy::Paren(has_inner, _l_paren, _end) => {
2580 let expr = if has_inner {
2581 Some(pop_back(&mut stack))
2582 } else {
2583 None
2584 };
2585
2586 stack.push_back(Expr {
2587 span: op.span,
2588 ty: ExprTy::Parens {
2589 expr: expr.map(|e| Box::from(e)),
2590 },
2591 });
2592 }
2593 OpTy::FnCall(count, l_paren, end) => {
2594 let mut temp = VecDeque::new();
2595 for _ in 0..count {
2596 temp.push_front(pop_back(&mut stack));
2597 }
2598
2599 let ident = match temp.pop_front().unwrap().ty {
2601 ExprTy::Ident(ident) => ident,
2602 _ => unreachable!("The first expression of a function call operator is not an identifier!")
2603 };
2604 let args = process_fn_arr_constructor_args(
2605 temp,
2606 &mut self.syntax_diags,
2607 l_paren,
2608 );
2609
2610 stack.push_back(Expr {
2611 span: Span::new(ident.span.start, end.end),
2612 ty: ExprTy::FnCall { ident, args },
2613 });
2614 }
2615 OpTy::Index(contains_i, _l_bracket, end) => {
2616 let i = if contains_i {
2617 Some(Box::from(pop_back(&mut stack)))
2618 } else {
2619 None
2620 };
2621 let expr = pop_back(&mut stack);
2622
2623 stack.push_back(Expr {
2624 span: Span::new(expr.span.start, end.end),
2625 ty: ExprTy::Index {
2626 item: Box::from(expr),
2627 i,
2628 },
2629 });
2630 }
2631 OpTy::Init(count, l_brace, _end) => {
2632 let mut temp = VecDeque::new();
2633 for _ in 0..count {
2634 temp.push_front(pop_back(&mut stack));
2635 }
2636
2637 let args = process_initializer_list_args(
2638 temp,
2639 &mut self.syntax_diags,
2640 l_brace,
2641 );
2642
2643 stack.push_back(Expr {
2644 ty: ExprTy::InitList { args },
2645 span: op.span,
2646 });
2647 }
2648 OpTy::ArrInit(count, l_paren, end) => {
2649 let mut temp = VecDeque::new();
2650 for _ in 0..count {
2651 temp.push_front(pop_back(&mut stack));
2652 }
2653
2654 let arr = temp.pop_front().unwrap();
2656 match arr.ty {
2657 ExprTy::Index { .. } => {}
2658 _ => {
2659 unreachable!("The first expression of an array constructor operator is not an `Expr::Index`!");
2660 }
2661 }
2662
2663 let args = process_fn_arr_constructor_args(
2664 temp,
2665 &mut self.syntax_diags,
2666 l_paren,
2667 );
2668
2669 stack.push_back(Expr {
2670 span: Span::new(arr.span.start, end.end),
2671 ty: ExprTy::ArrConstructor {
2672 arr: Box::from(arr),
2673 args,
2674 },
2675 });
2676 }
2677 OpTy::List(count) => {
2678 let mut temp = VecDeque::new();
2679 for _ in 0..count {
2680 temp.push_front(pop_back(&mut stack));
2681 }
2682
2683 let args =
2684 process_list_args(temp, &mut self.syntax_diags);
2685
2686 stack.push_back(Expr {
2687 ty: ExprTy::List { items: args },
2688 span: op.span,
2689 });
2690 }
2691 OpTy::ObjAccess(has_rhs) => {
2692 let last = pop_back(&mut stack);
2693 let (left, right) = if has_rhs {
2694 (pop_back(&mut stack), Some(last))
2695 } else {
2696 (last, None)
2697 };
2698
2699 let span = if let Some(ref right) = right {
2700 Span::new(left.span.start, right.span.end)
2701 } else {
2702 Span::new(left.span.start, op.span.end)
2703 };
2704
2705 stack.push_back(Expr {
2706 ty: ExprTy::ObjAccess {
2707 obj: Box::from(left),
2708 leaf: right.map(|e| Box::from(e)),
2709 },
2710 span,
2711 });
2712 }
2713 OpTy::Add(has_rhs)
2714 | OpTy::Sub(has_rhs)
2715 | OpTy::Mul(has_rhs)
2716 | OpTy::Div(has_rhs)
2717 | OpTy::Rem(has_rhs)
2718 | OpTy::And(has_rhs)
2719 | OpTy::Or(has_rhs)
2720 | OpTy::Xor(has_rhs)
2721 | OpTy::LShift(has_rhs)
2722 | OpTy::RShift(has_rhs)
2723 | OpTy::EqEq(has_rhs)
2724 | OpTy::NotEq(has_rhs)
2725 | OpTy::Gt(has_rhs)
2726 | OpTy::Lt(has_rhs)
2727 | OpTy::Ge(has_rhs)
2728 | OpTy::Le(has_rhs)
2729 | OpTy::AndAnd(has_rhs)
2730 | OpTy::OrOr(has_rhs)
2731 | OpTy::XorXor(has_rhs)
2732 | OpTy::Eq(has_rhs)
2733 | OpTy::AddEq(has_rhs)
2734 | OpTy::SubEq(has_rhs)
2735 | OpTy::MulEq(has_rhs)
2736 | OpTy::DivEq(has_rhs)
2737 | OpTy::RemEq(has_rhs)
2738 | OpTy::AndEq(has_rhs)
2739 | OpTy::OrEq(has_rhs)
2740 | OpTy::XorEq(has_rhs)
2741 | OpTy::LShiftEq(has_rhs)
2742 | OpTy::RShiftEq(has_rhs) => {
2743 let last = pop_back(&mut stack);
2744 let (left, right) = if has_rhs {
2745 (pop_back(&mut stack), Some(last))
2746 } else {
2747 (last, None)
2748 };
2749
2750 let span = if let Some(ref right) = right {
2751 Span::new(left.span.start, right.span.end)
2752 } else {
2753 Span::new(left.span.start, op.span.end)
2754 };
2755 let bin_op = op.to_bin_op();
2756
2757 stack.push_back(Expr {
2758 ty: ExprTy::Binary {
2759 left: Box::from(left),
2760 op: bin_op,
2761 right: right.map(|e| Box::from(e)),
2762 },
2763 span,
2764 });
2765 }
2766 _ => {
2767 unreachable!("Invalid operator {op:?} in shunting yard stack. This operator should never be present in the final RPN stack.");
2768 }
2769 },
2770 }
2771 }
2772
2773 if stack.len() > 1 {
2774 let expr = pop_back(&mut stack);
2775 stack.push_back(expr);
2776 }
2777
2778 if stack.len() != 1 {
2779 unreachable!("After processing the shunting yard output stack, we are left with more than one expression. This should not happen.");
2780 }
2781
2782 Some(stack.pop_back().unwrap())
2784 }
2785}
2786
2787fn process_fn_arr_constructor_args(
2788 mut list: VecDeque<Expr>,
2789 diags: &mut Vec<Syntax>,
2790 opening_delim: Span,
2791) -> Vec<Expr> {
2792 let mut args = Vec::new();
2793
2794 enum Prev {
2795 None,
2796 Item(Span),
2797 Comma(Span),
2798 }
2799 let mut previous = Prev::None;
2800 while let Some(arg) = list.pop_front() {
2801 match arg.ty {
2802 ExprTy::Separator => {
2803 match previous {
2804 Prev::Comma(span) => {
2805 diags.push(Syntax::Expr(
2806 ExprDiag::ExpectedArgAfterComma(Span::new_between(
2807 span, arg.span,
2808 )),
2809 ));
2810 }
2811 Prev::None => {
2812 diags.push(Syntax::Expr(
2813 ExprDiag::ExpectedArgBetweenParenComma(
2814 Span::new_between(opening_delim, arg.span),
2815 ),
2816 ));
2817 }
2818 _ => {}
2819 }
2820 previous = Prev::Comma(arg.span);
2821 }
2822 _ => {
2823 match previous {
2824 Prev::Item(span) => {
2825 diags.push(Syntax::Expr(
2826 ExprDiag::ExpectedCommaAfterArg(Span::new_between(
2827 span, arg.span,
2828 )),
2829 ));
2830 }
2831 _ => {}
2832 }
2833 previous = Prev::Item(arg.span);
2834 args.push(arg);
2835 }
2836 }
2837 }
2838
2839 if let Prev::Comma(span) = previous {
2840 diags.push(Syntax::Expr(ExprDiag::ExpectedArgAfterComma(
2841 span.next_single_width(),
2842 )));
2843 }
2844
2845 args
2846}
2847
2848fn process_initializer_list_args(
2849 mut list: VecDeque<Expr>,
2850 diags: &mut Vec<Syntax>,
2851 opening_delim: Span,
2852) -> Vec<Expr> {
2853 let mut args = Vec::new();
2854
2855 enum Prev {
2856 None,
2857 Item(Span),
2858 Comma(Span),
2859 }
2860 let mut previous = Prev::None;
2861 while let Some(arg) = list.pop_front() {
2862 match arg.ty {
2863 ExprTy::Separator => {
2864 match previous {
2865 Prev::Comma(span) => {
2866 diags.push(Syntax::Expr(
2867 ExprDiag::ExpectedArgAfterComma(Span::new_between(
2868 span, arg.span,
2869 )),
2870 ));
2871 }
2872 Prev::None => {
2873 diags.push(Syntax::Expr(
2874 ExprDiag::ExpectedArgBetweenParenComma(
2875 Span::new_between(opening_delim, arg.span),
2876 ),
2877 ));
2878 }
2879 _ => {}
2880 }
2881 previous = Prev::Comma(arg.span);
2882 }
2883 _ => {
2884 match previous {
2885 Prev::Item(span) => {
2886 diags.push(Syntax::Expr(
2887 ExprDiag::ExpectedCommaAfterArg(Span::new_between(
2888 span, arg.span,
2889 )),
2890 ));
2891 }
2892 _ => {}
2893 }
2894 previous = Prev::Item(arg.span);
2895 args.push(arg);
2896 }
2897 }
2898 }
2899
2900 args
2901}
2902
2903fn process_list_args(
2904 mut list: VecDeque<Expr>,
2905 diags: &mut Vec<Syntax>,
2906) -> Vec<Expr> {
2907 let mut args = Vec::new();
2908
2909 enum Prev {
2910 None,
2911 Item(Span),
2912 Comma(Span),
2913 }
2914 let mut previous = Prev::None;
2915 while let Some(arg) = list.pop_front() {
2916 match arg.ty {
2917 ExprTy::Separator => {
2918 match previous {
2919 Prev::Comma(span) => {
2920 diags.push(Syntax::Expr(
2921 ExprDiag::ExpectedExprAfterComma(
2922 Span::new_between(span, arg.span),
2923 ),
2924 ));
2925 }
2926 Prev::None => {
2927 diags.push(Syntax::Expr(
2928 ExprDiag::ExpectedExprBeforeComma(
2929 arg.span.previous_single_width(),
2930 ),
2931 ));
2932 }
2933 _ => {}
2934 }
2935 previous = Prev::Comma(arg.span);
2936 }
2937 _ => {
2938 match previous {
2939 Prev::Item(span) => {
2940 diags.push(Syntax::Expr(
2941 ExprDiag::ExpectedCommaAfterExpr(
2942 Span::new_between(span, arg.span),
2943 ),
2944 ));
2945 }
2946 _ => {}
2947 }
2948 previous = Prev::Item(arg.span);
2949 args.push(arg);
2950 }
2951 }
2952 }
2953
2954 if let Prev::Comma(span) = previous {
2955 diags.push(Syntax::Expr(ExprDiag::ExpectedExprAfterComma(
2956 span.next_single_width(),
2957 )));
2958 }
2959
2960 args
2961}