1use crate::{Parse, ParseBracket, ParseResult, ParseToEnd, Parser, ParserConsumed, Peek};
2
3use sway_ast::brackets::{Braces, Parens, SquareBrackets};
4use sway_ast::expr::{LoopControlFlow, ReassignmentOp, ReassignmentOpVariant};
5use sway_ast::keywords::{
6 AbiToken, AddEqToken, AmpersandToken, AsmToken, CommaToken, ConfigurableToken, ConstToken,
7 DivEqToken, DoubleColonToken, EnumToken, EqToken, FalseToken, FnToken, HashToken, IfToken,
8 ImplToken, LetToken, MutToken, OpenAngleBracketToken, PubToken, SemicolonToken, ShlEqToken,
9 ShrEqToken, StarEqToken, StorageToken, StructToken, SubEqToken, TraitToken, TrueToken,
10 TypeToken, UseToken,
11};
12use sway_ast::literal::{LitBool, LitBoolType};
13use sway_ast::punctuated::Punctuated;
14use sway_ast::token::DocComment;
15use sway_ast::{
16 AbiCastArgs, CodeBlockContents, Expr, ExprArrayDescriptor, ExprStructField,
17 ExprTupleDescriptor, GenericArgs, IfCondition, IfExpr, LitInt, Literal, MatchBranch,
18 MatchBranchKind, PathExpr, PathExprSegment, Statement, StatementLet,
19};
20use sway_error::parser_error::ParseErrorKind;
21use sway_types::{ast::Delimiter, Ident, Span, Spanned};
22
23mod asm;
24pub mod op_code;
25
26impl ParseToEnd for AbiCastArgs {
27 fn parse_to_end<'a, 'e>(
28 mut parser: Parser<'a, '_>,
29 ) -> ParseResult<(AbiCastArgs, ParserConsumed<'a>)> {
30 let name = parser.parse()?;
31 let comma_token = parser.parse()?;
32 let address = parser.parse()?;
33 match parser.check_empty() {
34 Some(consumed) => {
35 let abi_cast_args = AbiCastArgs {
36 name,
37 comma_token,
38 address,
39 };
40 Ok((abi_cast_args, consumed))
41 }
42 None => Err(parser.emit_error(ParseErrorKind::UnexpectedTokenAfterAbiAddress)),
43 }
44 }
45}
46
47impl Parse for IfExpr {
48 fn parse(parser: &mut Parser) -> ParseResult<IfExpr> {
49 let if_token = parser.parse()?;
50 let condition = parser.parse()?;
51 let then_block = parser.parse()?;
52 let else_opt = match parser.take() {
53 Some(else_token) => {
54 let else_body = match parser.guarded_parse::<IfToken, _>()? {
55 Some(if_expr) => LoopControlFlow::Continue(Box::new(if_expr)),
56 None => LoopControlFlow::Break(parser.parse()?),
57 };
58 Some((else_token, else_body))
59 }
60 None => None,
61 };
62 Ok(IfExpr {
63 if_token,
64 condition,
65 then_block,
66 else_opt,
67 })
68 }
69}
70
71impl Parse for IfCondition {
72 fn parse(parser: &mut Parser) -> ParseResult<IfCondition> {
73 if let Some(let_token) = parser.take() {
74 let lhs = parser.parse()?;
75 let eq_token = parser.parse()?;
76 let rhs = Box::new(parse_condition(parser)?);
77 Ok(IfCondition::Let {
78 let_token,
79 lhs,
80 eq_token,
81 rhs,
82 })
83 } else {
84 let expr = Box::new(parse_condition(parser)?);
85 Ok(IfCondition::Expr(expr))
86 }
87 }
88}
89
90impl Parse for Expr {
91 fn parse(parser: &mut Parser) -> ParseResult<Expr> {
92 parse_reassignment(parser, ParseExprCtx::default())
93 }
94}
95
96impl Parse for StatementLet {
97 fn parse(parser: &mut Parser) -> ParseResult<Self> {
98 let let_token: LetToken = parser.parse()?;
99
100 if parser.peek::<EqToken>().is_some() {
101 return Err(parser.emit_error_with_span(
102 ParseErrorKind::ExpectedPattern,
103 let_token
104 .span()
105 .next_char_utf8()
106 .unwrap_or_else(|| let_token.span()),
107 ));
108 }
109 let pattern = parser.try_parse(true)?;
110
111 let ty_opt = match parser.take() {
112 Some(colon_token) => Some((colon_token, parser.parse()?)),
113 None => None,
114 };
115 let eq_token: EqToken = parser.try_parse(true)?;
116 let expr = parser.try_parse(true)?;
117
118 let semicolon_token = parser.try_parse(true)?;
120
121 Ok(StatementLet {
122 let_token,
123 pattern,
124 ty_opt,
125 eq_token,
126 expr,
127 semicolon_token,
128 })
129 }
130}
131
132impl ParseToEnd for CodeBlockContents {
133 fn parse_to_end<'a, 'e>(
134 mut parser: Parser<'a, '_>,
135 ) -> ParseResult<(CodeBlockContents, ParserConsumed<'a>)> {
136 let mut statements = Vec::new();
137
138 let (final_expr_opt, consumed) = loop {
139 if let Some(consumed) = parser.check_empty() {
140 break (None, consumed);
141 }
142
143 match parser.call_parsing_function_with_recovery(parse_stmt) {
144 Ok(StmtOrTail::Stmt(s)) => statements.push(s),
145 Ok(StmtOrTail::Tail(e, c)) => break (Some(e), c),
146 Err(r) => {
147 let (spans, error) = r
148 .recover_at_next_line_with_fallback_error(ParseErrorKind::InvalidStatement);
149 statements.push(Statement::Error(spans, error));
150 }
151 }
152 };
153
154 let code_block_contents = CodeBlockContents {
155 statements,
156 final_expr_opt,
157 span: parser.full_span().clone(),
158 };
159
160 Ok((code_block_contents, consumed))
161 }
162}
163
164#[allow(clippy::large_enum_variant)]
166enum StmtOrTail<'a> {
167 Stmt(Statement),
169 Tail(Box<Expr>, ParserConsumed<'a>),
171}
172
173fn parse_stmt<'a>(parser: &mut Parser<'a, '_>) -> ParseResult<StmtOrTail<'a>> {
175 let stmt = |s| Ok(StmtOrTail::Stmt(s));
176
177 if parser.peek::<UseToken>().is_some()
179 || parser.peek::<StructToken>().is_some()
180 || parser.peek::<EnumToken>().is_some()
181 || parser.peek::<FnToken>().is_some()
182 || parser.peek::<PubToken>().is_some()
183 || parser.peek::<TraitToken>().is_some()
184 || parser.peek::<ImplToken>().is_some()
185 || parser.peek::<(AbiToken, Ident)>().is_some()
186 || parser.peek::<ConstToken>().is_some()
187 || parser.peek::<TypeToken>().is_some()
188 || parser.peek::<DocComment>().is_some()
189 || parser.peek::<HashToken>().is_some()
190 || matches!(
191 parser.peek::<(StorageToken, Delimiter)>(),
192 Some((_, Delimiter::Brace))
193 )
194 || matches!(
195 parser.peek::<(ConfigurableToken, Delimiter)>(),
196 Some((_, Delimiter::Brace))
197 )
198 {
199 return stmt(Statement::Item(parser.parse()?));
200 }
201
202 if let Some(item) = parser.guarded_parse::<LetToken, StatementLet>()? {
204 return stmt(Statement::Let(item));
205 }
206
207 let expr = parse_statement_expr(parser)?;
209 if let Some(semicolon_token) = parser.take() {
210 return stmt(Statement::Expr {
211 expr,
212 semicolon_token_opt: Some(semicolon_token),
213 });
214 }
215
216 if let Some(consumed) = parser.check_empty() {
218 return Ok(StmtOrTail::Tail(Box::new(expr), consumed));
219 }
220
221 if expr.is_control_flow() {
224 return stmt(Statement::Expr {
225 expr,
226 semicolon_token_opt: None,
227 });
228 }
229
230 Err(parser.emit_error(ParseErrorKind::UnexpectedTokenInStatement))
231}
232
233#[derive(Clone, Copy, Debug, Default)]
234struct ParseExprCtx {
235 pub parsing_conditional: bool,
236 pub at_start_of_statement: bool,
237}
238
239impl ParseExprCtx {
240 pub fn not_statement(self) -> ParseExprCtx {
241 ParseExprCtx {
242 at_start_of_statement: false,
243 ..self
244 }
245 }
246}
247
248fn parse_condition(parser: &mut Parser) -> ParseResult<Expr> {
249 let ctx = ParseExprCtx {
250 parsing_conditional: true,
251 at_start_of_statement: false,
252 };
253 parse_reassignment(parser, ctx)
254}
255
256fn parse_statement_expr(parser: &mut Parser) -> ParseResult<Expr> {
257 let ctx = ParseExprCtx {
258 parsing_conditional: false,
259 at_start_of_statement: true,
260 };
261 parse_reassignment(parser, ctx)
262}
263
264fn take_reassignment_op(parser: &mut Parser) -> Option<ReassignmentOp> {
266 let (variant, span) = if let Some(add_eq_token) = parser.take::<AddEqToken>() {
267 (ReassignmentOpVariant::AddEquals, add_eq_token.span())
268 } else if let Some(sub_eq_token) = parser.take::<SubEqToken>() {
269 (ReassignmentOpVariant::SubEquals, sub_eq_token.span())
270 } else if let Some(mul_eq_token) = parser.take::<StarEqToken>() {
271 (ReassignmentOpVariant::MulEquals, mul_eq_token.span())
272 } else if let Some(div_eq_token) = parser.take::<DivEqToken>() {
273 (ReassignmentOpVariant::DivEquals, div_eq_token.span())
274 } else if let Some(shl_eq_token) = parser.take::<ShlEqToken>() {
275 (ReassignmentOpVariant::ShlEquals, shl_eq_token.span())
276 } else if let Some(shr_eq_token) = parser.take::<ShrEqToken>() {
277 (ReassignmentOpVariant::ShrEquals, shr_eq_token.span())
278 } else if let Some(eq_token) = parser.take::<EqToken>() {
279 (ReassignmentOpVariant::Equals, eq_token.span())
280 } else {
281 return None;
282 };
283 Some(ReassignmentOp { variant, span })
284}
285
286fn parse_reassignment(parser: &mut Parser, ctx: ParseExprCtx) -> ParseResult<Expr> {
287 let expr = parse_logical_or(parser, ctx)?;
288 let expr_span = expr.span();
289
290 if let Some(reassignment_op) = take_reassignment_op(parser) {
291 let assignable = match expr.try_into_assignable() {
292 Ok(assignable) => assignable,
293 Err(expr) => {
294 let span = expr.span();
295 return Err(parser.emit_error_with_span(
296 ParseErrorKind::UnassignableExpression {
297 erroneous_expression_kind: expr.friendly_name(),
298 erroneous_expression_span: span,
299 },
300 expr_span,
301 ));
302 }
303 };
304 let expr = Box::new(parse_reassignment(parser, ctx.not_statement())?);
305 return Ok(Expr::Reassignment {
306 assignable,
307 reassignment_op,
308 expr,
309 });
310 }
311 Ok(expr)
312}
313
314fn parse_op_rhs<O: Peek>(
315 parser: &mut Parser,
316 ctx: ParseExprCtx,
317 sub: impl Fn(&mut Parser, ParseExprCtx) -> ParseResult<Expr>,
318) -> ParseResult<Option<(O, Box<Expr>)>> {
319 if let Some(op_token) = parser.take() {
320 let rhs = Box::new(sub(parser, ctx.not_statement())?);
321 return Ok(Some((op_token, rhs)));
322 }
323 Ok(None)
324}
325
326fn parse_binary<O: Peek>(
327 parser: &mut Parser,
328 ctx: ParseExprCtx,
329 sub: impl Fn(&mut Parser, ParseExprCtx) -> ParseResult<Expr>,
330 combine: impl Fn(Box<Expr>, Box<Expr>, O) -> Expr,
331) -> ParseResult<Expr> {
332 let mut expr = sub(parser, ctx)?;
333 if expr.is_control_flow() && ctx.at_start_of_statement {
334 return Ok(expr);
335 }
336 while let Some((op_token, rhs)) = parse_op_rhs(parser, ctx, &sub)? {
337 expr = combine(Box::new(expr), rhs, op_token);
338 }
339 Ok(expr)
340}
341
342fn parse_logical_or(parser: &mut Parser, ctx: ParseExprCtx) -> ParseResult<Expr> {
343 let combine = |lhs, rhs, double_pipe_token| Expr::LogicalOr {
344 lhs,
345 double_pipe_token,
346 rhs,
347 };
348 parse_binary(parser, ctx, parse_logical_and, combine)
349}
350
351fn parse_logical_and(parser: &mut Parser, ctx: ParseExprCtx) -> ParseResult<Expr> {
352 let combine = |lhs, rhs, double_ampersand_token| Expr::LogicalAnd {
353 lhs,
354 double_ampersand_token,
355 rhs,
356 };
357 parse_binary(parser, ctx, parse_comparison, combine)
358}
359
360fn parse_comparison(parser: &mut Parser, ctx: ParseExprCtx) -> ParseResult<Expr> {
361 let expr = parse_bit_or(parser, ctx)?;
362 let expr = if expr.is_control_flow() && ctx.at_start_of_statement {
363 expr
364 } else if let Some((double_eq_token, rhs)) = parse_op_rhs(parser, ctx, parse_bit_or)? {
365 Expr::Equal {
366 lhs: Box::new(expr),
367 double_eq_token,
368 rhs,
369 }
370 } else if let Some((bang_eq_token, rhs)) = parse_op_rhs(parser, ctx, parse_bit_or)? {
371 Expr::NotEqual {
372 lhs: Box::new(expr),
373 bang_eq_token,
374 rhs,
375 }
376 } else if let Some((less_than_token, rhs)) = parse_op_rhs(parser, ctx, parse_bit_or)? {
377 Expr::LessThan {
378 lhs: Box::new(expr),
379 less_than_token,
380 rhs,
381 }
382 } else if let Some((greater_than_token, rhs)) = parse_op_rhs(parser, ctx, parse_bit_or)? {
383 Expr::GreaterThan {
384 lhs: Box::new(expr),
385 greater_than_token,
386 rhs,
387 }
388 } else if let Some((less_than_eq_token, rhs)) = parse_op_rhs(parser, ctx, parse_bit_or)? {
389 Expr::LessThanEq {
390 lhs: Box::new(expr),
391 less_than_eq_token,
392 rhs,
393 }
394 } else if let Some((greater_than_eq_token, rhs)) = parse_op_rhs(parser, ctx, parse_bit_or)? {
395 Expr::GreaterThanEq {
396 lhs: Box::new(expr),
397 greater_than_eq_token,
398 rhs,
399 }
400 } else {
401 expr
402 };
403 Ok(expr)
404}
405
406fn parse_bit_or(parser: &mut Parser, ctx: ParseExprCtx) -> ParseResult<Expr> {
407 let combine = |lhs, rhs, pipe_token| Expr::BitOr {
408 lhs,
409 pipe_token,
410 rhs,
411 };
412 parse_binary(parser, ctx, parse_bit_xor, combine)
413}
414
415fn parse_bit_xor(parser: &mut Parser, ctx: ParseExprCtx) -> ParseResult<Expr> {
416 let combine = |lhs, rhs, caret_token| Expr::BitXor {
417 lhs,
418 caret_token,
419 rhs,
420 };
421 parse_binary(parser, ctx, parse_bit_and, combine)
422}
423
424fn parse_bit_and(parser: &mut Parser, ctx: ParseExprCtx) -> ParseResult<Expr> {
425 let combine = |lhs, rhs, ampersand_token| Expr::BitAnd {
426 lhs,
427 ampersand_token,
428 rhs,
429 };
430 parse_binary(parser, ctx, parse_shift, combine)
431}
432
433fn parse_shift(parser: &mut Parser, ctx: ParseExprCtx) -> ParseResult<Expr> {
434 let mut expr = parse_add(parser, ctx)?;
435 if expr.is_control_flow() && ctx.at_start_of_statement {
436 return Ok(expr);
437 }
438 loop {
439 expr = if let Some((shl_token, rhs)) = parse_op_rhs(parser, ctx, parse_add)? {
440 Expr::Shl {
441 lhs: Box::new(expr),
442 shl_token,
443 rhs,
444 }
445 } else if let Some((shr_token, rhs)) = parse_op_rhs(parser, ctx, parse_add)? {
446 Expr::Shr {
447 lhs: Box::new(expr),
448 shr_token,
449 rhs,
450 }
451 } else {
452 return Ok(expr);
453 };
454 }
455}
456
457fn parse_add(parser: &mut Parser, ctx: ParseExprCtx) -> ParseResult<Expr> {
458 let mut expr = parse_mul(parser, ctx)?;
459 if expr.is_control_flow() && ctx.at_start_of_statement {
460 return Ok(expr);
461 }
462 loop {
463 expr = if let Some((add_token, rhs)) = parse_op_rhs(parser, ctx, parse_mul)? {
464 Expr::Add {
465 lhs: Box::new(expr),
466 add_token,
467 rhs,
468 }
469 } else if let Some((sub_token, rhs)) = parse_op_rhs(parser, ctx, parse_mul)? {
470 Expr::Sub {
471 lhs: Box::new(expr),
472 sub_token,
473 rhs,
474 }
475 } else {
476 return Ok(expr);
477 };
478 }
479}
480
481fn parse_mul(parser: &mut Parser, ctx: ParseExprCtx) -> ParseResult<Expr> {
482 let mut expr = parse_unary_op(parser, ctx)?;
483 if expr.is_control_flow() && ctx.at_start_of_statement {
484 return Ok(expr);
485 }
486 loop {
487 expr = if let Some((double_star_token, rhs)) = parse_op_rhs(parser, ctx, parse_unary_op)? {
488 Expr::Pow {
489 lhs: Box::new(expr),
490 double_star_token,
491 rhs,
492 }
493 } else if let Some((star_token, rhs)) = parse_op_rhs(parser, ctx, parse_unary_op)? {
494 Expr::Mul {
495 lhs: Box::new(expr),
496 star_token,
497 rhs,
498 }
499 } else if let Some((forward_slash_token, rhs)) = parse_op_rhs(parser, ctx, parse_unary_op)?
500 {
501 Expr::Div {
502 lhs: Box::new(expr),
503 forward_slash_token,
504 rhs,
505 }
506 } else if let Some((percent_token, rhs)) = parse_op_rhs(parser, ctx, parse_unary_op)? {
507 Expr::Modulo {
508 lhs: Box::new(expr),
509 percent_token,
510 rhs,
511 }
512 } else {
513 return Ok(expr);
514 };
515 }
516}
517
518fn parse_unary_op(parser: &mut Parser, ctx: ParseExprCtx) -> ParseResult<Expr> {
519 if let Some((ampersand_token, mut_token, expr)) = parse_referencing(parser, ctx)? {
520 return Ok(Expr::Ref {
521 ampersand_token,
522 mut_token,
523 expr,
524 });
525 }
526 if let Some((star_token, expr)) = parse_op_rhs(parser, ctx, parse_unary_op)? {
527 return Ok(Expr::Deref { star_token, expr });
528 }
529 if let Some((bang_token, expr)) = parse_op_rhs(parser, ctx, parse_unary_op)? {
530 return Ok(Expr::Not { bang_token, expr });
531 }
532 return parse_projection(parser, ctx);
533
534 #[allow(clippy::type_complexity)] fn parse_referencing(
536 parser: &mut Parser,
537 ctx: ParseExprCtx,
538 ) -> ParseResult<Option<(AmpersandToken, Option<MutToken>, Box<Expr>)>> {
539 if let Some(ampersand_token) = parser.take() {
540 let mut_token = parser.take::<MutToken>();
541 let expr = Box::new(parse_unary_op(parser, ctx.not_statement())?);
542 return Ok(Some((ampersand_token, mut_token, expr)));
543 }
544 Ok(None)
545 }
546}
547
548fn parse_projection(parser: &mut Parser, ctx: ParseExprCtx) -> ParseResult<Expr> {
549 let mut expr = parse_func_app(parser, ctx)?;
550 loop {
551 if let Some(arg) = SquareBrackets::try_parse_all_inner(parser, |mut parser| {
552 parser.emit_error(ParseErrorKind::UnexpectedTokenAfterArrayIndex)
553 })? {
554 let target = Box::new(expr);
555 expr = Expr::Index { target, arg };
556 continue;
557 }
558 if let Some(dot_token) = parser.take() {
559 let target = Box::new(expr);
560
561 if let Some(path_seg) = parser.guarded_parse::<Ident, PathExprSegment>()? {
563 if !ctx.parsing_conditional {
564 if let Some(contract_args) = Braces::try_parse(parser)? {
565 expr = Expr::MethodCall {
566 target,
567 dot_token,
568 path_seg,
569 contract_args_opt: Some(contract_args),
570 args: Parens::parse(parser)?,
571 };
572 continue;
573 }
574 }
575 if let Some(args) = Parens::try_parse(parser)? {
576 expr = Expr::MethodCall {
577 target,
578 dot_token,
579 path_seg,
580 contract_args_opt: None,
581 args,
582 };
583 continue;
584 }
585
586 ensure_field_projection_no_generics(parser, &path_seg.generics_opt);
588 expr = Expr::FieldProjection {
589 target,
590 dot_token,
591 name: path_seg.name,
592 };
593 continue;
594 }
595
596 if let Some(lit) = parser.take() {
598 let lit_int = match lit {
599 Literal::Int(lit_int) => lit_int,
600 _ => {
601 let span = lit.span();
602 return Err(parser
603 .emit_error_with_span(ParseErrorKind::InvalidLiteralFieldName, span));
604 }
605 };
606 let LitInt {
607 span,
608 parsed,
609 ty_opt,
610 is_generated_b256: _,
611 } = lit_int;
612 if ty_opt.is_some() {
613 return Err(
614 parser.emit_error_with_span(ParseErrorKind::IntFieldWithTypeSuffix, span)
615 );
616 }
617 let field = parsed;
618 let field_span = span;
619 expr = Expr::TupleFieldProjection {
620 target,
621 dot_token,
622 field,
623 field_span,
624 };
625 continue;
626 }
627
628 let err = parser.emit_error(ParseErrorKind::ExpectedFieldName);
631 return Ok(Expr::Error([target.span(), dot_token.span()].into(), err));
632 }
633 return Ok(expr);
634 }
635}
636
637fn ensure_field_projection_no_generics(
639 parser: &mut Parser,
640 generic_args: &Option<(DoubleColonToken, GenericArgs)>,
641) {
642 if let Some((dct, generic_args)) = generic_args {
643 let span = Span::join(dct.span(), &generic_args.span());
644 parser.emit_error_with_span(ParseErrorKind::FieldProjectionWithGenericArgs, span);
645 }
646}
647
648fn parse_func_app(parser: &mut Parser, ctx: ParseExprCtx) -> ParseResult<Expr> {
649 let mut expr = parse_atom(parser, ctx)?;
650 if expr.is_control_flow() && ctx.at_start_of_statement {
651 return Ok(expr);
652 }
653 while let Some(args) = Parens::try_parse(parser)? {
654 let func = Box::new(expr);
655 expr = Expr::FuncApp { func, args };
656 }
657 Ok(expr)
658}
659
660fn parse_atom(parser: &mut Parser, ctx: ParseExprCtx) -> ParseResult<Expr> {
661 if let Some(code_block_inner) = Braces::try_parse(parser)? {
662 return Ok(Expr::Block(code_block_inner));
663 }
664 if let Some(array_inner) = SquareBrackets::try_parse(parser)? {
665 return Ok(Expr::Array(array_inner));
666 }
667 if let Some((mut parser, span)) = parser.enter_delimited(Delimiter::Parenthesis) {
668 if let Some(_consumed) = parser.check_empty() {
669 return Ok(Expr::Tuple(Parens::new(ExprTupleDescriptor::Nil, span)));
670 }
671 let head = parser.parse()?;
672 if let Some(comma_token) = parser.take() {
673 let (tail, _consumed) = parser.parse_to_end()?;
674 let tuple = ExprTupleDescriptor::Cons {
675 head,
676 comma_token,
677 tail,
678 };
679 return Ok(Expr::Tuple(Parens::new(tuple, span)));
680 }
681 if let Some(_consumed) = parser.check_empty() {
682 return Ok(Expr::Parens(Parens::new(head, span)));
683 }
684 return Err(
685 parser.emit_error(ParseErrorKind::ExpectedCommaOrCloseParenInTupleOrParenExpression)
686 );
687 }
688
689 let lit_bool = |span, kind| Ok(Expr::Literal(Literal::Bool(LitBool { span, kind })));
690 if let Some(ident) = parser.take::<TrueToken>() {
691 return lit_bool(ident.span(), LitBoolType::True);
692 }
693 if let Some(ident) = parser.take::<FalseToken>() {
694 return lit_bool(ident.span(), LitBoolType::False);
695 }
696 if let Some(asm_block) = parser.guarded_parse::<AsmToken, _>()? {
697 return Ok(Expr::Asm(asm_block));
698 }
699 if let Some(break_token) = parser.take() {
700 return Ok(Expr::Break { break_token });
701 }
702 if let Some(continue_token) = parser.take() {
703 return Ok(Expr::Continue { continue_token });
704 }
705 if let Some(abi_token) = parser.take() {
706 let args = parser.parse()?;
707 return Ok(Expr::AbiCast { abi_token, args });
708 }
709 if let Some(return_token) = parser.take() {
710 if parser.is_empty()
711 || parser.peek::<CommaToken>().is_some()
712 || parser.peek::<SemicolonToken>().is_some()
713 {
714 return Ok(Expr::Return {
715 return_token,
716 expr_opt: None,
717 });
718 }
719 let expr = parser.parse()?;
720 return Ok(Expr::Return {
721 return_token,
722 expr_opt: Some(expr),
723 });
724 }
725 if let Some(panic_token) = parser.take() {
726 if parser.is_empty()
727 || parser.peek::<CommaToken>().is_some()
728 || parser.peek::<SemicolonToken>().is_some()
729 {
730 return Ok(Expr::Panic {
731 panic_token,
732 expr_opt: None,
733 });
734 }
735 let expr = parser.parse()?;
736 return Ok(Expr::Panic {
737 panic_token,
738 expr_opt: Some(expr),
739 });
740 }
741 if let Some(if_expr) = parser.guarded_parse::<IfToken, _>()? {
742 return Ok(Expr::If(if_expr));
743 }
744 if let Some(match_token) = parser.take() {
745 let condition = Box::new(parse_condition(parser)?);
746 let branches = parser.parse()?;
747 return Ok(Expr::Match {
748 match_token,
749 value: condition,
750 branches,
751 });
752 }
753 if let Some(while_token) = parser.take() {
754 let condition = Box::new(parse_condition(parser)?);
755 let block = parser.parse()?;
756 return Ok(Expr::While {
757 while_token,
758 condition,
759 block,
760 });
761 }
762 if let Some(for_token) = parser.take() {
763 let value_pattern = parser.parse()?;
764 let in_token = parser.parse()?;
765 let iterator = Box::new(parse_condition(parser)?);
766 let block = parser.parse()?;
767 return Ok(Expr::For {
768 for_token,
769 value_pattern,
770 in_token,
771 iterator,
772 block,
773 });
774 }
775 if parser.peek::<OpenAngleBracketToken>().is_some()
776 || parser.peek::<DoubleColonToken>().is_some()
777 || parser.peek::<Ident>().is_some()
778 {
779 let path: PathExpr = parser.parse()?;
780 if path.incomplete_suffix {
781 return Ok(Expr::Error(
785 [path.span()].into(),
786 parser.emit_error(ParseErrorKind::ExpectedPathType),
787 ));
788 }
789 if !ctx.parsing_conditional {
790 if let Some(fields) = Braces::try_parse(parser)? {
791 return Ok(Expr::Struct { path, fields });
792 }
793 };
794 return Ok(Expr::Path(path));
795 }
796 if let Some(literal) = parser.take() {
797 return Ok(Expr::Literal(literal));
798 }
799 Err(parser.emit_error(ParseErrorKind::ExpectedExpression))
800}
801
802impl Parse for ExprStructField {
803 fn parse(parser: &mut Parser) -> ParseResult<ExprStructField> {
804 let field_name = parser.parse()?;
805 let expr_opt = match parser.take() {
806 Some(colon_token) => {
807 let expr = parser.parse()?;
808 Some((colon_token, expr))
809 }
810 None => None,
811 };
812 Ok(ExprStructField {
813 field_name,
814 expr_opt,
815 })
816 }
817}
818
819impl ParseToEnd for ExprArrayDescriptor {
820 fn parse_to_end<'a, 'e>(
821 mut parser: Parser<'a, '_>,
822 ) -> ParseResult<(ExprArrayDescriptor, ParserConsumed<'a>)> {
823 if let Some(consumed) = parser.check_empty() {
824 let punctuated = Punctuated::empty();
825 let descriptor = ExprArrayDescriptor::Sequence(punctuated);
826 return Ok((descriptor, consumed));
827 }
828 let value = parser.parse()?;
829 if let Some(semicolon_token) = parser.take() {
830 let length = parser.parse()?;
831 let consumed = match parser.check_empty() {
832 Some(consumed) => consumed,
833 None => {
834 return Err(parser.emit_error(ParseErrorKind::UnexpectedTokenAfterArrayLength));
835 }
836 };
837 let descriptor = ExprArrayDescriptor::Repeat {
838 value: Box::new(value),
839 semicolon_token,
840 length,
841 };
842 return Ok((descriptor, consumed));
843 }
844 if let Some(comma_token) = parser.take() {
845 let (mut punctuated, consumed): (Punctuated<_, _>, _) = parser.parse_to_end()?;
846 punctuated
847 .value_separator_pairs
848 .insert(0, (value, comma_token));
849 let descriptor = ExprArrayDescriptor::Sequence(punctuated);
850 return Ok((descriptor, consumed));
851 }
852 if let Some(consumed) = parser.check_empty() {
853 let punctuated = Punctuated::single(value);
854 let descriptor = ExprArrayDescriptor::Sequence(punctuated);
855 return Ok((descriptor, consumed));
856 }
857 Err(parser.emit_error(ParseErrorKind::ExpectedCommaSemicolonOrCloseBracketInArray))
858 }
859}
860
861impl Parse for MatchBranch {
862 fn parse(parser: &mut Parser) -> ParseResult<MatchBranch> {
863 let pattern = parser.parse()?;
864 let fat_right_arrow_token = parser.parse()?;
865 let kind = parser.parse()?;
866 Ok(MatchBranch {
867 pattern,
868 fat_right_arrow_token,
869 kind,
870 })
871 }
872}
873
874impl Parse for MatchBranchKind {
875 fn parse(parser: &mut Parser) -> ParseResult<MatchBranchKind> {
876 if let Some(block) = Braces::try_parse(parser)? {
877 return Ok(MatchBranchKind::Block {
878 block,
879 comma_token_opt: parser.take(),
880 });
881 }
882 let expr = parser.parse()?;
883 let comma_token = parser.parse()?;
884 Ok(MatchBranchKind::Expr { expr, comma_token })
885 }
886}