/// Parse a sequential or concurrent statement.
Parse a sequential or concurrent statement.
Parse a sequential or concurrent statement .
pub fn parse_stmt<P: Parser>(p: &mut P) -> ReportedResult<ast::Stmt> {
    let mut span = p.peek(0).span;
    // Parse the leading statement label, if any.
    let label = try_label(p);
    // Handle the simple cases where the statement is clearly identified and
    // introduced by a keyword. Otherwise try the more complex cases introduced
    // by a name or parenthesized expression (aggregate).
    let data = match p.peek(0).value {
        Keyword(Kw::Wait) => parse_wait_stmt(p)?,
        Keyword(Kw::Assert) => parse_assert_stmt(p)?,
        Keyword(Kw::Report) => parse_report_stmt(p)?,
        // For the if statement, check if the `generate` or the `then` keyword
        // occurs earlier. This allows us to determine whether we should parse a
        // generate or regular statement.
        Keyword(Kw::If) => match earliest(
            p,
            &[Keyword(Kw::Generate), Keyword(Kw::Then), Keyword(Kw::End)],
        )
        .value
        {
            Keyword(Kw::Generate) => parse_if_generate_stmt(p, label)?,
            _ => parse_if_stmt(p, label)?,
        },
        // For the case statement, check if the `generate` or the `is` keyword
        // occurs earlier. This allows us to determine whether we should parse a
        // generate or regular statement.
        Keyword(Kw::Case) => match earliest(
            p,
            &[Keyword(Kw::Generate), Keyword(Kw::Is), Keyword(Kw::End)],
        )
        .value
        {
            Keyword(Kw::Generate) => parse_case_generate_stmt(p, label)?,
            _ => parse_case_stmt(p, label)?,
        },
        // For the loop statements, check if the `generate` or the `loop`
        // keyword occurs earlier. This allows us to determine whether we should
        // parse a generate or a regular statement.
        Keyword(Kw::For) => match earliest(
            p,
            &[Keyword(Kw::Generate), Keyword(Kw::Loop), Keyword(Kw::End)],
        )
        .value
        {
            Keyword(Kw::Generate) => parse_for_generate_stmt(p, label)?,
            _ => parse_loop_stmt(p, label)?,
        },
        Keyword(Kw::While) | Keyword(Kw::Loop) => parse_loop_stmt(p, label)?,
        Keyword(Kw::Next) | Keyword(Kw::Exit) => parse_nexit_stmt(p)?,
        Keyword(Kw::Return) => parse_return_stmt(p)?,
        Keyword(Kw::Null) => parse_null_stmt(p)?,
        Keyword(Kw::Block) => parse_block_stmt(p, label)?,
        Keyword(Kw::Process) => parse_proc_stmt(p, label)?,
        Keyword(Kw::With) => parse_select_assign(p)?,
        Keyword(Kw::Component) | Keyword(Kw::Entity) | Keyword(Kw::Configuration) => {
            let target = match p.peek(0).value {
                Keyword(Kw::Component) => ast::InstTarget::Comp,
                Keyword(Kw::Entity) => ast::InstTarget::Entity,
                Keyword(Kw::Configuration) => ast::InstTarget::Cfg,
                _ => unreachable!(),
            };
            p.bump();
            let name = parse_name(p)?;
            parse_inst_or_call_tail(p, Some(target), name)?
        }
        wrong => {
            if let Some(name) = try_name(p)? {
                // Try to parse a statement that begins with a name.
                let span = name.span;
                match p.peek(0).value {
                    Leq | VarAssign => {
                        parse_assign_tail(p, Spanned::new(ast::AssignTarget::Name(name), span))?
                    }
                    _ => parse_inst_or_call_tail(p, None, name)?,
                }
            } else if let Some(expr) = try_paren_expr(p)? {
                // Try to parse a statement that begins with a parenthesized
                // expression, aka an assignment.
                let span = expr.span;
                parse_assign_tail(p, Spanned::new(ast::AssignTarget::Aggregate(expr), span))?
            } else {
                // If we get here, nothing matched, so throw an error.
                let q = p.peek(0).span;
                p.emit(
                    DiagBuilder2::error(format!("Expected statement, found {} instead", wrong))
                        .span(q)
                        .add_note("see IEEE 1076-2008 section 10"),
                );
                return Err(Reported);
            }
        }
    };
    span.expand(p.last_span());
    Ok(ast::Stmt {
        id: Default::default(),
        span: span,
        label: label,
        data: data,
    })
}
pub fn parse_stmt < P : Parser > ( p : & mut P ) -> ReportedResult < ast :: Stmt > { let mut span = p . peek ( 0 ) . span ; // Parse the leading statement label, if any. let label = try_label ( p ) ; // Handle the simple cases where the statement is clearly identified and // introduced by a keyword. Otherwise try the more complex cases introduced // by a name or parenthesized expression (aggregate). let data = match p . peek ( 0 ) . value { Keyword ( Kw :: Wait ) => parse_wait_stmt ( p ) ? , Keyword ( Kw :: Assert ) => parse_assert_stmt ( p ) ? , Keyword ( Kw :: Report ) => parse_report_stmt ( p ) ? , // For the if statement, check if the `generate` or the `then` keyword // occurs earlier. This allows us to determine whether we should parse a // generate or regular statement. Keyword ( Kw :: If ) => match earliest ( p , & [ Keyword ( Kw :: Generate ) , Keyword ( Kw :: Then ) , Keyword ( Kw :: End ) ] , ) . value { Keyword ( Kw :: Generate ) => parse_if_generate_stmt ( p , label ) ? , _ => parse_if_stmt ( p , label ) ? , } , // For the case statement, check if the `generate` or the `is` keyword // occurs earlier. This allows us to determine whether we should parse a // generate or regular statement. Keyword ( Kw :: Case ) => match earliest ( p , & [ Keyword ( Kw :: Generate ) , Keyword ( Kw :: Is ) , Keyword ( Kw :: End ) ] , ) . value { Keyword ( Kw :: Generate ) => parse_case_generate_stmt ( p , label ) ? , _ => parse_case_stmt ( p , label ) ? , } , // For the loop statements, check if the `generate` or the `loop` // keyword occurs earlier. This allows us to determine whether we should // parse a generate or a regular statement. Keyword ( Kw :: For ) => match earliest ( p , & [ Keyword ( Kw :: Generate ) , Keyword ( Kw :: Loop ) , Keyword ( Kw :: End ) ] , ) . value { Keyword ( Kw :: Generate ) => parse_for_generate_stmt ( p , label ) ? , _ => parse_loop_stmt ( p , label ) ? , } , Keyword ( Kw :: While ) | Keyword ( Kw :: Loop ) => parse_loop_stmt ( p , label ) ? , Keyword ( Kw :: Next ) | Keyword ( Kw :: Exit ) => parse_nexit_stmt ( p ) ? , Keyword ( Kw :: Return ) => parse_return_stmt ( p ) ? , Keyword ( Kw :: Null ) => parse_null_stmt ( p ) ? , Keyword ( Kw :: Block ) => parse_block_stmt ( p , label ) ? , Keyword ( Kw :: Process ) => parse_proc_stmt ( p , label ) ? , Keyword ( Kw :: With ) => parse_select_assign ( p ) ? , Keyword ( Kw :: Component ) | Keyword ( Kw :: Entity ) | Keyword ( Kw :: Configuration ) => { let target = match p . peek ( 0 ) . value { Keyword ( Kw :: Component ) => ast :: InstTarget :: Comp , Keyword ( Kw :: Entity ) => ast :: InstTarget :: Entity , Keyword ( Kw :: Configuration ) => ast :: InstTarget :: Cfg , _ => unreachable ! ( ) , } ; p . bump ( ) ; let name = parse_name ( p ) ? ; parse_inst_or_call_tail ( p , Some ( target ) , name ) ? } wrong => { if let Some ( name ) = try_name ( p ) ? { // Try to parse a statement that begins with a name. let span = name . span ; match p . peek ( 0 ) . value { Leq | VarAssign => { parse_assign_tail ( p , Spanned :: new ( ast :: AssignTarget :: Name ( name ) , span ) ) ? } _ => parse_inst_or_call_tail ( p , None , name ) ? , } } else if let Some ( expr ) = try_paren_expr ( p ) ? { // Try to parse a statement that begins with a parenthesized // expression, aka an assignment. let span = expr . span ; parse_assign_tail ( p , Spanned :: new ( ast :: AssignTarget :: Aggregate ( expr ) , span ) ) ? } else { // If we get here, nothing matched, so throw an error. let q = p . peek ( 0 ) . span ; p . emit ( DiagBuilder2 :: error ( format ! ( " " wrong ) ) . span ( q ) . add_note ( " " ) , ) ; return Err ( Reported ) ; } } } ; span . expand ( p . last_span ( ) ) ; Ok ( ast :: Stmt { id : Default :: default ( ) , span : span , label : label , data : data , } ) }
Parse a sequential or concurrent statement.
Parse a sequential or concurrent statement .
p
&mut P