pub fn parse_intf_decl<P: Parser>(
    p: &mut P,
    default: Option<ast::IntfObjKind>,
) -> ReportedResult<ast::IntfDecl> {
    let Spanned {
        value: tkn,
        mut span,
    } = p.peek(0);
    let kind = match tkn {
        // Try to short-circuit a type interface declarations.
        Keyword(Kw::Type) => return parse_type_decl(p, false).map(|d| ast::IntfDecl::TypeDecl(d)),

        // Try to short-circuit a subprogram interface declaration.
        Keyword(Kw::Pure)
        | Keyword(Kw::Impure)
        | Keyword(Kw::Procedure)
        | Keyword(Kw::Function) => {
            let spec = parse_subprog_spec(p)?;
            let default = if accept(p, Keyword(Kw::Is)) {
                if accept(p, LtGt) {
                    // subprog_spec "is" "<>"
                    Some(ast::SubprogDefault::Any)
                } else if let Some(name) = try_name(p)? {
                    // subprog_spec "is" name
                    Some(ast::SubprogDefault::Name(name))
                } else {
                    p.emit(
                        DiagBuilder2::error(format!(
                            "Expected default subprogram name or `<>` after `is`, found {} instead",
                            tkn
                        ))
                        .span(span)
                        .add_note("see IEEE 1076-2008 section 6.5.4"),
                    );
                    return Err(Reported);
                }
            } else {
                None
            };
            span.expand(p.last_span());
            return Ok(ast::IntfDecl::SubprogSpec(ast::IntfSubprogDecl {
                id: Default::default(),
                span: span,
                spec: spec,
                default: default,
            }));
        }

        // Try to short-circuit a package interface declaration.
        Keyword(Kw::Package) => {
            let inst = parse_package_inst(p, false)?;
            return Ok(ast::IntfDecl::PkgInst(inst));
        }

        // Try to parse one of the object declarations.
        Keyword(Kw::Constant) => {
            p.bump();
            ast::IntfObjKind::Const
        }
        Keyword(Kw::Signal) => {
            p.bump();
            ast::IntfObjKind::Signal
        }
        Keyword(Kw::Variable) => {
            p.bump();
            ast::IntfObjKind::Var
        }
        Keyword(Kw::File) => {
            p.bump();
            ast::IntfObjKind::File
        }
        _ => {
            if let Some(k) = default {
                k
            } else {
                p.emit(
                    DiagBuilder2::error("Expected an interface declaration")
                        .span(span)
                        .add_note(
                            "`constant`, `signal`, `variable`, and `file` start an object \
                             declaration",
                        )
                        .add_note("`type` starts a type declaration")
                        .add_note(
                            "`procedure`, `function`, `pure function`, or `impure function` start \
                             a subprogram declaration",
                        )
                        .add_note("`package` starts a package declaration")
                        .add_note("see IEEE 1076-2008 section 6.5"),
                );
                return Err(Reported);
            }
        }
    };

    // Parse the object names.
    let names = separated_nonempty(p, Comma, Colon, "object name", |p| {
        parse_ident(p, "object name")
    })?;
    require(p, Colon)?;

    // Parse the optional mode.
    let mode = match p.peek(0).value {
        Keyword(Kw::In) => {
            p.bump();
            Some(ast::IntfMode::In)
        }
        Keyword(Kw::Out) => {
            p.bump();
            Some(ast::IntfMode::Out)
        }
        Keyword(Kw::Inout) => {
            p.bump();
            Some(ast::IntfMode::Inout)
        }
        Keyword(Kw::Buffer) => {
            p.bump();
            Some(ast::IntfMode::Buffer)
        }
        Keyword(Kw::Linkage) => {
            p.bump();
            Some(ast::IntfMode::Linkage)
        }
        _ => None,
    };

    // Parse the type and optional `bus` keyword.
    let ty = parse_subtype_ind(p)?;
    let bus = accept(p, Keyword(Kw::Bus));

    // Parse the optional default expression.
    let def = if accept(p, VarAssign) {
        Some(parse_expr(p)?)
    } else {
        None
    };

    span.expand(p.last_span());
    Ok(ast::IntfDecl::ObjDecl(ast::IntfObjDecl {
        kind: kind,
        span: span,
        names: names.into_iter().map(|n| ast::Ident::from(n)).collect(),
        mode: mode,
        ty: ty,
        bus: bus,
        default: def,
    }))
}
/// Parse an interface declaration. These are generally part of an interface
/// list as they appear in generic and port clauses within for example entity
/// declarations. See IEEE 1076-2008 section 6.5.1.
Parse an interface declaration. These are generally part of an interface
list as they appear in generic and port clauses within for example entity
declarations.
Parse an interface declaration . These are generally part of an interface list as they appear in generic and port clauses within for example entity declarations .
pub fn parse_intf_decl<P: Parser>(
    p: &mut P,
    default: Option<ast::IntfObjKind>,
) -> ReportedResult<ast::IntfDecl> {
    let Spanned {
        value: tkn,
        mut span,
    } = p.peek(0);
    let kind = match tkn {
        // Try to short-circuit a type interface declarations.
        Keyword(Kw::Type) => return parse_type_decl(p, false).map(|d| ast::IntfDecl::TypeDecl(d)),
        // Try to short-circuit a subprogram interface declaration.
        Keyword(Kw::Pure)
        | Keyword(Kw::Impure)
        | Keyword(Kw::Procedure)
        | Keyword(Kw::Function) => {
            let spec = parse_subprog_spec(p)?;
            let default = if accept(p, Keyword(Kw::Is)) {
                if accept(p, LtGt) {
                    // subprog_spec "is" "<>"
                    Some(ast::SubprogDefault::Any)
                } else if let Some(name) = try_name(p)? {
                    // subprog_spec "is" name
                    Some(ast::SubprogDefault::Name(name))
                } else {
                    p.emit(
                        DiagBuilder2::error(format!(
                            "Expected default subprogram name or `<>` after `is`, found {} instead",
                            tkn
                        ))
                        .span(span)
                        .add_note("see IEEE 1076-2008 section 6.5.4"),
                    );
                    return Err(Reported);
                }
            } else {
                None
            };
            span.expand(p.last_span());
            return Ok(ast::IntfDecl::SubprogSpec(ast::IntfSubprogDecl {
                id: Default::default(),
                span: span,
                spec: spec,
                default: default,
            }));
        }
        // Try to short-circuit a package interface declaration.
        Keyword(Kw::Package) => {
            let inst = parse_package_inst(p, false)?;
            return Ok(ast::IntfDecl::PkgInst(inst));
        }
        // Try to parse one of the object declarations.
        Keyword(Kw::Constant) => {
            p.bump();
            ast::IntfObjKind::Const
        }
        Keyword(Kw::Signal) => {
            p.bump();
            ast::IntfObjKind::Signal
        }
        Keyword(Kw::Variable) => {
            p.bump();
            ast::IntfObjKind::Var
        }
        Keyword(Kw::File) => {
            p.bump();
            ast::IntfObjKind::File
        }
        _ => {
            if let Some(k) = default {
                k
            } else {
                p.emit(
                    DiagBuilder2::error("Expected an interface declaration")
                        .span(span)
                        .add_note(
                            "`constant`, `signal`, `variable`, and `file` start an object \
                             declaration",
                        )
                        .add_note("`type` starts a type declaration")
                        .add_note(
                            "`procedure`, `function`, `pure function`, or `impure function` start \
                             a subprogram declaration",
                        )
                        .add_note("`package` starts a package declaration")
                        .add_note("see IEEE 1076-2008 section 6.5"),
                );
                return Err(Reported);
            }
        }
    };
    // Parse the object names.
    let names = separated_nonempty(p, Comma, Colon, "object name", |p| {
        parse_ident(p, "object name")
    })?;
    require(p, Colon)?;
    // Parse the optional mode.
    let mode = match p.peek(0).value {
        Keyword(Kw::In) => {
            p.bump();
            Some(ast::IntfMode::In)
        }
        Keyword(Kw::Out) => {
            p.bump();
            Some(ast::IntfMode::Out)
        }
        Keyword(Kw::Inout) => {
            p.bump();
            Some(ast::IntfMode::Inout)
        }
        Keyword(Kw::Buffer) => {
            p.bump();
            Some(ast::IntfMode::Buffer)
        }
        Keyword(Kw::Linkage) => {
            p.bump();
            Some(ast::IntfMode::Linkage)
        }
        _ => None,
    };
    // Parse the type and optional `bus` keyword.
    let ty = parse_subtype_ind(p)?;
    let bus = accept(p, Keyword(Kw::Bus));
    // Parse the optional default expression.
    let def = if accept(p, VarAssign) {
        Some(parse_expr(p)?)
    } else {
        None
    };
    span.expand(p.last_span());
    Ok(ast::IntfDecl::ObjDecl(ast::IntfObjDecl {
        kind: kind,
        span: span,
        names: names.into_iter().map(|n| ast::Ident::from(n)).collect(),
        mode: mode,
        ty: ty,
        bus: bus,
        default: def,
    }))
}
pub fn parse_intf_decl < P : Parser > ( p : & mut P , default : Option < ast :: IntfObjKind > , ) -> ReportedResult < ast :: IntfDecl > { let Spanned { value : tkn , mut span , } = p . peek ( 0 ) ; let kind = match tkn { // Try to short-circuit a type interface declarations. Keyword ( Kw :: Type ) => return parse_type_decl ( p , false ) . map ( | d | ast :: IntfDecl :: TypeDecl ( d ) ) , // Try to short-circuit a subprogram interface declaration. Keyword ( Kw :: Pure ) | Keyword ( Kw :: Impure ) | Keyword ( Kw :: Procedure ) | Keyword ( Kw :: Function ) => { let spec = parse_subprog_spec ( p ) ? ; let default = if accept ( p , Keyword ( Kw :: Is ) ) { if accept ( p , LtGt ) { // subprog_spec "is" "<>" Some ( ast :: SubprogDefault :: Any ) } else if let Some ( name ) = try_name ( p ) ? { // subprog_spec "is" name Some ( ast :: SubprogDefault :: Name ( name ) ) } else { p . emit ( DiagBuilder2 :: error ( format ! ( " " tkn ) ) . span ( span ) . add_note ( " " ) , ) ; return Err ( Reported ) ; } } else { None } ; span . expand ( p . last_span ( ) ) ; return Ok ( ast :: IntfDecl :: SubprogSpec ( ast :: IntfSubprogDecl { id : Default :: default ( ) , span : span , spec : spec , default : default , } ) ) ; } // Try to short-circuit a package interface declaration. Keyword ( Kw :: Package ) => { let inst = parse_package_inst ( p , false ) ? ; return Ok ( ast :: IntfDecl :: PkgInst ( inst ) ) ; } // Try to parse one of the object declarations. Keyword ( Kw :: Constant ) => { p . bump ( ) ; ast :: IntfObjKind :: Const } Keyword ( Kw :: Signal ) => { p . bump ( ) ; ast :: IntfObjKind :: Signal } Keyword ( Kw :: Variable ) => { p . bump ( ) ; ast :: IntfObjKind :: Var } Keyword ( Kw :: File ) => { p . bump ( ) ; ast :: IntfObjKind :: File } _ => { if let Some ( k ) = default { k } else { p . emit ( DiagBuilder2 :: error ( " " ) . span ( span ) . add_note ( " \
 " , ) . add_note ( " " ) . add_note ( " \
 " , ) . add_note ( " " ) . add_note ( " " ) , ) ; return Err ( Reported ) ; } } } ; // Parse the object names. let names = separated_nonempty ( p , Comma , Colon , " " , | p | { parse_ident ( p , " " ) } ) ? ; require ( p , Colon ) ? ; // Parse the optional mode. let mode = match p . peek ( 0 ) . value { Keyword ( Kw :: In ) => { p . bump ( ) ; Some ( ast :: IntfMode :: In ) } Keyword ( Kw :: Out ) => { p . bump ( ) ; Some ( ast :: IntfMode :: Out ) } Keyword ( Kw :: Inout ) => { p . bump ( ) ; Some ( ast :: IntfMode :: Inout ) } Keyword ( Kw :: Buffer ) => { p . bump ( ) ; Some ( ast :: IntfMode :: Buffer ) } Keyword ( Kw :: Linkage ) => { p . bump ( ) ; Some ( ast :: IntfMode :: Linkage ) } _ => None , } ; // Parse the type and optional `bus` keyword. let ty = parse_subtype_ind ( p ) ? ; let bus = accept ( p , Keyword ( Kw :: Bus ) ) ; // Parse the optional default expression. let def = if accept ( p , VarAssign ) { Some ( parse_expr ( p ) ? ) } else { None } ; span . expand ( p . last_span ( ) ) ; Ok ( ast :: IntfDecl :: ObjDecl ( ast :: IntfObjDecl { kind : kind , span : span , names : names . into_iter ( ) . map ( | n | ast :: Ident :: from ( n ) ) . collect ( ) , mode : mode , ty : ty , bus : bus , default : def , } ) ) }
Parse an interface declaration.
Parse an interface declaration .
p
&mut P
default
Option<ast::IntfObjKind>
p
&mut P
default
Option<ast::IntfObjKind>