cmtc 0.1.2

The cmtc compiler providing cmtir-based passes to generate backends including FIRRTL, SystemVerilog and simulators.
Documentation
use std::fmt::Debug;

use super::*;

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RuleId {
  pub module_name: String,
  pub rule_name: String,
}

impl ToString for RuleId {
  fn to_string(&self) -> String {
    format!("{}::{}", self.module_name, self.rule_name)
  }
}

impl From<(String, String)> for RuleId {
  fn from(value: (String, String)) -> Self {
    Self {
      module_name: value.0,
      rule_name: value.1,
    }
  }
}

impl RuleId {
  pub fn from(callee_name: &str, rule_name: &str) -> Self {
    Self {
      module_name: callee_name.to_string(),
      rule_name: rule_name.to_string(),
    }
  }
  pub fn to_string(&self) -> String {
    format!("{}::{}", self.module_name, self.rule_name)
  }
}

pub struct TopoSolver<T: Clone> {
  pub digraph: DiGraph<T, ()>,
  pub mapping: HashMap<String, NodeIndex<u32>>,
}

impl<T: Clone + Debug> TopoSolver<T> {
  pub fn new(nodes_with_name: impl IntoIterator<Item = (String, T)>) -> Self {
    let mut digraph = DiGraph::<T, ()>::new();
    let mut mapping = HashMap::new();
    for (name, data) in nodes_with_name {
      let node_index = digraph.add_node(data);
      mapping.insert(name, node_index);
    }
    Self { digraph, mapping }
  }

  pub fn add_edge(&mut self, u: String, v: String) {
    if let Some(u) = self.mapping.get(&u) {
      if let Some(v) = self.mapping.get(&v) {
        self.digraph.add_edge(*u, *v, ());
      } else {
        log::error!("node {} not found", v);
        panic!("node {} not found", v);
      }
    } else {
      log::error!("node {} not found", u);
      panic!("node {} not found", u);
    }
  }

  pub fn topo_sort(&self) -> Vec<T> {
    let topo_order = match petgraph::algo::toposort(&self.digraph, None) {
      Ok(topo_order) => topo_order,
      Err(_e) => {
        let dot = petgraph::dot::Dot::new(&self.digraph);
        log::error!("topo sort failed: \n {:?}", dot);
        panic!("topo sort failed");
      }
    };
    topo_order
      .into_iter()
      .map(|node| self.digraph.node_weight(node).unwrap().clone())
      .collect()
  }
}