bitsy_lang/
component.rs

1use super::*;
2use std::sync::Arc;
3
4/// A [`Component`] is a declaration that lives inside of a `mod` or `ext` definiton.
5#[derive(Debug, Clone)]
6pub enum Component {
7    Mod(Loc, Name, Vec<Arc<Component>>, Vec<Wire>, Vec<When>),
8    ModInst(Loc, Name, Arc<Component>),
9    Ext(Loc, Name, Vec<Arc<Component>>),
10    Incoming(Loc, Name, Type),
11    Outgoing(Loc, Name, Type),
12    Node(Loc, Name, Type),
13    Reg(Loc, Name, Type, Option<Arc<Expr>>),
14}
15
16impl Component {
17    pub fn name(&self) -> &str {
18        match self {
19            Component::Mod(_loc, name, _children, _wires, _whens) => name.as_str(),
20            Component::ModInst(_loc, name, _defname) => name.as_str(),
21            Component::Ext(_loc, name, _children) => name.as_str(),
22            Component::Incoming(_loc, name, _typ) => name.as_str(),
23            Component::Outgoing(_loc, name, _typ) => name.as_str(),
24            Component::Node(_loc, name, _typ) => name.as_str(),
25            Component::Reg(_loc, name, _typ, _value) => name.as_str(),
26        }
27    }
28
29    pub fn child(&self, name: &str) -> Option<Arc<Component>> {
30        for child in self.children() {
31            if child.name() == name {
32                return Some(child);
33            }
34        }
35        None
36    }
37
38    pub fn children(&self) -> Vec<Arc<Component>> {
39        match self {
40            Component::Mod(_loc, _name, children, _wires, _whens) => children.iter().cloned().collect(),
41            Component::ModInst(_loc, _name, _defname) => vec![],
42            Component::Ext(_loc, _name, children) => children.iter().cloned().collect(),
43            Component::Incoming(_loc, _name, _typ) => vec![],
44            Component::Outgoing(_loc, _name, _typ) => vec![],
45            Component::Node(_loc, _name, _typ) => vec![],
46            Component::Reg(_loc, _name, _typ, _value) => vec![],
47        }
48    }
49
50    pub(crate) fn wires(&self) -> Vec<Wire> {
51        match self {
52            Component::Mod(_loc, _name, _children, wires, _whens) => {
53                wires.clone()
54            }
55            _ => vec![],
56        }
57    }
58
59    pub(crate) fn paths_rec(&self, path: Path) -> Vec<Path> {
60        let mut results = vec![];
61        for child in self.children() {
62            match &*child {
63                Component::Node(_loc, name, _typ) => results.push(path.join(name.clone().into())),
64                Component::Reg(_loc, name, _typ, _reset) => {
65                    results.push(path.join(format!("{name}.set").into()));
66                    results.push(path.join(name.clone().into()));
67                },
68                Component::Incoming(_loc, name, _typ) => results.push(path.join(name.clone().into())),
69                Component::Outgoing(_loc, name, _typ) => results.push(path.join(name.clone().into())),
70                Component::Mod(_loc, name, _children, _wires, _whens) => results.extend(child.paths_rec(path.join(name.clone().into()))),
71                Component::ModInst(_loc, name, moddef) => {
72                    results.extend(moddef.paths_rec(path.join(name.clone().into())))
73                }
74                Component::Ext(_loc, name, _children) => results.extend(child.paths_rec(path.join(name.clone().into()))),
75            }
76        }
77        results
78    }
79
80    pub fn port_paths(&self) -> Vec<(Path, Arc<Component>)> {
81        let mut results = vec![];
82        for child in self.children() {
83            match &*child {
84                Component::Incoming(_loc, name, _typ) => results.push((name.to_string().into(), child.clone())),
85                Component::Outgoing(_loc, name, _typ) => results.push((name.to_string().into(), child.clone())),
86                _ => (),
87            }
88        }
89        results
90    }
91
92    pub fn is_mod(&self) -> bool {
93        match self {
94            Component::Mod(_loc, _name, _children, _wires, _whens) => true,
95            _ => false
96        }
97    }
98
99    pub fn is_port(&self) -> bool {
100        match self {
101            Component::Incoming(_loc, _name, _typ) => true,
102            Component::Outgoing(_loc, _name, _typ) => true,
103            _ => false
104        }
105    }
106
107    pub fn is_incoming_port(&self) -> bool {
108        match self {
109            Component::Incoming(_loc, _name, _typ) => true,
110            _ => false
111        }
112    }
113
114    pub fn is_outgoing_port(&self) -> bool {
115        match self {
116            Component::Outgoing(_loc, _name, _typ) => true,
117            _ => false
118        }
119    }
120
121    pub fn type_of(&self) -> Option<Type> {
122        match self {
123            Component::Node(_loc,_name, typ) => Some(typ.clone()),
124            Component::Reg(_loc,_name, typ, _reset) => Some(typ.clone()),
125            Component::Incoming(_loc,_name, typ) => Some(typ.clone()),
126            Component::Outgoing(_loc,_name, typ) => Some(typ.clone()),
127            Component::Mod(_loc,_name, _children, _wires, _whens) => None,
128            Component::ModInst(_loc,_name, _defname) => None,
129            Component::Ext(_loc,_name, _children) => None,
130        }
131    }
132
133    pub fn reset(&self) -> Option<Arc<Expr>> {
134        match self {
135            Component::Reg(_loc, _name, _typ, reset) => reset.clone(),
136            _ => None
137        }
138    }
139
140    pub fn submods(&self) -> Vec<Arc<Component>> {
141        let mut results = vec![];
142        for child in self.children() {
143            if let Component::Mod(_loc,_name, _children, _wires, _whens) = &*child {
144                results.push(child.clone());
145            }
146        }
147        results
148    }
149}