1use super::*;
2use std::sync::Arc;
3
4#[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}