glast/parser/
expression.rs

1//! The parser for general expressions.
2
3use 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
17/*
18Useful reading links related to expression parsing:
19
20https://petermalmgren.com/three-rust-parsers/
21	- recursive descent parser
22
23https://wcipeg.com/wiki/Shunting_yard_algorithm
24	- shunting yard overview & algorithm extensions
25
26https://erikeidt.github.io/The-Double-E-Method
27	- stateful shunting yard for unary support
28
29https://matklad.github.io/2020/04/13/simple-but-powerful-pratt-parsing.html
30https://matklad.github.io/2020/04/15/from-pratt-to-dijkstra.html
31	- two parter, first writing a pratt parser, and then refactoring into a shunting yard parser with a slightly
32	  different approach
33*/
34
35/// Tries to parse an expression beginning at the current position.
36///
37/// - `end_tokens` - Any tokens which, when encountered, will immediately stop the parser without producing syntax
38///   errors.
39pub(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		// If we are at the end of the token stream, we can return early with nothing.
47		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/// Configures the behaviour of the expression parser.
71#[derive(Debug, PartialEq, Eq)]
72pub(super) enum Mode {
73	/// The default behaviour which can be used to parse any valid expressions, including those that can form
74	/// entire statements, such as `i = 5`.
75	Default,
76	/// Disallows top-level lists, i.e. upon encountering the first comma (`,`) outside of a group, the parser will
77	/// return. E.g. `a, b` would return but `(a, b)` wouldn't.
78	DisallowTopLevelList,
79	/// Disallows treating assignments as a valid expression, i.e. upon encountering the first `Token::Eq` (`=`),
80	/// the parser will return.
81	BreakAtEq,
82	/// Stops parsing after taking one unit, without producing a lot of the syntax errors that are normally
83	/// produced. This mode is mostly useful to take single "expressions", for example, taking a single unit as a
84	/// parameter type, and then another single unit as the parameter identifier.
85	///
86	/// This mode stops parsing at the following:
87	/// - missing binary operators, e.g. `int i` or `int (` or `int {`,
88	/// - commas in a top-level list, e.g. `int, i` but not `int[a, b]`,
89	/// - unmatched closing delimiters, e.g. `int[])` or `int }`,
90	/// - equals sign binary operator, e.g. `i = 5`.
91	///
92	/// In this mode, none of those scenarios generate a syntax error.
93	///
94	/// E.g. in `int[3],` the parser would break after the end of the index operator.
95	///
96	/// E.g. in `(float) f`, the parser would break after the end of the parenthesis.
97	///
98	/// E.g. in `i + 5, b`, the parser would break after the 5.
99	///
100	/// E.g. in `i = 5`, the parser would break after i.
101	///
102	/// E.g. in `{1} 2`, the parser would break after the end of the initializer list.
103	///
104	/// Note that this mode still composes with `end_tokens`, so if that, for example, contains `[Token::LBrace]`,
105	/// then `{1} 2` would immediately break and return no expression.
106	TakeOneUnit,
107}
108
109/// A node; used in the parser stack.
110#[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/// A node operator; used in the parser stack.
124#[derive(Debug, Clone, PartialEq)]
125struct Op {
126	ty: OpTy,
127	span: Span,
128}
129
130#[derive(Debug, Clone, PartialEq)]
131enum OpTy {
132	/* BINARY OPERATORS */
133	/* - `0` - Whether to consume a node for the right-hand side expression. */
134	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	/// - `0` - Whether to consume a node for the leaf expression (after the `.`).
165	ObjAccess(bool),
166	/// - `0` - Whether to consume a node for the if expression (after the `?`).
167	TernaryQ(bool),
168	/// - `0` - Whether to consume a node for the else expression (after the `:`).
169	TernaryC(bool),
170	/* PREFIX OPERATORS */
171	/* - `0` - Whether to consume a node for the expression. */
172	AddPre(bool),
173	SubPre(bool),
174	Neg(bool),
175	Flip(bool),
176	Not(bool),
177	/* POSTFIX OPERATORS */
178	AddPost,
179	SubPost,
180	/* GROUP BEGINNING DELIMITERS */
181	/// The `(` token.
182	ParenStart,
183	/// The `(` token.
184	FnCallStart,
185	/// The `[` token.
186	IndexStart,
187	/// The `{` token.
188	InitStart,
189	/// The `(` token.
190	ArrInitStart,
191	/* GROUPS */
192	/// A parenthesis group. This operator spans from the opening parenthesis to the closing parenthesis.
193	///
194	/// - `0` - Whether to consume a node for the inner expression within the `(...)` parenthesis.
195	/// - `1` - The span of the opening parenthesis.
196	/// - `2` - The span of the closing parenthesis. If this is zero-width, that means there is no `)` token
197	///   present.
198	Paren(bool, Span, Span),
199	/// A function call. This operator spans from the opening parenthesis to the closing parenthesis.
200	///
201	/// - `0` - The number of nodes to consume for the arguments; this includes the function identifier node, so it
202	///   will always be `1` or greater.
203	/// - `1` - The span of the opening parenthesis.
204	/// - `2` - The span of the closing parenthesis. If this is zero-width, that means there is no `)` token
205	///   present.
206	FnCall(usize, Span, Span),
207	/// An index operator. This operator spans from the opening bracket to the closing bracket.
208	///
209	/// - `0` - Whether to consume a node for the expression within the `[...]` brackets.
210	/// - `1` - The span of the opening bracket.
211	/// - `2` - The span of the closing bracket. If this is zero-width, that means there is no `]` token present.
212	Index(bool, Span, Span),
213	/// An initializer list. This operator spans from the opening brace to the closing brace.
214	///
215	/// - `0` - The number of nodes to consume for the arguments.
216	/// - `1` - The span of the opening brace.
217	/// - `2` - The span of the closing brace. If this is zero-width, that means there is no `}` token present.
218	Init(usize, Span, Span),
219	/// An array initializer. This operator spans from the opening parenthesis to the closing parenthesis.
220	///
221	/// - `0` - The number of nodes to consume for the arguments; this includes the index expression node, so it
222	///   will always be `1` or greater.
223	/// - `1` - The span of the opening parenthesis.
224	/// - `2` - The span of the closing parenthesis. If this is zero-width, that means there is no `)` token
225	///   present.
226	ArrInit(usize, Span, Span),
227	/// A general list **outside** of function calls, initializer lists and array constructors.
228	///
229	/// - `0` - The number of nodes to consume for the arguments.
230	List(usize),
231}
232
233impl Op {
234	/// Converts from a lexer `OpTy` token to the `Op` type used in this expression parser.
235	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					// These tokens are handled by individual branches in the main parser loop.
274					unreachable!("[Op::from_token] Given a `token` which should never be handled by this function.")
275				}
276			},
277		}
278	}
279
280	/// Returns the precedence of this operator.
281	#[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			// These are never directly checked for precedence, but rather have special branches.
316			_ => 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/// An open grouping of items.
363#[derive(Debug, PartialEq)]
364enum Group {
365	/// A parenthesis group.
366	///
367	/// - `0` - Whether this group has an inner expression within the parenthesis.
368	/// - `1` - The span of the opening parenthesis.
369	Paren(bool, Span),
370	/// A function call.
371	///
372	/// - `0` - The number of expressions to consume for the arguments.
373	/// - `1` - The span of the opening parenthesis.
374	FnCall(usize, Span),
375	/// An index operator.
376	///
377	/// - `0` - Whether this group has an inner expression within the brackets.
378	/// - `1` - The span of the opening bracket.
379	Index(bool, Span),
380	/// An initializer list.
381	///
382	/// - `0` - The number of expressions to consume for the arguments.
383	/// - `1` - The span of the opening brace.
384	Init(usize, Span),
385	/// An array constructor.
386	///
387	/// - `0` - The number of expressions to consume for the arguments.
388	/// - `1` - The span of the opening parenthesis.
389	ArrInit(usize, Span),
390	/// A general list **outside** of function calls, initializer lists and array constructors.
391	///
392	/// - `0` - The number of expressions to consume for the arguments.
393	/// - `1` - The starting position of this list.
394	///
395	/// # Invariants
396	/// This group only exists if the outer `Group` is not of type `Group::FnCall|Init|ArrInit|List`. (You can't
397	/// have a list within a list since there are no delimiters, and commas within the other groups won't create an
398	/// inner list but rather increase the arity).
399	List(usize, usize),
400	/// A ternary expression.
401	Ternary,
402}
403
404/// The implementation of a shunting yard-based parser.
405struct ShuntingYard {
406	/// The final output stack in RPN.
407	stack: VecDeque<Either<Node, Op>>,
408	/// Temporary stack to hold operators.
409	operators: VecDeque<Op>,
410	/// Temporary stack to hold item groups. The top-most entry is the group being currently parsed.
411	groups: Vec<Group>,
412	/// The start position of the first item in this expression.
413	start_position: usize,
414	/// The behavioural mode of the parser.
415	mode: Mode,
416
417	/// Syntax diagnostics encountered during the parser execution.
418	syntax_diags: Vec<Syntax>,
419	/// Semantic diagnostics encountered during the parser execution; (these will only be related to macros).
420	semantic_diags: Vec<Semantic>,
421
422	/// Syntax highlighting tokens created during the parser execution.
423	syntax_tokens: Vec<SyntaxToken>,
424}
425
426impl ShuntingYard {
427	/// Pushes an operator onto the stack, potentially popping any operators which have a greater precedence than
428	/// the operator being pushed.
429	fn push_operator(&mut self, op: Op) {
430		if let OpTy::TernaryC(_) = op.ty {
431			// This completes the ternary.
432			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				// Group delimiter start operators always have the highest precedence, so we don't need to check
446				// further.
447				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				// This is done to make `ObjAccess` right-associative.
457				(OpTy::ObjAccess(_), OpTy::ObjAccess(_)) => {
458					let moved = self.operators.pop_back().unwrap();
459					self.stack.push_back(Either::Right(moved));
460					break;
461				}
462				// These are done to make the ternary operator right-associate correctly. This is slightly more
463				// complex since the ternary is made of two distinct "operators", the `?` and `:`.
464				(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			// TODO: Implement same precedence check for binary operators as in the conditional expression parser.
478			// This is strictly not necessary since we won't ever be mathematically evaluating expressions, but it
479			// would be a good idea nonetheless.
480			if op.precedence() < back.precedence() {
481				let moved = self.operators.pop_back().unwrap();
482				self.stack.push_back(Either::Right(moved));
483			} else {
484				// If the precedence is greater, we aren't going to be moving any operators to the stack anymore,
485				// so we can exit the loop.
486				break;
487			}
488		}
489		self.operators.push_back(op);
490	}
491
492	/// # Invariants
493	/// Assumes that `group` is of type [`Group::Paren`].
494	///
495	/// `end_span` is the span which marks the end of this parenthesis group. It may be the span of the `)` token,
496	/// or it may be a zero-width span if this group was collapsed without a matching closing delimiter.
497	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					// Any other operators get moved, since we are moving everything until we hit the start
521					// delimiter.
522					self.stack.push_back(Either::Right(op));
523				}
524			}
525		} else {
526			unreachable!()
527		}
528	}
529
530	/// # Invariants
531	/// Assumes that `group` is of type [`Group::Fn`].
532	///
533	/// `end_span` is the span which marks the end of this function call group. It may be the span of the `)`
534	/// token, or it may be a zero-width span if this group was collapsed without a matching closing delimiter.
535	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					// The first expression will always be the `Expr::Ident` containing the function identifier,
553					// hence the `count + 1`.
554					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					// Any other operators get moved, since we are moving everything until we hit the start
561					// delimiter.
562					self.stack.push_back(Either::Right(op));
563				}
564			}
565		} else {
566			unreachable!()
567		}
568	}
569
570	/// # Invariants
571	/// Assumes that `group` is of type [`Group::Index`].
572	///
573	/// `end_span` is the span which marks the end of this index group. It may be a span of the `]` token, or it
574	/// may be a zero-width span if this group was collapsed without a matching closing delimiter.
575	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					// Any other operators get moved, since we are moving everything until we hit the start
599					// delimiter.
600					self.stack.push_back(Either::Right(op));
601				}
602			}
603		} else {
604			unreachable!()
605		}
606	}
607
608	/// # Invariants
609	/// Assumes that `group` is of type [`Group::Init`].
610	///
611	/// `end_span` is the span which marks the end of this initializer list group. It may be a span of the `}`
612	/// token, or it may be a zero-width span if this group was collapsed without a matching closing delimiter.
613	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					// Any other operators get moved, since we are moving everything until we hit the start
637					// delimiter.
638					self.stack.push_back(Either::Right(op));
639				}
640			}
641		} else {
642			unreachable!()
643		}
644	}
645
646	/// # Invariants
647	/// Assumes that `group` is of type [`Group::ArrInit`].
648	///
649	/// `end_span` is the span which marks the end of this array constructor group. It may be a span of the `)`
650	/// token, or it may be a zero-width span if this group was collapsed without a matching closing delimiter.
651	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					// The first expression will always be the `Expr::Index` containing the identifier/item and the
669					// array index, hence the `count + 1`.
670					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					// Any other operators get moved, since we are moving everything until we hit the start
677					// delimiter.
678					self.stack.push_back(Either::Right(op));
679				}
680			}
681		} else {
682			unreachable!()
683		}
684	}
685
686	/// # Invariants
687	/// Assumes that `group` is of type [`Group::List`].
688	///
689	/// `span_end` is the position which marks the end of this list group.
690	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				// Lists don't have a starting delimiter, so we consume until we encounter another group-start
706				// delimiter (and if there are none, we just end up consuming the rest of the operator stack).
707				// Since lists cannnot exist within a `Group::FnCall|Init|ArrInit`, we don't check for those start
708				// delimiters.
709				match op.ty {
710					OpTy::ParenStart | OpTy::IndexStart => break,
711					_ => {
712						// Any other operators get moved, since we are moving everything until we hit the start
713						// delimiter.
714						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	/// Registers the end of a parenthesis, function call or array constructor group, popping any operators until
729	/// the start of the group is reached.
730	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				// Since we have no groups, that means we have a lonely `)`. This means we want to stop parsing
735				// further tokens.
736				return Err(());
737			}
738		};
739
740		match current_group {
741			Group::Paren(_, _) => {}
742			Group::FnCall(_, _) | Group::ArrInit(_, _) => {}
743			_ => {
744				// The current group is not a bracket/function/array constructor group, so we need to check whether
745				// there is one at all.
746
747				if self.exists_paren_fn_group() {
748					// We have at least one other group to close before we can close the bracket/function/array
749					// constructor group.
750					'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					// Since we don't have a parenthesis/function/array constructor group at all, that means we
804					// have a lonely `)`. This means we want to stop parsing further tokens.
805					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			// Either the inner-most group is already a parenthesis-delimited group, or we've closed all inner
816			// groups and are now at a parenthesis-delimited group, hence this branch will never occur.
817			_ => unreachable!(),
818		}
819		Ok(())
820	}
821
822	/// Registers the end of an index operator group, popping any operators until the start of the index group is
823	/// reached.
824	///
825	/// `end_span` is a span which ends at the end of this index operator. (The start value is irrelevant).
826	fn end_index(&mut self, end_span: Span) -> Result<(), ()> {
827		let current_group = match self.groups.last() {
828			Some(t) => t,
829			None => {
830				// Since we have no groups, that means we have a lonely `]`. This means we want to stop parsing
831				// further tokens.
832				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			// The current group is not an index group, so we need to check whether there is one at all.
842
843			if self.exists_index_group() {
844				// We have at least one other group to close before we can close the index group.
845				'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				// Since we don't have an index group at all, that means we have a lonely `]`. This means we want
915				// to stop parsing further tokens.
916				return Err(());
917			}
918		}
919
920		let group = self.groups.pop().unwrap();
921		self.collapse_index(group, end_span);
922		Ok(())
923	}
924
925	/// Registers the end of an initializer list group, popping any operators until the start of the group is
926	/// reached.
927	fn end_init(&mut self, end_span: Span) -> Result<(), ()> {
928		let current_group = match self.groups.last() {
929			Some(t) => t,
930			None => {
931				// Since we have no groups, that means we have a lonely `}`. This means we want to stop parsing
932				// further tokens.
933				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			// The current group is not an initializer group, so we need to check whether there is one at all.
941
942			if self.exists_init_group() {
943				// We have at least one other group to close before we can close the initializer group.
944				'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						// See `List` documentation.
1000						Group::List(_, _) => unreachable!(),
1001						Group::Init(_, _) => break 'inner,
1002					}
1003				}
1004			} else {
1005				// Since we don't have an initializer group at all, that means we have a lonely `}`. This means we
1006				// want to stop parsing further tokens.
1007				return Err(());
1008			}
1009		}
1010
1011		let group = self.groups.pop().unwrap();
1012		self.collapse_init(group, end_span);
1013		Ok(())
1014	}
1015
1016	/// Registers the end of a sub-expression, popping any operators until the start of the group (or expression)
1017	/// is reached.
1018	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					// We want to move all existing operators up to the function call, initializer list, or array
1025					// constructor start delimiter to the stack, to clear it for the next expression.
1026					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				// We collapse the entire group since commas aren't allowed within parenthesis or index
1052				// operators. We continue looping until we either come across a delimited arity group, such as
1053				// a function call, or if have no such group we create a top-level list group.
1054				// We want to move all existing operators up to the function call, initializer list, or array
1055				// constructor start delimiter to the stack, to clear it for the next expression.
1056				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		// Since we are outside of any group, we can just push all the operators to the stack to clear it for
1082		// the next expression. We also push a new list group. Since list groups don't have a start delimiter,
1083		// we can only do it now that we've encountered a comma in an otherwise ungrouped expression.
1084		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	/// Sets the toggle on the last operator that it has a right-hand side operand, (if applicable).
1099	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	/// Returns whether we have just started to parse a parenthesis group, i.e. `..(<HERE>`.
1152	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	/// Returns whether we have just started to parse a function, i.e. `..fn(<HERE>`
1164	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	/// Returns whether we have just started to parse an initializer list, i.e. `..{<HERE>`
1184	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	/// Returns whether we are currently within a ternary expression group.
1196	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	/// Returns whether we are currently in a function call, initializer list, array constructor, or general list
1208	/// group.
1209	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	/// Returns whether an open parenthesis, function call or array constructor group exists.
1236	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	/// Returns whether an open index operator group exists.
1249	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	/// Returns whether an open initializer list group exists.
1259	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	/// Returns the [`Span`] of the last item on the stack or operator stack.
1269	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	/// Pushes a syntax highlighting token over the given span.
1291	fn colour<'a, P: super::TokenStreamProvider<'a>>(
1292		&mut self,
1293		walker: &Walker<'a, P>,
1294		span: Span,
1295		token: SyntaxType,
1296	) {
1297		// When we are within a macro, we don't want to produce syntax tokens.
1298		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	/// Parses a list of tokens. Populates the internal `stack` with a RPN output.
1308	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			/// We are looking for either a) a prefix operator, b) an atom, c) bracket group start, d) function
1316			/// call group start, e) initializer list group start.
1317			Operand,
1318			/// We are looking for either a) a postfix operator, b) an index operator start or end, c) a binary
1319			/// operator, d) bracket group end, e) function call group end, f) initializer list group end, g) a
1320			/// comma, h) end of expression.
1321			AfterOperand,
1322		}
1323		let mut state = State::Operand;
1324
1325		#[derive(PartialEq)]
1326		enum Start {
1327			/// Nothing.
1328			None,
1329			/// We have found an `ident`; we can start a function call assuming we find `(` next. If we encounter a
1330			/// `[` next, we want to store the `possible_delim_start` value with the `Index` group, in case we have
1331			/// an array constructor after the index.
1332			FnOrArr,
1333			/// We have found an `Expr::Index`; we can start an array constructor assuming we find `(` next.
1334			ArrInit,
1335			/// We have found a `[`. If the next token is a `]` we have an empty index operator.
1336			EmptyIndex,
1337		}
1338		let mut can_start = Start::None;
1339
1340		#[derive(PartialEq)]
1341		enum Arity {
1342			/// On the first iteration of the parsing loop.
1343			None,
1344			/// Signifies that the previous token can end an argument in an arity group, for example:
1345			/// ```text
1346			/// fn( 1+1, 5
1347			///        ^ signifies the end
1348			/// ```
1349			/// Or when dealing with error recovery of missing commas:
1350			/// ```text
1351			/// { 1+1 5
1352			///     ^ signifies the end, (missing comma afterwards though)
1353			/// ```
1354			PotentialEnd,
1355			/// Signifies that the previous token cannot end an argument in an arity group, for example:
1356			/// ```text
1357			/// fn( 1 + 6
1358			///       ^ expects a rhs,
1359			///           so the 6 is treated as part of the same argument
1360			/// ```
1361			/// The only exception is if the current token is a comma (`,`), in which case it always ends the
1362			/// argument in an arity group.
1363			Operator,
1364		}
1365		// The state of arity manipulation set in the previous iteration of the loop.
1366		let mut arity_state = Arity::None;
1367
1368		// Whether we have just started an arity group. This is set to `true` right after we have an opening
1369		// delimiter to an arity group, such as `(` or `{`. This is also set to `true` at the beginning here, in
1370		// order to correctly handle the case where we encounter a comma `,` as the first token in this expression.
1371		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				// Return if we reach the end of the token list.
1377				None => break 'main,
1378			};
1379
1380			// If the current token is one which signifies the end of the current expression, we stop parsing.
1381			if end_tokens.contains(token) {
1382				// We may be given a `)` token to break parsing at, but take this example: `while ((true))`.
1383				// As part of the while statement parser, we've already consumed the first `(`. We then start
1384				// the rest in here, and we start a parenthesis group with the `true` token within it. But then we
1385				// encounter the first `)` and immediately break, leaving an incomplete expression and syntax
1386				// errors where they shouldn't be.
1387				//
1388				// So instead, we only break if we encounter these closing delimiter tokens assuming we don't have
1389				// the relevant group open.
1390				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					// TODO: Register syntax error if previous was operator.
1396					break 'main;
1397				}
1398			}
1399
1400			match token {
1401				Token::Num { .. } | Token::Bool(_)
1402					if state == State::Operand =>
1403				{
1404					// If we previously had a token which can end an argument of an arity group, and we are in a
1405					// delimited arity group, we want to increase the arity, for example:
1406					// `fn(10, 5` or `fn(10 5` or `{1+1  100`
1407					// but not:
1408					// `10 5` or `fn(10 + 5`
1409					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					// We switch state since after an operand, we are expecting an operator, i.e.
1431					// `..10 + 5` instead of `..10 5`.
1432					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 we previously had a token which can end an argument of an arity group, and we are in a
1456					// delimited arity group, we want to increase the arity, for example:
1457					// `fn(10, 5` or `fn(10 5` or `{1+1  100`
1458					// but not:
1459					// `a b` or `fn(10 + 5`
1460					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						// We are not in a delimited arity group. We don't perform error recovery because in this
1466						// situation it's not as obvious what the behaviour should be, so we avoid any surprises.
1467						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					// We don't change state since even though we found an operand instead of an operator, after
1504					// this operand we will still be expecting an operator.
1505				}
1506				Token::Ident(s) if state == State::Operand => {
1507					// If we previously had a token which can end an argument of an arity group, and we are in a
1508					// delimited arity group, we want to increase the arity, for example:
1509					// `fn(10, i` or `fn(10 i` or `{1+1  i`
1510					// but not:
1511					// `a i` or `fn(10 + i`
1512					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					// We switch state since after an operand, we are expecting an operator, i.e.
1528					// `..10 + i` instead of `..10 i`.
1529					state = State::AfterOperand;
1530
1531					// After an identifier, we may start a function call, or eventually an array constructor.
1532					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 we previously had a token which can end an argument of an arity group, and we are in a
1544					// delimited arity group, we want to increase the arity, for example:
1545					// `fn(10, 5` or `fn(10 5` or `{1+1  100`
1546					// but not:
1547					// `a b` or `fn(10 + 5`
1548					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						// We are not in a delimited arity group. We don't perform error recovery because in this
1554						// situation it's not as obvious what the behaviour should be, so we avoid any surprises.
1555						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					// After an identifier, we may start a function call.
1574					can_start = Start::FnOrArr;
1575
1576					self.colour(walker, span, SyntaxType::UncheckedIdent);
1577
1578					// We don't change state since even though we found an operand instead of an operator, after
1579					// this operand we will still be expecting an operator.
1580				}
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 we previously had a token which can end an argument of an arity group, and we are
1596							// in a delimited arity group, we want to increase the arity, for example:
1597							// `fn(10, !true` or `fn(10 !true` or `{1+1  !true`
1598							// but not:
1599							// `a !true` or `fn(10 + !true`
1600							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						// If the operator is a valid prefix operator, we can move it to the stack. We don't switch
1621						// state since after a prefix operator, we are still looking for an operand atom.
1622						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						// These operators are postfix operators. We don't switch state since after a postfix
1667						// operator, we are still looking for a binary operator or the end of expression, i.e.
1668						// `..i++ - i` rather than `..i++ i`.
1669						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						// Any other operators can be part of a binary expression. We switch state since after a
1682						// binary operator we are expecting an operand.
1683						_ => {
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 we previously had a token which can end an argument of an arity group, and we are in a
1697					// delimited arity group, we want to increase the arity, for example:
1698					// `fn(10, (` or `fn(10 (` or `{1+1  (`
1699					// but not:
1700					// `a (` or `fn(10 + (`
1701					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					// We don't switch state since after a `(`, we are expecting an operand, i.e.
1721					// `..+ ( 1 *` rather than `..+ ( *`.
1722				}
1723				Token::LParen if state == State::AfterOperand => {
1724					if can_start == Start::FnOrArr {
1725						// We have `ident(` which makes this a function call.
1726						self.operators.push_back(Op {
1727							span,
1728							ty: OpTy::FnCallStart,
1729						});
1730						self.groups.push(Group::FnCall(0, span));
1731
1732						// We switch state since after a `(` we are expecting an operand, i.e.
1733						// `fn( 1..` rather than`fn( +..`.1
1734						state = State::Operand;
1735
1736						// We unset this flag, since this flag is only used to detect the `ident` -> `(` token
1737						// chain.
1738						can_start = Start::None;
1739
1740						just_started_arity_group = true;
1741					} else if can_start == Start::ArrInit {
1742						// We have `ident[...](` which makes this an array constructor.
1743						self.operators.push_back(Op {
1744							span,
1745							ty: OpTy::ArrInitStart,
1746						});
1747						self.groups.push(Group::ArrInit(0, span));
1748
1749						// We switch state since after a `(` we are expecting an operand, i.e.
1750						// `int[]( 1,..` rather than`int[]( +1,..`.
1751						state = State::Operand;
1752
1753						// We unset this flag, since this flag is only used to detect the `..]` -> `(` token chain.
1754						can_start = Start::None;
1755
1756						just_started_arity_group = true;
1757					} else {
1758						// We have something like `..5 (`.
1759						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							// We are not in a delimited arity group. We don't perform error recovery because in
1767							// this situation it's not as obvious what the behaviour should be, so we avoid any
1768							// surprises.
1769							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					// We don't switch state since after a `)`, we are expecting an operator, i.e.
1816					// `..) + 5` rather than `..) 5`.
1817				}
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					// We switch state since after a `[`, we are expecting an operand, i.e.
1863					// `i[5 +..` rather than `i[+..`.
1864					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					// We don't switch state since after a `]`, we are expecting an operator, i.e.
1891					// `..] + 5` instead of `..] 5`.
1892					match self.end_index(span) {
1893						Ok(_) => {}
1894						Err(_) => {
1895							break 'main;
1896						}
1897					}
1898
1899					// After an index `ident[..]` we may have an array constructor.
1900					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					// We switch state since after a `]`, we are expecting an operator, i.e.
1932					// `..[] + 5` rather than `..[] 5`.
1933					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 we previously had a token which can end an argument of an arity group, and we are in a
1941					// delimited arity group, we want to increase the arity, for example:
1942					// `{10, {` or `{10 {` or `{1+1  {`
1943					// but not:
1944					// `a {` or `fn{10 + {`
1945					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					// We don't switch state since after a `{`, we are expecting an operand, i.e.
1967					// `..+ {1,` rather than `..+ {,`.
1968				}
1969				Token::LBrace if state == State::AfterOperand => {
1970					// If we previously had a token which can end an argument of an arity group, and we are in a
1971					// delimited arity group, we want to increase the arity, for example:
1972					// `{10, {` or `{10 {` or `{1+1  {`
1973					// but not:
1974					// `a {` or `fn{10 + {`
1975					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					// We don't switch state since after a `}`, we are expecting an operator, i.e.
2026					// `..}, {..` rather than `..} {..`.
2027				}
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					// This is valid, i.e. `{}`, or `{1, }`.
2041					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					// We switch state since after an init list we are expecting an operator, i.e.
2058					// `..}, {..` rather than `..} {..`.
2059					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					// We switch state since after a comma (which delineates an expression), we're effectively
2084					// starting a new expression which must start with an operand, i.e.
2085					// `.., 5 + 6` instead of `.., + 6`.
2086					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					// This is an error, e.g. `..+ ,` instead of `..+ 1,`.
2101					// We only create this error if there is something before this comma, because if there isn't,
2102					// the list analysis will produce an error anyway, and we don't want two errors for the same
2103					// incorrect syntax.
2104					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					// We don't need to consider arity because a dot after an operand will always be a valid object
2157					// access notation, and in the alternate branch we don't recover from the error.
2158
2159					self.push_operator(Op {
2160						span,
2161						ty: OpTy::ObjAccess(false),
2162					});
2163
2164					// We switch state since after an object access we are execting an operand, such as:
2165					// `foo. bar()`.
2166					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					// We have encountered something like: `foo + . ` or `foo.bar(). . `.
2176					//
2177					// We do not recover from this error because we currently mandate that the `ExprTy::ObjAccess`
2178					// node has a left-hand side.
2179					//
2180					// MAYBE: Should we make this a recoverable situation? (If so we need to consider arity)
2181
2182					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						// We have encountered something like: `foo + ?`.
2193						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					// We switch state since after the `?` we are expecting an operand, such as:
2208					// `foo ? bar`.
2209					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						// We have encountered something like: `foo ? a + :`.
2224						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					// We switch state since after the `:` we are expecting an operand, such as:
2238					// `foo ? bar : baz2`.
2239					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					// We have encountered an unexpected token that's not allowed to be part of an expression.
2249					self.syntax_diags
2250						.push(Syntax::Expr(ExprDiag::FoundInvalidToken(span)));
2251					break 'main;
2252				}
2253			}
2254
2255			// Reset the flag. This is a separate statement because otherwise this assignment would have to be in
2256			// _every_ single branch other than the l_paren branch and this is just cleaner/more maintainable.
2257			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		// Close any open groups. Any groups still open must be missing a closing delimiter.
2270		if !self.groups.is_empty() {
2271			// The end position of this expression will be the end position of the last parsed item.
2272			let group_end = self.get_previous_span().unwrap().end_zero_width();
2273
2274			// We don't take ownership of the groups because the individual `collapse_*()` methods do that.
2275			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					// A list always goes to the end of the expression, so we never increment the counter in the
2285					// main loop for the final expression, hence we must always do it here.
2286					Group::List(count, _) => *count += 1,
2287					_ => {}
2288				}
2289
2290				// After the first iteration, we reset to false because if there are more groups, then they
2291				// definitely have at least one argument.
2292				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		// If there is an open group, then all of the operators will have been already moved as part of the
2341		// collapsing functions. However, if we didn't need to close any groups, we may have leftover operators
2342		// which still need moving.
2343		while let Some(op) = self.operators.pop_back() {
2344			self.stack.push_back(Either::Right(op));
2345		}
2346	}
2347
2348	/// Converts the internal RPN stack into a singular `Expr` node, which contains the entire expression.
2349	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		// Consume the stack from the front. If we have an expression, we move it to the back of a temporary stack.
2358		// If we have an operator, we take the n-most expressions from the back of the temporary stack, process
2359		// them in accordance to the operator type, and then push the result onto the back of the temporary stack.
2360		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							// Panics: `prev` is guaranteed to be a `ExprTy::Ternary` which only has the `cond`,
2560							// `question` and `true_` fields filled in.
2561							_ => 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						// Get the identifier (which is the first expression).
2600						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						// Get the index operator (which is the first expression).
2655						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		// Return the one root expression.
2783		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}