use super::*;
use std::sync::Arc;
#[derive(Debug, Clone)]
pub enum Component {
Mod(Span, Name, Vec<Arc<Component>>, Vec<Wire>, Vec<When>),
ModInst(Span, Name, Arc<Component>),
Ext(Span, Name, Vec<Arc<Component>>),
Dom(Span, Name),
Incoming(Span, Name, Type),
Outgoing(Span, Name, Type),
Node(Span, Name, Type),
Reg(Span, Name, Type, Option<Arc<Expr>>),
}
impl Component {
pub fn name(&self) -> &str {
match self {
Component::Mod(_loc, name, _children, _wires, _whens) => name.as_str(),
Component::ModInst(_loc, name, _defname) => name.as_str(),
Component::Ext(_loc, name, _children) => name.as_str(),
Component::Dom(_loc, name) => name.as_str(),
Component::Incoming(_loc, name, _typ) => name.as_str(),
Component::Outgoing(_loc, name, _typ) => name.as_str(),
Component::Node(_loc, name, _typ) => name.as_str(),
Component::Reg(_loc, name, _typ, _value) => name.as_str(),
}
}
pub fn child(&self, name: &str) -> Option<Arc<Component>> {
for child in self.children() {
if child.name() == name {
return Some(child);
}
}
None
}
pub fn children(&self) -> Vec<Arc<Component>> {
match self {
Component::Mod(_loc, _name, children, _wires, _whens) => children.iter().cloned().collect(),
Component::ModInst(_loc, _name, _defname) => vec![],
Component::Ext(_loc, _name, children) => children.iter().cloned().collect(),
Component::Dom(_loc, _name) => vec![],
Component::Incoming(_loc, _name, _typ) => vec![],
Component::Outgoing(_loc, _name, _typ) => vec![],
Component::Node(_loc, _name, _typ) => vec![],
Component::Reg(_loc, _name, _typ, _value) => vec![],
}
}
pub(crate) fn wires(&self) -> Vec<Wire> {
match self {
Component::Mod(_loc, _name, _children, wires, _whens) => {
wires.clone()
}
_ => vec![],
}
}
pub(crate) fn whens(&self) -> Vec<When> {
match self {
Component::Mod(_loc, _name, _children, _wires, whens) => {
whens.clone()
}
_ => vec![],
}
}
pub(crate) fn paths_rec(&self, path: Path) -> Vec<Path> {
let mut results = vec![];
for child in self.children() {
match &*child {
Component::Node(_loc, name, _typ) => results.push(path.join(name.clone().into())),
Component::Reg(_loc, name, _typ, _reset) => {
results.push(path.join(format!("{name}.set").into()));
results.push(path.join(name.clone().into()));
},
Component::Dom(_loc, name) => results.push(path.join(name.clone().into())),
Component::Incoming(_loc, name, _typ) => results.push(path.join(name.clone().into())),
Component::Outgoing(_loc, name, _typ) => results.push(path.join(name.clone().into())),
Component::Mod(_loc, name, _children, _wires, _whens) => results.extend(child.paths_rec(path.join(name.clone().into()))),
Component::ModInst(_loc, name, moddef) => {
results.extend(moddef.paths_rec(path.join(name.clone().into())))
}
Component::Ext(_loc, name, _children) => results.extend(child.paths_rec(path.join(name.clone().into()))),
}
}
results
}
pub fn port_paths(&self) -> Vec<(Path, Arc<Component>)> {
let mut results = vec![];
for child in self.children() {
match &*child {
Component::Incoming(_loc, name, _typ) => results.push((name.to_string().into(), child.clone())),
Component::Outgoing(_loc, name, _typ) => results.push((name.to_string().into(), child.clone())),
_ => (),
}
}
results
}
pub fn is_mod(&self) -> bool {
match self {
Component::Mod(_loc, _name, _children, _wires, _whens) => true,
_ => false
}
}
pub fn is_port(&self) -> bool {
match self {
Component::Incoming(_loc, _name, _typ) => true,
Component::Outgoing(_loc, _name, _typ) => true,
_ => false
}
}
pub fn is_incoming_port(&self) -> bool {
match self {
Component::Incoming(_loc, _name, _typ) => true,
_ => false
}
}
pub fn is_outgoing_port(&self) -> bool {
match self {
Component::Outgoing(_loc, _name, _typ) => true,
_ => false
}
}
pub fn type_of(&self) -> Option<Type> {
match self {
Component::Node(_loc,_name, typ) => Some(typ.clone()),
Component::Reg(_loc,_name, typ, _reset) => Some(typ.clone()),
Component::Dom(_loc, _name) => None,
Component::Incoming(_loc,_name, typ) => Some(typ.clone()),
Component::Outgoing(_loc,_name, typ) => Some(typ.clone()),
Component::Mod(_loc,_name, _children, _wires, _whens) => None,
Component::ModInst(_loc,_name, _defname) => None,
Component::Ext(_loc,_name, _children) => None,
}
}
pub fn reset(&self) -> Option<Arc<Expr>> {
match self {
Component::Reg(_loc, _name, _typ, reset) => reset.clone(),
_ => None
}
}
pub fn submods(&self) -> Vec<Arc<Component>> {
let mut results = vec![];
for child in self.children() {
if let Component::Mod(_loc,_name, _children, _wires, _whens) = &*child {
results.push(child.clone());
}
}
results
}
}
#[derive(Debug, Clone)]
pub struct TbDef {
pub span: Span,
pub name: String,
pub statements: Vec<TbStatement>,
}
#[derive(Debug, Clone)]
pub enum TbStatement {
Debug,
Reset,
Clock,
ModInst(String, Arc<Component>),
}