mirror of
https://github.com/Noratrieb/dilaria.git
synced 2026-01-14 17:35:03 +01:00
78 lines
1.9 KiB
Rust
78 lines
1.9 KiB
Rust
use std::fmt::Debug;
|
|
|
|
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash)]
|
|
pub struct Span {
|
|
start: usize,
|
|
len: usize,
|
|
}
|
|
|
|
impl Span {
|
|
pub fn new(start: usize, len: usize) -> Self {
|
|
Self { start, len }
|
|
}
|
|
|
|
pub fn start_end(start: usize, end: usize) -> Self {
|
|
Self::new(start, end - start)
|
|
}
|
|
|
|
pub fn single(start: usize) -> Self {
|
|
Self { start, len: 1 }
|
|
}
|
|
}
|
|
|
|
pub trait CompilerError {
|
|
fn span(&self) -> Span;
|
|
fn message(&self) -> String;
|
|
fn note(&self) -> Option<String>;
|
|
}
|
|
|
|
pub fn display_error<E>(source: &str, error: E)
|
|
where
|
|
E: CompilerError + Debug,
|
|
{
|
|
let mut chars = 0;
|
|
let mut lines = source.split_inclusive('\n').enumerate();
|
|
while let Some((idx, line)) = lines.next() {
|
|
if chars + line.len() + 1 > error.span().start {
|
|
let offset_on_line = error.span().start - chars;
|
|
|
|
println!("{}error: {}{}", RED, error.message(), RESET);
|
|
println!(" {}|{}", CYAN, RESET);
|
|
println!(
|
|
"{}{:>5} |{} {}",
|
|
CYAN,
|
|
idx + 1,
|
|
RESET,
|
|
&line[..line.len() - 1]
|
|
);
|
|
print!(" {}|{} ", CYAN, RESET);
|
|
println!(
|
|
"{}{}{}{}",
|
|
" ".repeat(offset_on_line),
|
|
RED,
|
|
"^".repeat(error.span().len),
|
|
RESET,
|
|
);
|
|
if let Some(note) = error.note() {
|
|
println!(" {}|{}", CYAN, RESET);
|
|
println!(
|
|
" {}|{} {}note: {}{}",
|
|
CYAN, RESET, GREEN, note, RESET
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
chars += line.len();
|
|
}
|
|
}
|
|
|
|
macro_rules! color {
|
|
($name:ident: $value:literal) => {
|
|
const $name: &str = concat!("\x1B[", $value);
|
|
};
|
|
}
|
|
|
|
color!(RED: "0;31m");
|
|
color!(RESET: "0m");
|
|
color!(CYAN: "0;36m");
|
|
color!(GREEN: "0;32m");
|