bitsy_lang/
error.rs

1use super::*;
2
3use std::sync::Arc;
4
5#[derive(Debug, Clone)]
6pub enum BitsyError {
7    ExtHasNonPort(Loc, Name),
8    DuplicateComponent(Arc<Component>),
9    MultipleDrivers(Loc, Name),
10    NoDrivers(Arc<Component>),
11    WrongWireType(Loc, Name, WireType),
12    IncomingPortDriven(Loc, Name),
13    NoSuchComponent(Loc, String),
14    TypeError(TypeError),
15    ParseError(Loc, String),
16    Unknown(Option<Loc>, String),
17}
18
19#[derive(Clone, Debug)]
20pub enum TypeError {
21    UndefinedReference(Arc<Expr>),
22    NotExpectedType(Type, Type, Arc<Expr>),
23    InvalidWord(Arc<Expr>),
24    CantInferType(Arc<Expr>),
25    Other(Arc<Expr>, String),
26}
27
28impl HasLoc for TypeError {
29    fn loc(&self) -> Loc {
30        match self {
31            TypeError::UndefinedReference(e) => e.loc(),
32            TypeError::NotExpectedType(_type_expected, _type_actual, e) => e.loc(),
33            TypeError::InvalidWord(e) => e.loc(),
34            TypeError::CantInferType(e) => e.loc(),
35            TypeError::Other(e, _msg) => e.loc(),
36        }
37    }
38}
39
40impl std::fmt::Display for TypeError {
41    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
42        match self {
43            TypeError::UndefinedReference(expr) => write!(f, "Undefiend reference: {expr:?}"),
44            TypeError::NotExpectedType(type_expected, type_actual, _expr) => write!(f, "Not expected type: has type {type_actual:?} but expected {type_expected:?}."),
45            TypeError::InvalidWord(expr) => write!(f, "Invalid literal: {expr:?}"),
46            TypeError::CantInferType(expr) => write!(f, "Can't infer type: {expr:?}"),
47            TypeError::Other(_expr, message) => write!(f, "{message}"),
48        }
49    }
50}
51
52impl std::fmt::Display for BitsyError {
53    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
54        match self {
55            BitsyError::ExtHasNonPort(_loc, name) => write!(f, "Ext declares a component other than an incoming or outgoing: {name}"),
56            BitsyError::DuplicateComponent(component) => write!(f, "Duplicate component: {}", component.name()),
57            BitsyError::MultipleDrivers(_loc, name) => write!(f, "Component has multiple drivers: {name}."),
58            BitsyError::NoDrivers(component) => write!(f, "Component is not driven: {}", component.name()),
59            BitsyError::WrongWireType(_loc, name, wire_type) => {
60                let symbol = match wire_type {
61                    WireType::Direct => ":=",
62                    WireType::Latch => "<=",
63                    WireType::Proc => "<=!",
64                };
65                write!(f, "Wrong wire type: {name} does not support {symbol}")
66            },
67            BitsyError::IncomingPortDriven(_loc, name) => write!(f, "Incoming port is being driven from inside a mod, but shouldn't be: {name}"),
68            BitsyError::NoSuchComponent(_loc, s) => write!(f, "No such component: {s}"),
69            BitsyError::TypeError(type_error) => write!(f, "Type Error: {type_error}"),
70            BitsyError::ParseError(_loc, error) => write!(f, "{error}"),
71            BitsyError::Unknown(_loc, message) => write!(f, "{message}"),
72        }
73    }
74}
75
76impl HasLoc for BitsyError {
77    fn loc(&self) -> Loc {
78        match self {
79            BitsyError::ExtHasNonPort(loc, _name) => loc.clone(),
80            BitsyError::DuplicateComponent(component) => component.loc(),
81            BitsyError::MultipleDrivers(loc, _name) => loc.clone(),
82            BitsyError::NoDrivers(component) => component.loc(),
83            BitsyError::WrongWireType(loc, _name, _wire_type) => loc.clone(),
84            BitsyError::IncomingPortDriven(loc, _name) => loc.clone(),
85            BitsyError::NoSuchComponent(loc, _name) => loc.clone(),
86            BitsyError::TypeError(type_error) => type_error.loc(),
87            BitsyError::ParseError(loc, _error) => loc.clone(),
88            BitsyError::Unknown(loc, _string) => loc.clone().unwrap_or_else(|| Loc::unknown()),
89        }
90    }
91}