pub fn new(
        signature: ast::Signature,
        cells: Vec<ast::Cell>,
        connections: Vec<ast::Connection>,
        comp_sigs: &HashMap<ast::Id, ast::Signature>,
        prim_sigs: &HashMap<ast::Id, ast::Signature>,
    ) -> Result<Self> {
        let mut structure = StructureGraph::default();

        structure.add_signature(signature);

        // add vertices first, ignoring wires so that order of structure
        // doesn't matter
        let mut cell_map: Vec<(ast::Id, ast::Cell)> = cells
            .into_iter()
            .map(|c| match c {
                Cell::Decl {
                    data: ast::Decl { ref name, .. },
                }
                | Cell::Prim {
                    data: ast::Prim { ref name, .. },
                } => (name.clone(), c),
            })
            .collect();

        while let Some((id, stmt)) = cell_map.pop() {
            // Error if this cell name is already bound.
            if cell_map.iter().any(|(i, _)| *i == id) {
                return Err(Error::AlreadyBound(id, "cell".to_string()));
            }
            match stmt {
                Cell::Decl { ref data } => {
                    // lookup signature for data.component
                    let sig =
                        comp_sigs.get(&data.component).ok_or_else(|| {
                            Error::UndefinedComponent(data.component.clone())
                        })?;
                    // create node for this decl
                    let instance = Node {
                        name: data.name.clone(),
                        data: NodeData::Cell(stmt.clone()),
                        signature: sig.clone(),
                    };
                    // insert the node into the graph
                    structure.graph.add_node(instance);
                }
                Cell::Prim { ref data } => {
                    // resolve param signature and add it to hashmap so that
                    //  we keep a reference to it
                    let sig = prim_sigs.get(&data.name).ok_or_else(|| {
                        Error::UndefinedComponent(data.name.clone())
                    })?;
                    // create node for this prim
                    let instance = Node {
                        name: data.name.clone(),
                        data: NodeData::Cell(stmt.clone()),
                        signature: sig.clone(),
                    };
                    // insert the node into the graph
                    structure.graph.add_node(instance);
                }
            }
        }

        // flatten connections into Vec<(group_name: Option<Id>, wire: Wire)>
        let wires: Vec<_> = connections
            .into_iter()
            .map(|stmt| match stmt {
                Connection::Wire(wire) => vec![(None, wire)],
                Connection::Group(group) => {
                    let name = group.name.clone();
                    let key = Some(name.clone());
                    // XXX(rachit): This is the wrong way to handle
                    // the Result<_> returned from insert_group.
                    structure.insert_group(&name, group.attributes).expect(
                        "Malformed input AST: Duplicate group names found.",
                    );

                    group.wires.into_iter().map(|w| (key.clone(), w)).collect()
                }
            })
            .flatten()
            .collect();

        // Create "default" group that contains all edges without a group.
        structure.groups.insert(None, (HashMap::new(), Vec::new()));
        // then add edges
        for (group, wire) in wires {
            // get src node and port in graph
            let (src_node, src_port) = match &wire.src.expr {
                Atom::Port(p) => match p {
                    Port::Comp { component: c, port }
                    | Port::Hole {
                        group: c,
                        name: port,
                    } => (structure.get_node_by_name(c)?, port.clone()),
                    Port::This { port } => (structure.io, port.clone()),
                },
                Atom::Num(n) => structure.new_constant(n.val, n.width)?,
            };
            // get dest node and port in graph
            let (dest_node, dest_port) = match &wire.dest {
                Port::Comp { component: c, port }
                | Port::Hole {
                    group: c,
                    name: port,
                } => (structure.get_node_by_name(c)?, port.clone()),
                Port::This { port } => (structure.io, port.clone()),
            };
            structure.insert_edge(
                (src_node, src_port),
                (dest_node, dest_port),
                group.clone(),
                wire.src.guard.clone(),
            )?;
        }
        Ok(structure)
    }
