1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use std::fmt;
use nom::Finish;
use owo_colors::OwoColorize;
use super::{
parser,
span::{Span, Spanned},
};
#[derive(Debug)]
pub struct AssemblerError {
span: Span,
quoted: (String, bool),
msg: String,
}
impl AssemblerError {
pub(crate) fn new<S: ToString>(nom_span: parser::NomSpan<'_>, msg: S) -> Self {
let span = Span::from_nom(
&nom_span,
nom_span
.chars()
.take_while(|&c| !c.is_whitespace() && c != ';')
.count(),
);
let quoted = nom_span
.extra
.extract_line(nom_span.location_offset())
.to_owned();
Self {
span,
quoted: (quoted, false),
msg: msg.to_string(),
}
}
pub(crate) fn custom<S: ToString, T>(input: &str, span: Spanned<T>, msg: S) -> Self {
let span = span.into_span();
let quoted = format!(
"{dots}{line}{dots}",
dots = "...".blue(),
line = &input[&span]
);
Self {
span,
quoted: (quoted, true),
msg: msg.to_string(),
}
}
pub fn span(&self) -> &Span {
&self.span
}
pub fn quoted(&self) -> &str {
&self.quoted.0
}
pub fn message(&self) -> &str {
&self.msg
}
pub(crate) fn check_tokenization<'t>(
result: nom::IResult<parser::NomSpan<'t>, Vec<parser::Statement<'t>>>,
) -> Result<Vec<parser::Statement<'t>>, Self> {
match result.finish() {
Ok((_, tokens)) => Ok(tokens),
Err(e) => Err(Self::new(e.input, "Unparseable tokens detected")),
}
}
}
impl fmt::Display for AssemblerError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"at line {}, column {}: {}",
self.span().line(),
self.span().column(),
self.msg
)
}
}
impl std::error::Error for AssemblerError {}