1use crate::aig::U;
8use std::{fmt::Display, path::PathBuf};
9use sv_parser::{RefNode, RefNodes, SyntaxTree, unwrap_node};
10use thiserror::Error;
11
12#[derive(Error, Debug)]
14pub struct VerilogError {
15 origin: Option<(PathBuf, usize)>,
16 message: String,
17 content: String,
18}
19
20impl VerilogError {
21 pub fn new<'a, T: Into<RefNodes<'a>> + Into<RefNode<'a>> + Clone, K>(
23 ast: &'a SyntaxTree,
24 nodes: T,
25 message: String,
26 ) -> Result<K, Self> {
27 let content = match ast.get_str_trim(nodes.clone()) {
28 Some(s) => s.lines().next().unwrap_or("").to_string(),
29 None => String::new(),
30 };
31 let rn: RefNode<'_> = nodes.into();
32 let locate = match unwrap_node!(rn, Locate) {
33 Some(RefNode::Locate(l)) => Some(*l),
34 _ => None,
35 };
36 let origin = match locate {
37 Some(l) => ast.get_origin(&l),
38 None => None,
39 };
40 let origin = origin.map(|(p, l)| (p.clone(), l));
41 Err(Self {
42 origin,
43 message,
44 content,
45 })
46 }
47}
48
49impl Default for VerilogError {
50 fn default() -> Self {
51 Self {
52 origin: None,
53 message: "Source text is missing".to_string(),
54 content: String::new(),
55 }
56 }
57}
58
59impl Display for VerilogError {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 if let Some((path, line)) = &self.origin {
62 write!(f, "{}:{}: ", path.display(), line)?;
63 }
64 writeln!(f, "{}", self.message)?;
65 if !self.content.is_empty() {
66 writeln!(f, "> {}", self.content)?;
67 }
68 Ok(())
69 }
70}
71
72#[derive(Error, Debug)]
74pub enum AigError {
75 #[error("Contains bad state properties `{0:?}`")]
77 ContainsBadStates(Vec<U>),
78 #[error("Contains latches `{0:?}`")]
80 ContainsLatches(Vec<U>),
81 #[error("Attempted aig contains cycles")]
83 ContainsCycle,
84 #[error("Attempted aig contains gates besides AND and INV")]
86 ContainsOtherGates,
87 #[error("Attempted aig has disconnected gates.")]
89 DisconnectedGates,
90 #[error("Safety net error `{0}`")]
92 SafetyNetError(#[from] safety_net::Error),
93 #[error("flussab error `{0}`")]
95 FlussabError(#[from] flussab_aiger::aig::AigStructureError<crate::aig::U>),
96 #[error("flussab error `{0}`")]
98 AigParseError(#[from] flussab_aiger::ParseError),
99 #[error("IO error `{0}`")]
101 IoError(#[from] std::io::Error),
102}