/// Parses a list of statements, stopping when the given closure returns true. The final token is not consumed.
Parses a list of statements, stopping when the given closure returns true. The final token is not consumed.
Parses a list of statements stopping when the given closure returns true . The final token is not consumed .
fn parse_stmt_list(&mut self, ctx: &mut ErrorContext, end_list: impl Fn(&Token) -> bool) -> ParseResult<StmtList> {
        ctx.push(ContextTag::StmtList);
        let mut suite = Vec::new();
        let mut control = None;
        debug!("enter stmt list at index {}...", self.current_index());
        loop {
            // statement separators
            while matches!(self.peek()?.token, Token::Semicolon) {
                ctx.set_end(&self.advance().unwrap());
            }
            let next = self.peek()?;
            if end_list(&next.token) {
                break;
            }
            let parse_result = self.try_parse_control_flow(ctx);
            control = match self.catch_error_and_sync(ctx, parse_result, true) {
                Some(result) => result?,
                None => continue,
            };
            // if we found a control flow statement, it must be the last item in the statement list
            if let Some(control) = control.as_ref() {
                let next = self.peek()?;
                if !end_list(&next.token) {
                    // consume the unexpected token so that it is included in the error message
                    ctx.set_end(&self.advance().unwrap());
                    let name = match control {
                        ControlFlow::Continue {..} => "continue",
                        ControlFlow::Break {..} => "break",
                        ControlFlow::Return {..} => "return",
                    };
                    let message = format!("\"{}\" must be the last statement in a block", name);
                    let error = ParserError::from(ErrorKind::SyntaxError(message))
                        .with_symbol_from_ctx(ctx);
                    self.errors.push_back(error);
                }
                break;
            }
            let parse_result = self.parse_stmt(ctx);
            let stmt = match self.catch_error_and_sync(ctx, parse_result, true) {
                Some(result) => result?,
                None => continue,
            };
            suite.push(stmt);
        }
        debug!("exit stmt list at {}...", self.current_index());
        ctx.pop_extend();
        Ok(StmtList::new(suite, control))
    }
fn parse_stmt_list ( & mut self , ctx : & mut ErrorContext , end_list : impl Fn ( & Token ) -> bool ) -> ParseResult < StmtList > { ctx . push ( ContextTag :: StmtList ) ; let mut suite = Vec :: new ( ) ; let mut control = None ; debug ! ( " " self current_index ( ) ) ; loop { // statement separators while matches ! ( self peek ( ) token Token Semicolon ) { ctx . set_end ( & self . advance ( ) . unwrap ( ) ) ; } let next = self . peek ( ) ? ; if end_list ( & next . token ) { break ; } let parse_result = self . try_parse_control_flow ( ctx ) ; control = match self . catch_error_and_sync ( ctx , parse_result , true ) { Some ( result ) => result ? , None => continue , } ; // if we found a control flow statement, it must be the last item in the statement list if let Some ( control ) = control . as_ref ( ) { let next = self . peek ( ) ? ; if ! end_list ( & next . token ) { // consume the unexpected token so that it is included in the error message ctx . set_end ( & self . advance ( ) . unwrap ( ) ) ; let name = match control { ControlFlow :: Continue { .. } => " " , ControlFlow :: Break { .. } => " " , ControlFlow :: Return { .. } => " " , } ; let message = format ! ( " \" \" " name ) ; let error = ParserError :: from ( ErrorKind :: SyntaxError ( message ) ) . with_symbol_from_ctx ( ctx ) ; self . errors . push_back ( error ) ; } break ; } let parse_result = self . parse_stmt ( ctx ) ; let stmt = match self . catch_error_and_sync ( ctx , parse_result , true ) { Some ( result ) => result ? , None => continue , } ; suite . push ( stmt ) ; } debug ! ( " " self current_index ( ) ) ; ctx . pop_extend ( ) ; Ok ( StmtList :: new ( suite , control ) ) }
Parses a list of statements, stopping when the given closure returns true.
Parses a list of statements stopping when the given closure returns true .
&mut self
ctx
&mut ErrorContext
end_list
impl Fn(&Token) -> bool