1#[macro_export]
2macro_rules! error {
3 ( $( $x:expr ),* ) => {
4 {
5 eprintln!("Error: {}",format!($($x,)*));
6 std::process::exit(1);
7 }
8 };
9}
10
11#[macro_export]
12macro_rules! file_error {
13 ( $file:expr, $content:expr, $location:expr, $error:expr ) => {{
14 let (x, y) = $crate::error::get_loc($content.clone(), $location.start)
15 .unwrap_or_else(|| $crate::error!("{} {}", $error, $file));
16 let line = $crate::error::get_line($content, y - 1)
17 .unwrap_or_else(|| $crate::error!("{} {}", $error, $file));
18 eprintln!("Error: {} {}:{}:{}", $error, $file, y, x);
19 eprintln!("{line}");
20 eprintln!("{}{}", " ".repeat(x), "^".repeat($location.len()));
21 std::process::exit(1);
22 }};
23}
24
25pub fn get_loc(content: String, location: usize) -> Option<(usize, usize)> {
26 let mut y = 0;
27 let mut current = 0;
28 for line in content.split('\n') {
29 y += 1;
30 let old = current;
31 current += 1 + line.len();
32 if old < location && current > location {
33 return Some((location - old, y));
34 }
35 }
36 None
37}
38
39pub fn get_line(content: String, line: usize) -> Option<String> {
40 Some(content.lines().nth(line)?.to_string())
41}