/// Creates a new structure graph from a component definition
///
/// # Arguments
///   * `compdef` - the component definition
///   * `comp_sigs` - map of component signatures
///   * `prim_sigs` - map of primitive component signatures
Creates a new structure graph from a component definition
Creates a new structure graph from a component definition
pub fn new(
        signature: ast::Signature,
        cells: Vec<ast::Cell>,
        connections: Vec<ast::Connection>,
        comp_sigs: &HashMap<ast::Id, ast::Signature>,
        prim_sigs: &HashMap<ast::Id, ast::Signature>,
    ) -> Result<Self> {
        let mut structure = StructureGraph::default();
        structure.add_signature(signature);
        // add vertices first, ignoring wires so that order of structure
        // doesn't matter
        let mut cell_map: Vec<(ast::Id, ast::Cell)> = cells
            .into_iter()
            .map(|c| match c {
                Cell::Decl {
                    data: ast::Decl { ref name, .. },
                }
                | Cell::Prim {
                    data: ast::Prim { ref name, .. },
                } => (name.clone(), c),
            })
            .collect();
        while let Some((id, stmt)) = cell_map.pop() {
            // Error if this cell name is already bound.
            if cell_map.iter().any(|(i, _)| *i == id) {
                return Err(Error::AlreadyBound(id, "cell".to_string()));
            }
            match stmt {
                Cell::Decl { ref data } => {
                    // lookup signature for data.component
                    let sig =
                        comp_sigs.get(&data.component).ok_or_else(|| {
                            Error::UndefinedComponent(data.component.clone())
                        })?;
                    // create node for this decl
                    let instance = Node {
                        name: data.name.clone(),
                        data: NodeData::Cell(stmt.clone()),
                        signature: sig.clone(),
                    };
                    // insert the node into the graph
                    structure.graph.add_node(instance);
                }
                Cell::Prim { ref data } => {
                    // resolve param signature and add it to hashmap so that
                    //  we keep a reference to it
                    let sig = prim_sigs.get(&data.name).ok_or_else(|| {
                        Error::UndefinedComponent(data.name.clone())
                    })?;
                    // create node for this prim
                    let instance = Node {
                        name: data.name.clone(),
                        data: NodeData::Cell(stmt.clone()),
                        signature: sig.clone(),
                    };
                    // insert the node into the graph
                    structure.graph.add_node(instance);
                }
            }
        }
        // flatten connections into Vec<(group_name: Option<Id>, wire: Wire)>
        let wires: Vec<_> = connections
            .into_iter()
            .map(|stmt| match stmt {
                Connection::Wire(wire) => vec![(None, wire)],
                Connection::Group(group) => {
                    let name = group.name.clone();
                    let key = Some(name.clone());
                    // XXX(rachit): This is the wrong way to handle
                    // the Result<_> returned from insert_group.
                    structure.insert_group(&name, group.attributes).expect(
                        "Malformed input AST: Duplicate group names found.",
                    );
                    group.wires.into_iter().map(|w| (key.clone(), w)).collect()
                }
            })
            .flatten()
            .collect();
        // Create "default" group that contains all edges without a group.
        structure.groups.insert(None, (HashMap::new(), Vec::new()));
        // then add edges
        for (group, wire) in wires {
            // get src node and port in graph
            let (src_node, src_port) = match &wire.src.expr {
                Atom::Port(p) => match p {
                    Port::Comp { component: c, port }
                    | Port::Hole {
                        group: c,
                        name: port,
                    } => (structure.get_node_by_name(c)?, port.clone()),
                    Port::This { port } => (structure.io, port.clone()),
                },
                Atom::Num(n) => structure.new_constant(n.val, n.width)?,
            };
            // get dest node and port in graph
            let (dest_node, dest_port) = match &wire.dest {
                Port::Comp { component: c, port }
                | Port::Hole {
                    group: c,
                    name: port,
                } => (structure.get_node_by_name(c)?, port.clone()),
                Port::This { port } => (structure.io, port.clone()),
            };
            structure.insert_edge(
                (src_node, src_port),
                (dest_node, dest_port),
                group.clone(),
                wire.src.guard.clone(),
            )?;
        }
        Ok(structure)
    }
