Skip to main content

nl_compiler/
error.rs

1/*!
2
3  Error types
4
5*/
6
7use crate::aig::U;
8use std::{fmt::Display, path::PathBuf};
9use sv_parser::{RefNode, RefNodes, SyntaxTree, unwrap_node};
10use thiserror::Error;
11
12/// Errors for Verilog Compilation.
13#[derive(Error, Debug)]
14pub struct VerilogError {
15    /// Path, line, offset
16    origin: Option<(PathBuf, usize, usize)>,
17    message: String,
18    content: String,
19}
20
21impl VerilogError {
22    /// Create a new error from an AST node
23    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/// Errors for AIG Compilation.
75#[derive(Error, Debug)]
76pub enum AigError {
77    /// Contains bad state properties.
78    #[error("Contains bad state properties `{0:?}`")]
79    ContainsBadStates(Vec<U>),
80    /// Contains latches.
81    #[error("Contains latches `{0:?}`")]
82    ContainsLatches(Vec<U>),
83    /// Attempted aig contains cycles.
84    #[error("Attempted aig contains cycles")]
85    ContainsCycle,
86    /// Attempted aig contains gates besides AND and INV.
87    #[error("Attempted aig contains gates besides AND and INV")]
88    ContainsOtherGates,
89    /// Attempted aig has disconnected gates.
90    #[error("Attempted aig has disconnected gates.")]
91    DisconnectedGates,
92    /// An error originating from `safety-net`.
93    #[error("Safety net error `{0}`")]
94    SafetyNetError(#[from] safety_net::Error),
95    /// An error originating from `flussab`.
96    #[error("flussab error `{0}`")]
97    FlussabError(#[from] flussab_aiger::aig::AigStructureError<crate::aig::U>),
98    /// An error originating from `flussab_aiger`.
99    #[error("flussab error `{0}`")]
100    AigParseError(#[from] flussab_aiger::ParseError),
101    /// An error originating from `io`.
102    #[error("IO error `{0}`")]
103    IoError(#[from] std::io::Error),
104}