2022-06-18 21:56:31 -07:00
|
|
|
use super::*;
|
2017-11-16 23:30:08 -08:00
|
|
|
|
2024-01-08 13:26:33 -08:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
|
2019-12-07 03:09:21 -08:00
|
|
|
pub(crate) struct Token<'src> {
|
2023-11-21 20:17:38 -08:00
|
|
|
pub(crate) column: usize,
|
|
|
|
pub(crate) kind: TokenKind,
|
2019-09-21 15:35:03 -07:00
|
|
|
pub(crate) length: usize,
|
2021-09-16 06:44:40 -07:00
|
|
|
pub(crate) line: usize,
|
2023-11-21 20:17:38 -08:00
|
|
|
pub(crate) offset: usize,
|
|
|
|
pub(crate) path: &'src Path,
|
2021-09-16 06:44:40 -07:00
|
|
|
pub(crate) src: &'src str,
|
2017-11-16 23:30:08 -08:00
|
|
|
}
|
|
|
|
|
2019-12-07 03:09:21 -08:00
|
|
|
impl<'src> Token<'src> {
|
|
|
|
pub(crate) fn lexeme(&self) -> &'src str {
|
2019-11-07 10:55:15 -08:00
|
|
|
&self.src[self.offset..self.offset + self.length]
|
2019-04-15 22:40:02 -07:00
|
|
|
}
|
|
|
|
|
2021-07-26 01:26:06 -07:00
|
|
|
pub(crate) fn error(&self, kind: CompileErrorKind<'src>) -> CompileError<'src> {
|
2022-09-11 01:41:24 -07:00
|
|
|
CompileError::new(*self, kind)
|
2019-11-13 19:32:50 -08:00
|
|
|
}
|
2021-07-28 18:06:57 -07:00
|
|
|
}
|
2019-11-13 19:32:50 -08:00
|
|
|
|
2021-07-28 18:06:57 -07:00
|
|
|
impl<'src> ColorDisplay for Token<'src> {
|
|
|
|
fn fmt(&self, f: &mut Formatter, color: Color) -> fmt::Result {
|
2019-11-13 19:32:50 -08:00
|
|
|
let width = if self.length == 0 { 1 } else { self.length };
|
|
|
|
|
|
|
|
let line_number = self.line.ordinal();
|
|
|
|
match self.src.lines().nth(self.line) {
|
|
|
|
Some(line) => {
|
|
|
|
let mut i = 0;
|
|
|
|
let mut space_column = 0;
|
|
|
|
let mut space_line = String::new();
|
|
|
|
let mut space_width = 0;
|
|
|
|
for c in line.chars() {
|
|
|
|
if c == '\t' {
|
|
|
|
space_line.push_str(" ");
|
|
|
|
if i < self.column {
|
|
|
|
space_column += 4;
|
|
|
|
}
|
|
|
|
if i >= self.column && i < self.column + width {
|
|
|
|
space_width += 4;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if i < self.column {
|
|
|
|
space_column += UnicodeWidthChar::width(c).unwrap_or(0);
|
|
|
|
}
|
|
|
|
if i >= self.column && i < self.column + width {
|
|
|
|
space_width += UnicodeWidthChar::width(c).unwrap_or(0);
|
|
|
|
}
|
|
|
|
space_line.push(c);
|
|
|
|
}
|
|
|
|
i += c.len_utf8();
|
|
|
|
}
|
|
|
|
let line_number_width = line_number.to_string().len();
|
2023-11-21 20:17:38 -08:00
|
|
|
writeln!(
|
|
|
|
f,
|
|
|
|
"{:width$}{} {}:{}:{}",
|
|
|
|
"",
|
2023-12-29 13:25:30 -08:00
|
|
|
color.context().paint("——▶"),
|
2023-11-21 20:17:38 -08:00
|
|
|
self.path.display(),
|
|
|
|
line_number,
|
|
|
|
self.column.ordinal(),
|
|
|
|
width = line_number_width
|
|
|
|
)?;
|
|
|
|
writeln!(
|
|
|
|
f,
|
|
|
|
"{:width$} {}",
|
|
|
|
"",
|
2023-12-29 13:25:30 -08:00
|
|
|
color.context().paint("│"),
|
2023-11-21 20:17:38 -08:00
|
|
|
width = line_number_width
|
|
|
|
)?;
|
|
|
|
writeln!(
|
|
|
|
f,
|
|
|
|
"{} {space_line}",
|
2023-12-29 13:25:30 -08:00
|
|
|
color.context().paint(&format!("{line_number} │"))
|
2023-11-21 20:17:38 -08:00
|
|
|
)?;
|
|
|
|
write!(
|
|
|
|
f,
|
|
|
|
"{:width$} {}",
|
|
|
|
"",
|
2023-12-29 13:25:30 -08:00
|
|
|
color.context().paint("│"),
|
2023-11-21 20:17:38 -08:00
|
|
|
width = line_number_width
|
|
|
|
)?;
|
2019-11-13 19:32:50 -08:00
|
|
|
write!(
|
2021-07-28 18:06:57 -07:00
|
|
|
f,
|
2019-11-13 19:32:50 -08:00
|
|
|
" {0:1$}{2}{3:^<4$}{5}",
|
|
|
|
"",
|
|
|
|
space_column,
|
|
|
|
color.prefix(),
|
|
|
|
"",
|
2021-03-28 22:38:07 -07:00
|
|
|
space_width.max(1),
|
2019-11-13 19:32:50 -08:00
|
|
|
color.suffix()
|
|
|
|
)?;
|
2021-09-16 06:44:40 -07:00
|
|
|
}
|
|
|
|
None => {
|
2019-11-13 19:32:50 -08:00
|
|
|
if self.offset != self.src.len() {
|
|
|
|
write!(
|
2021-07-28 18:06:57 -07:00
|
|
|
f,
|
2023-01-26 18:49:03 -08:00
|
|
|
"internal error: Error has invalid line number: {line_number}"
|
2021-05-07 00:14:38 -07:00
|
|
|
)?;
|
2021-09-16 06:44:40 -07:00
|
|
|
}
|
|
|
|
}
|
2017-11-16 23:30:08 -08:00
|
|
|
}
|
2021-07-26 01:26:06 -07:00
|
|
|
|
2019-11-13 19:32:50 -08:00
|
|
|
Ok(())
|
2017-11-16 23:30:08 -08:00
|
|
|
}
|
|
|
|
}
|