pub fn new ( signature : ast :: Signature , cells : Vec < ast :: Cell > , connections : Vec < ast :: Connection > , comp_sigs : & HashMap < ast :: Id , ast :: Signature > , prim_sigs : & HashMap < ast :: Id , ast :: Signature > , ) -> Result < Self > { let mut structure = StructureGraph :: default ( ) ; structure . add_signature ( signature ) ; // add vertices first, ignoring wires so that order of structure // doesn't matter let mut cell_map : Vec < ( ast :: Id , ast :: Cell ) > = cells . into_iter ( ) . map ( | c | match c { Cell :: Decl { data : ast :: Decl { ref name , .. } , } | Cell :: Prim { data : ast :: Prim { ref name , .. } , } => ( name . clone ( ) , c ) , } ) . collect ( ) ; while let Some ( ( id , stmt ) ) = cell_map . pop ( ) { // Error if this cell name is already bound. if cell_map . iter ( ) . any ( | ( i , _ ) | * i == id ) { return Err ( Error :: AlreadyBound ( id , " " . to_string ( ) ) ) ; } match stmt { Cell :: Decl { ref data } => { // lookup signature for data.component let sig = comp_sigs . get ( & data . component ) . ok_or_else ( | | { Error :: UndefinedComponent ( data . component . clone ( ) ) } ) ? ; // create node for this decl let instance = Node { name : data . name . clone ( ) , data : NodeData :: Cell ( stmt . clone ( ) ) , signature : sig . clone ( ) , } ; // insert the node into the graph structure . graph . add_node ( instance ) ; } Cell :: Prim { ref data } => { // resolve param signature and add it to hashmap so that //  we keep a reference to it let sig = prim_sigs . get ( & data . name ) . ok_or_else ( | | { Error :: UndefinedComponent ( data . name . clone ( ) ) } ) ? ; // create node for this prim let instance = Node { name : data . name . clone ( ) , data : NodeData :: Cell ( stmt . clone ( ) ) , signature : sig . clone ( ) , } ; // insert the node into the graph structure . graph . add_node ( instance ) ; } } } // flatten connections into Vec<(group_name: Option<Id>, wire: Wire)> let wires : Vec < _ > = connections . into_iter ( ) . map ( | stmt | match stmt { Connection :: Wire ( wire ) => vec ! [ ( None wire ) ] , Connection :: Group ( group ) => { let name = group . name . clone ( ) ; let key = Some ( name . clone ( ) ) ; // XXX(rachit): This is the wrong way to handle // the Result<_> returned from insert_group. structure . insert_group ( & name , group . attributes ) . expect ( " " , ) ; group . wires . into_iter ( ) . map ( | w | ( key . clone ( ) , w ) ) . collect ( ) } } ) . flatten ( ) . collect ( ) ; // Create "default" group that contains all edges without a group. structure . groups . insert ( None , ( HashMap :: new ( ) , Vec :: new ( ) ) ) ; // then add edges for ( group , wire ) in wires { // get src node and port in graph let ( src_node , src_port ) = match & wire . src . expr { Atom :: Port ( p ) => match p { Port :: Comp { component : c , port } | Port :: Hole { group : c , name : port , } => ( structure . get_node_by_name ( c ) ? , port . clone ( ) ) , Port :: This { port } => ( structure . io , port . clone ( ) ) , } , Atom :: Num ( n ) => structure . new_constant ( n . val , n . width ) ? , } ; // get dest node and port in graph let ( dest_node , dest_port ) = match & wire . dest { Port :: Comp { component : c , port } | Port :: Hole { group : c , name : port , } => ( structure . get_node_by_name ( c ) ? , port . clone ( ) ) , Port :: This { port } => ( structure . io , port . clone ( ) ) , } ; structure . insert_edge ( ( src_node , src_port ) , ( dest_node , dest_port ) , group . clone ( ) , wire . src . guard . clone ( ) , ) ? ; } Ok ( structure ) }
Creates a new structure graph from a component definition
Creates a new structure graph from a component definition
signature
ast::Signature
cells
Vec<ast::Cell>
connections
Vec<ast::Connection>
comp_sigs
&HashMap<ast::Id, ast::Signature>
prim_sigs
&HashMap<ast::Id, ast::Signature>