1use std::borrow::Cow;
10
11use logos::Span;
12
13pub use crate::asm::AsmErr;
14pub use crate::ast::OffsetNewErr;
15pub use crate::parse::lex::LexErr;
16pub use crate::parse::ParseErr;
17pub use crate::sim::SimErr;
18
19pub trait Error: std::error::Error {
26 fn span(&self) -> Option<crate::err::ErrSpan> {
30 None
31 }
32
33 fn help(&self) -> Option<Cow<str>>;
37}
38
39#[derive(Clone, PartialEq, Eq, Hash)]
46pub enum ErrSpan {
47 One(Span),
49 Two([Span; 2]),
51 Many(Vec<Span>)
55}
56impl ErrSpan {
57 pub fn first(&self) -> Span {
59 match self {
60 ErrSpan::One(r) => r.clone(),
61 ErrSpan::Two([r, _]) => r.clone(),
62 ErrSpan::Many(r) => r.first().unwrap().clone(),
63 }
64 }
65
66 pub fn iter(&self) -> impl Iterator<Item=&Span> {
68 match self {
69 ErrSpan::One(r) => std::slice::from_ref(r).iter(),
70 ErrSpan::Two(r) => r.iter(),
71 ErrSpan::Many(r) => r.iter(),
72 }
73 }
74}
75impl Extend<Span> for ErrSpan {
76 fn extend<T: IntoIterator<Item = Span>>(&mut self, iter: T) {
77 let mut iter = iter.into_iter();
78
79 loop {
81 match self {
82 ErrSpan::One(r0) => {
83 let Some(r1) = iter.next() else { return };
84 let r0 = std::mem::replace(r0, 0..0);
85 *self = ErrSpan::Two([r0, r1]);
86 },
87 ErrSpan::Two([r0, r1]) => {
88 let Some(r2) = iter.next() else { return };
89 let r0 = std::mem::replace(r0, 0..0);
90 let r1 = std::mem::replace(r1, 0..0);
91 *self = ErrSpan::Many(vec![r0, r1, r2]);
92 },
93 ErrSpan::Many(mr) => {
94 mr.extend(iter);
95 return;
96 },
97 }
98 }
99 }
100}
101impl From<Span> for ErrSpan {
102 fn from(value: Span) -> Self {
103 ErrSpan::One(value)
104 }
105}
106impl From<&[Span]> for ErrSpan {
107 fn from(value: &[Span]) -> Self {
108 match value {
109 [r0] => ErrSpan::One(r0.clone()),
110 [r0, r1] => ErrSpan::Two([r0.clone(), r1.clone()]),
111 rr => ErrSpan::Many(rr.to_vec())
112 }
113 }
114}
115impl<const N: usize> From<[Span; N]> for ErrSpan {
116 fn from(value: [Span; N]) -> Self {
117 Self::from(value.as_slice())
118 }
119}
120impl From<Vec<Span>> for ErrSpan {
121 fn from(value: Vec<Span>) -> Self {
122 match <[_; 1]>::try_from(value) {
123 Ok([r]) => ErrSpan::One(r),
124 Err(value) => match <[_; 2]>::try_from(value) {
125 Ok(r2) => ErrSpan::Two(r2),
126 Err(value) => ErrSpan::Many(value)
127 }
128 }
129 }
130}
131impl From<Vec<ErrSpan>> for ErrSpan {
132 fn from(value: Vec<ErrSpan>) -> Self {
133 let mr: Vec<_> = value.into_iter()
134 .flat_map(|r| match r {
135 ErrSpan::One(r) => vec![r],
136 ErrSpan::Two(r) => r.to_vec(),
137 ErrSpan::Many(r) => r,
138 })
139 .collect();
140
141 ErrSpan::from(mr)
142 }
143}
144impl std::fmt::Debug for ErrSpan {
145 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
146 match self {
147 Self::One(r) => r.fmt(f),
148 Self::Two(r) => r.fmt(f),
149 Self::Many(mr) => mr.fmt(f),
150 }
151 }
152}