Parses a `DO` statement.
(&mut self, do_pos: LineCol)
| 634 | |
| 635 | /// Parses a `DO` statement. |
| 636 | fn parse_do(&mut self, do_pos: LineCol) -> Result<Statement> { |
| 637 | let pre_guard = self.parse_do_guard("DO")?; |
| 638 | self.expect_and_consume(Token::Eol, "Expecting newline after DO")?; |
| 639 | |
| 640 | let stmts = self.parse_until(Token::Loop)?; |
| 641 | self.expect_and_consume_with_pos(Token::Loop, do_pos, "DO without LOOP")?; |
| 642 | |
| 643 | let post_guard = self.parse_do_guard("LOOP")?; |
| 644 | |
| 645 | let guard = match (pre_guard, post_guard) { |
| 646 | (None, None) => DoGuard::Infinite, |
| 647 | (Some((guard, true)), None) => DoGuard::PreUntil(guard), |
| 648 | (Some((guard, false)), None) => DoGuard::PreWhile(guard), |
| 649 | (None, Some((guard, true))) => DoGuard::PostUntil(guard), |
| 650 | (None, Some((guard, false))) => DoGuard::PostWhile(guard), |
| 651 | (Some(_), Some(_)) => { |
| 652 | return Err(Error::Bad( |
| 653 | do_pos, |
| 654 | "DO loop cannot have pre and post guards at the same time".to_owned(), |
| 655 | )); |
| 656 | } |
| 657 | }; |
| 658 | |
| 659 | Ok(Statement::Do(DoSpan { guard, body: stmts })) |
| 660 | } |
| 661 | |
| 662 | /// Advances until the next statement after failing to parse a `DO` statement. |
| 663 | fn reset_do(&mut self) -> Result<()> { |
no test coverage detected