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}