improved error messages

- some small bugs are now fixed
- include comments in error messages (if this causes issues, use --hide-comments)
- colors should make more sense now
- error-related things moved to mers_lib/src/errors/
This commit is contained in:
Mark
2023-11-16 14:50:09 +01:00
parent c39e784939
commit 12925fed67
33 changed files with 462 additions and 320 deletions

View File

@@ -1 +0,0 @@

View File

@@ -1,8 +1,10 @@
use std::sync::Arc;
use crate::program::{self, parsed::block::Block, run::CheckError};
use crate::{
errors::{CheckError, SourcePos},
program::{self, parsed::block::Block},
};
pub mod errors;
pub mod statements;
pub mod types;
@@ -20,7 +22,7 @@ pub struct Source {
src_raw_len: usize,
src_og: String,
src: String,
/// (start, content) of each comment, including start/end (//, \n, /* and */)
/// (start, content) of each comment, including start/end (//, /* and */), but NOT newline after //
comments: Vec<(usize, String)>,
i: usize,
sections: Vec<SectionMarker>,
@@ -36,13 +38,15 @@ impl Source {
if let Some((i, ch)) = chars.next() {
match in_comment {
Some(false) => {
comment.1.push(ch);
if ch == '\n' {
src.push('\n');
in_comment = None;
comments.push((
comment.0,
std::mem::replace(&mut comment.1, String::new()),
));
} else {
comment.1.push(ch);
}
}
Some(true) => {
@@ -223,6 +227,20 @@ impl Source {
}
o
}
pub fn pos_in_og(&self, mut pos: usize, inclusive: bool) -> usize {
for (start, comment) in &self.comments {
if *start < pos || (inclusive && *start == pos) {
pos += comment.len();
} else {
break;
}
}
pos
}
pub fn src_og(&self) -> &String {
&self.src_og
}
}
impl Drop for Source {
@@ -261,14 +279,3 @@ impl SectionMarker {
}
}
}
#[derive(Clone, Copy, Debug)]
pub struct SourcePos(usize);
impl SourcePos {
pub fn pos(&self) -> usize {
self.0
}
fn diff(&self, rhs: &Self) -> usize {
rhs.0 - self.0
}
}

View File

@@ -3,11 +3,8 @@ use std::fs;
use super::{Source, SourcePos};
use crate::{
data::Data,
program::{
self,
parsed::MersStatement,
run::{error_colors, CheckError},
},
errors::{error_colors, CheckError},
program::{self, parsed::MersStatement},
};
pub fn parse(
@@ -19,6 +16,7 @@ pub fn parse(
} else {
return Ok(None);
};
let mut pos_after_first = src.get_pos();
src.skip_whitespace();
match src.peek_word() {
":=" => {
@@ -68,15 +66,15 @@ pub fn parse(
});
}
_ => loop {
let pos_in_src = src.get_pos();
src.skip_whitespace();
let dot_in_src = src.get_pos();
if let Some('.') = src.peek_char() {
src.next_char();
let chained = match parse_no_chain(src) {
Ok(Some(v)) => v,
Ok(None) => {
return Err(CheckError::new()
.src(vec![((pos_in_src, src.get_pos()).into(), None)])
.src(vec![((dot_in_src, src.get_pos()).into(), None)])
.msg(format!("EOF after `.`")))
}
Err(e) => return Err(e),
@@ -91,11 +89,13 @@ pub fn parse(
});
}
first = Box::new(program::parsed::chain::Chain {
pos_in_src: (pos_in_src, src.get_pos()).into(),
pos_in_src: (first.source_range().start(), src.get_pos()).into(),
first,
chained,
});
pos_after_first = src.get_pos();
} else {
src.set_pos(pos_after_first);
break;
}
},