pub fn parse_subprog_decl_item<P: Parser>(p: &mut P) -> ReportedResult<ast::Subprog> {
    let mut span = p.peek(0).span;
    let spec = parse_subprog_spec(p)?;

    // Try to parse a subprogram declaration.
    if accept(p, Semicolon) {
        span.expand(p.last_span());
        return Ok(ast::Subprog {
            id: Default::default(),
            span: span,
            spec: spec,
            data: ast::SubprogData::Decl,
        });
    }

    // Try to parse a subprogram body or instantiation.
    if accept(p, Keyword(Kw::Is)) {
        // Try to parse a subprogram instantiation. Otherwise fall back to a
        // subprogram body.
        if accept(p, Keyword(Kw::New)) {
            let name = parse_name(p)?;
            let gm = try_map_aspect(p, Kw::Generic)?;
            require(p, Semicolon)?;
            span.expand(p.last_span());
            return Ok(ast::Subprog {
                id: Default::default(),
                span: span,
                spec: spec,
                data: ast::SubprogData::Inst {
                    name: name,
                    generics: gm,
                },
            });
        } else {
            let decl_items = repeat(p, try_decl_item)?;
            require(p, Keyword(Kw::Begin))?;
            let stmts = repeat_until(p, Keyword(Kw::End), parse_stmt)?;
            require(p, Keyword(Kw::End))?;
            // TODO: Check if things match once the subprog_spec returns
            // something useful.
            accept(p, Keyword(Kw::Function));
            accept(p, Keyword(Kw::Procedure));
            try_primary_name(p);
            require(p, Semicolon)?;
            span.expand(p.last_span());
            return Ok(ast::Subprog {
                id: Default::default(),
                span: span,
                spec: spec,
                data: ast::SubprogData::Body {
                    decls: decl_items,
                    stmts: stmts,
                },
            });
        }
    }

    // If we arrive here, none of the above matched. Emit an error that
    // describes what we expected.
    let pk = p.peek(0);
    p.emit(
        DiagBuilder2::error(format!(
            "Expected `;` or keyword `is` after subprogram specification, found {} instead",
            pk.value
        ))
        .span(pk.span)
        .add_note("see IEEE 1076-2008 section 4.2"),
    );
    Err(Reported)
}
/// Parse a subprogram declarative item, which is either a subprogram
/// declaration, body, or instantiation. See IEEE 1076-2008 section 4.2.
///
/// ```text
/// subprog_decl := subprog_spec ";"
/// subprog_body := subprog_spec "is" ...
/// subprog_inst := subprog_spec "is" "new" name [signature] [generic_map_aspect] ";"
/// ```
Parse a subprogram declarative item, which is either a subprogram
declaration, body, or instantiation.


Parse a subprogram declarative item which is either a subprogram declaration body or instantiation .
pub fn parse_subprog_decl_item<P: Parser>(p: &mut P) -> ReportedResult<ast::Subprog> {
    let mut span = p.peek(0).span;
    let spec = parse_subprog_spec(p)?;
    // Try to parse a subprogram declaration.
    if accept(p, Semicolon) {
        span.expand(p.last_span());
        return Ok(ast::Subprog {
            id: Default::default(),
            span: span,
            spec: spec,
            data: ast::SubprogData::Decl,
        });
    }
    // Try to parse a subprogram body or instantiation.
    if accept(p, Keyword(Kw::Is)) {
        // Try to parse a subprogram instantiation. Otherwise fall back to a
        // subprogram body.
        if accept(p, Keyword(Kw::New)) {
            let name = parse_name(p)?;
            let gm = try_map_aspect(p, Kw::Generic)?;
            require(p, Semicolon)?;
            span.expand(p.last_span());
            return Ok(ast::Subprog {
                id: Default::default(),
                span: span,
                spec: spec,
                data: ast::SubprogData::Inst {
                    name: name,
                    generics: gm,
                },
            });
        } else {
            let decl_items = repeat(p, try_decl_item)?;
            require(p, Keyword(Kw::Begin))?;
            let stmts = repeat_until(p, Keyword(Kw::End), parse_stmt)?;
            require(p, Keyword(Kw::End))?;
            // TODO: Check if things match once the subprog_spec returns
            // something useful.
            accept(p, Keyword(Kw::Function));
            accept(p, Keyword(Kw::Procedure));
            try_primary_name(p);
            require(p, Semicolon)?;
            span.expand(p.last_span());
            return Ok(ast::Subprog {
                id: Default::default(),
                span: span,
                spec: spec,
                data: ast::SubprogData::Body {
                    decls: decl_items,
                    stmts: stmts,
                },
            });
        }
    }
    // If we arrive here, none of the above matched. Emit an error that
    // describes what we expected.
    let pk = p.peek(0);
    p.emit(
        DiagBuilder2::error(format!(
            "Expected `;` or keyword `is` after subprogram specification, found {} instead",
            pk.value
        ))
        .span(pk.span)
        .add_note("see IEEE 1076-2008 section 4.2"),
    );
    Err(Reported)
}
pub fn parse_subprog_decl_item < P : Parser > ( p : & mut P ) -> ReportedResult < ast :: Subprog > { let mut span = p . peek ( 0 ) . span ; let spec = parse_subprog_spec ( p ) ? ; // Try to parse a subprogram declaration. if accept ( p , Semicolon ) { span . expand ( p . last_span ( ) ) ; return Ok ( ast :: Subprog { id : Default :: default ( ) , span : span , spec : spec , data : ast :: SubprogData :: Decl , } ) ; } // Try to parse a subprogram body or instantiation. if accept ( p , Keyword ( Kw :: Is ) ) { // Try to parse a subprogram instantiation. Otherwise fall back to a // subprogram body. if accept ( p , Keyword ( Kw :: New ) ) { let name = parse_name ( p ) ? ; let gm = try_map_aspect ( p , Kw :: Generic ) ? ; require ( p , Semicolon ) ? ; span . expand ( p . last_span ( ) ) ; return Ok ( ast :: Subprog { id : Default :: default ( ) , span : span , spec : spec , data : ast :: SubprogData :: Inst { name : name , generics : gm , } , } ) ; } else { let decl_items = repeat ( p , try_decl_item ) ? ; require ( p , Keyword ( Kw :: Begin ) ) ? ; let stmts = repeat_until ( p , Keyword ( Kw :: End ) , parse_stmt ) ? ; require ( p , Keyword ( Kw :: End ) ) ? ; // TODO: Check if things match once the subprog_spec returns // something useful. accept ( p , Keyword ( Kw :: Function ) ) ; accept ( p , Keyword ( Kw :: Procedure ) ) ; try_primary_name ( p ) ; require ( p , Semicolon ) ? ; span . expand ( p . last_span ( ) ) ; return Ok ( ast :: Subprog { id : Default :: default ( ) , span : span , spec : spec , data : ast :: SubprogData :: Body { decls : decl_items , stmts : stmts , } , } ) ; } } // If we arrive here, none of the above matched. Emit an error that // describes what we expected. let pk = p . peek ( 0 ) ; p . emit ( DiagBuilder2 :: error ( format ! ( " " pk value ) ) . span ( pk . span ) . add_note ( " " ) , ) ; Err ( Reported ) }
Parse a subprogram declarative item, which is either a subprogram
declaration, body, or instantiation.
Parse a subprogram declarative item which is either a subprogram declaration body or instantiation .
p
&mut P
p
&mut P