/// Gather a list of arguments from the arguments in the function declaration.
Gather a list of arguments from the arguments in the function declaration.
Gather a list of arguments from the arguments in the function declaration .
fn gather_from_args<'a>(
    cx: &impl Context<'a>,
    node: &'a ast::SubroutineDecl<'a>,
    args: &'a [ast::SubroutinePort<'a>],
    next_rib: NodeId,
) -> Vec<FuncArg<'a>> {
    let mut out_args = vec![];
    let first_span = args.get(0).map(|x| x.span()).unwrap_or(node.span());
    // Determine the default direction and data type. These *may* be carried
    // over from argument to argument.
    let mut carry_dir = ast::SubroutinePortDir::Input;
    let mut carry_ty = Cow::Owned(ast::TypeKind::new(
        first_span.begin().into(),
        ast::LogicType,
    ));
    let mut carry_sign = ast::TypeSign::None;
    let mut carry_packed_dims: &[ast::TypeDim] = &[];
    for arg in args {
        // First resolve the ambiguity in the port type and name.
        let (ty, name) = cx.resolve_subroutine_port_ty_name(Ref(arg));
        // If no direction has been provided, use the one carried over from the
        // previous argument.
        let dir = arg.dir.unwrap_or(carry_dir);
        // Explicitly stating the port resets the carried-over data type.
        if arg.dir.is_some() {
            carry_ty = Cow::Owned(ast::TypeKind::new(
                first_span.begin().into(),
                ast::LogicType,
            ));
            carry_sign = ast::TypeSign::None;
            carry_packed_dims = &[];
        }
        // If no data type, sign, or packed dimensions have been provided, use
        // the ones carried over from the previous argument. Otherwise we use
        // the ones provided, filling in an implicit base data type if needed.
        let inherit = ty.kind.data == ast::ImplicitType
            && ty.sign == ast::TypeSign::None
            && ty.dims.is_empty();
        let (ty, sign, packed_dims, ty_span) = if inherit {
            (carry_ty, carry_sign, carry_packed_dims, None)
        } else {
            // If the argument has an implicit data type, use the one carried
            // over from before.
            let kind = if ty.kind.data == ast::ImplicitType {
                carry_ty
            } else {
                Cow::Borrowed(&ty.kind)
            };
            (kind, ty.sign, ty.dims.as_slice(), Some(ty.span()))
        };
        // Keep the direction, type, sign, and packed dimensions around for the
        // next argument in the list, which might want to inherit them.
        carry_dir = dir;
        carry_ty = ty.clone();
        carry_sign = sign;
        carry_packed_dims = packed_dims;
        // Wrap the type up.
        let ty = cx.arena().alloc(ast::Type::new(
            ty_span.unwrap_or(arg.span()),
            ast::TypeData {
                kind: ty.into_owned(),
                sign: sign,
                dims: packed_dims.to_vec(),
            },
        ));
        ty.link_attach(arg, arg.order());
        cx.register_ast(ty);
        cx.map_ast_with_parent(AstNode::Type(ty), next_rib);
        // Extract the name and default value for the argument.
        let (name, unpacked_dims, default): (_, &[_], _) = match name {
            Some(pn) => (Some(pn.name), pn.dims.as_slice(), pn.expr.as_ref()),
            None => (None, &[], None),
        };
        // Add an argument to the list.
        out_args.push(FuncArg {
            ast: arg,
            func: node,
            span: arg.span,
            name,
            dir,
            ty,
            var: arg.var,
            unpacked_dims,
            default,
        });
    }
    out_args
}
fn gather_from_args < ' a > ( cx : & impl Context < ' a > , node : & ' a ast :: SubroutineDecl < ' a > , args : & ' a [ ast :: SubroutinePort < ' a > ] , next_rib : NodeId , ) -> Vec < FuncArg < ' a > > { let mut out_args = vec ! [ ] ; let first_span = args . get ( 0 ) . map ( | x | x . span ( ) ) . unwrap_or ( node . span ( ) ) ; // Determine the default direction and data type. These *may* be carried // over from argument to argument. let mut carry_dir = ast :: SubroutinePortDir :: Input ; let mut carry_ty = Cow :: Owned ( ast :: TypeKind :: new ( first_span . begin ( ) . into ( ) , ast :: LogicType , ) ) ; let mut carry_sign = ast :: TypeSign :: None ; let mut carry_packed_dims : & [ ast :: TypeDim ] = & [ ] ; for arg in args { // First resolve the ambiguity in the port type and name. let ( ty , name ) = cx . resolve_subroutine_port_ty_name ( Ref ( arg ) ) ; // If no direction has been provided, use the one carried over from the // previous argument. let dir = arg . dir . unwrap_or ( carry_dir ) ; // Explicitly stating the port resets the carried-over data type. if arg . dir . is_some ( ) { carry_ty = Cow :: Owned ( ast :: TypeKind :: new ( first_span . begin ( ) . into ( ) , ast :: LogicType , ) ) ; carry_sign = ast :: TypeSign :: None ; carry_packed_dims = & [ ] ; } // If no data type, sign, or packed dimensions have been provided, use // the ones carried over from the previous argument. Otherwise we use // the ones provided, filling in an implicit base data type if needed. let inherit = ty . kind . data == ast :: ImplicitType && ty . sign == ast :: TypeSign :: None && ty . dims . is_empty ( ) ; let ( ty , sign , packed_dims , ty_span ) = if inherit { ( carry_ty , carry_sign , carry_packed_dims , None ) } else { // If the argument has an implicit data type, use the one carried // over from before. let kind = if ty . kind . data == ast :: ImplicitType { carry_ty } else { Cow :: Borrowed ( & ty . kind ) } ; ( kind , ty . sign , ty . dims . as_slice ( ) , Some ( ty . span ( ) ) ) } ; // Keep the direction, type, sign, and packed dimensions around for the // next argument in the list, which might want to inherit them. carry_dir = dir ; carry_ty = ty . clone ( ) ; carry_sign = sign ; carry_packed_dims = packed_dims ; // Wrap the type up. let ty = cx . arena ( ) . alloc ( ast :: Type :: new ( ty_span . unwrap_or ( arg . span ( ) ) , ast :: TypeData { kind : ty . into_owned ( ) , sign : sign , dims : packed_dims . to_vec ( ) , } , ) ) ; ty . link_attach ( arg , arg . order ( ) ) ; cx . register_ast ( ty ) ; cx . map_ast_with_parent ( AstNode :: Type ( ty ) , next_rib ) ; // Extract the name and default value for the argument. let ( name , unpacked_dims , default ) : ( _ , & [ _ ] , _ ) = match name { Some ( pn ) => ( Some ( pn . name ) , pn . dims . as_slice ( ) , pn . expr . as_ref ( ) ) , None => ( None , & [ ] , None ) , } ; // Add an argument to the list. out_args . push ( FuncArg { ast : arg , func : node , span : arg . span , name , dir , ty , var : arg . var , unpacked_dims , default , } ) ; } out_args }
Gather a list of arguments from the arguments in the function declaration.
Gather a list of arguments from the arguments in the function declaration .
cx
&impl Context<'a>
node
&'a ast::SubroutineDecl<'a>
args
&'a [ast::SubroutinePort<'a>]
next_rib
NodeId