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    origin: Option<(PathBuf, usize)>,
16    message: String,
17    content: String,
18}
19
20impl VerilogError {
21    /// Create a new error from an AST node
22    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/// Errors for AIG Compilation.
73#[derive(Error, Debug)]
74pub enum AigError {
75    /// Contains bad state properties.
76    #[error("Contains bad state properties `{0:?}`")]
77    ContainsBadStates(Vec<U>),
78    /// Contains latches.
79    #[error("Contains latches `{0:?}`")]
80    ContainsLatches(Vec<U>),
81    /// Attempted aig contains cycles.
82    #[error("Attempted aig contains cycles")]
83    ContainsCycle,
84    /// Attempted aig contains gates besides AND and INV.
85    #[error("Attempted aig contains gates besides AND and INV")]
86    ContainsOtherGates,
87    /// Attempted aig has disconnected gates.
88    #[error("Attempted aig has disconnected gates.")]
89    DisconnectedGates,
90    /// An error originating from `safety-net`.
91    #[error("Safety net error `{0}`")]
92    SafetyNetError(#[from] safety_net::Error),
93    /// An error originating from `flussab`.
94    #[error("flussab error `{0}`")]
95    FlussabError(#[from] flussab_aiger::aig::AigStructureError<crate::aig::U>),
96    /// An error originating from `flussab_aiger`.
97    #[error("flussab error `{0}`")]
98    AigParseError(#[from] flussab_aiger::ParseError),
99    /// An error originating from `io`.
100    #[error("IO error `{0}`")]
101    IoError(#[from] std::io::Error),
102}