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