Use true source for error formatting
This commit is contained in:
		
							parent
							
								
									df4febf1ef
								
							
						
					
					
						commit
						6dfd98eba3
					
				
							
								
								
									
										73
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										73
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -4,18 +4,21 @@ version = 4 | ||||
| 
 | ||||
| [[package]] | ||||
| name = "aho-corasick" | ||||
| version = "1.0.2" | ||||
| version = "1.1.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" | ||||
| checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" | ||||
| dependencies = [ | ||||
|  "memchr", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "cc" | ||||
| version = "1.0.79" | ||||
| version = "1.2.29" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" | ||||
| checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362" | ||||
| dependencies = [ | ||||
|  "shlex", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "colored" | ||||
| @ -28,21 +31,21 @@ dependencies = [ | ||||
| 
 | ||||
| [[package]] | ||||
| name = "lazy_static" | ||||
| version = "1.4.0" | ||||
| version = "1.5.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" | ||||
| checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "libc" | ||||
| version = "0.2.147" | ||||
| version = "0.2.174" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" | ||||
| checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "llvm-sys" | ||||
| version = "160.1.3" | ||||
| version = "160.2.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0bf51981ac0622b10fe4790763e3de1f3d68a0ee4222e03accaaab6731bd508d" | ||||
| checksum = "e73861901245d32e1c3d8b35b639cf100859b4cd0c9da56fe0273040acbb3ea4" | ||||
| dependencies = [ | ||||
|  "cc", | ||||
|  "lazy_static", | ||||
| @ -53,33 +56,33 @@ dependencies = [ | ||||
| 
 | ||||
| [[package]] | ||||
| name = "memchr" | ||||
| version = "2.5.0" | ||||
| version = "2.7.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" | ||||
| checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "proc-macro2" | ||||
| version = "1.0.66" | ||||
| version = "1.0.95" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" | ||||
| checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" | ||||
| dependencies = [ | ||||
|  "unicode-ident", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "quote" | ||||
| version = "1.0.32" | ||||
| version = "1.0.40" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" | ||||
| checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "regex" | ||||
| version = "1.9.1" | ||||
| version = "1.11.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" | ||||
| checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" | ||||
| dependencies = [ | ||||
|  "aho-corasick", | ||||
|  "memchr", | ||||
| @ -89,9 +92,9 @@ dependencies = [ | ||||
| 
 | ||||
| [[package]] | ||||
| name = "regex-automata" | ||||
| version = "0.3.4" | ||||
| version = "0.4.9" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b7b6d6190b7594385f61bd3911cd1be99dfddcfc365a4160cc2ab5bff4aed294" | ||||
| checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" | ||||
| dependencies = [ | ||||
|  "aho-corasick", | ||||
|  "memchr", | ||||
| @ -100,9 +103,9 @@ dependencies = [ | ||||
| 
 | ||||
| [[package]] | ||||
| name = "regex-syntax" | ||||
| version = "0.7.4" | ||||
| version = "0.8.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" | ||||
| checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "reid" | ||||
| @ -124,15 +127,21 @@ dependencies = [ | ||||
| 
 | ||||
| [[package]] | ||||
| name = "semver" | ||||
| version = "1.0.18" | ||||
| version = "1.0.26" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" | ||||
| checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "shlex" | ||||
| version = "1.3.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "syn" | ||||
| version = "2.0.28" | ||||
| version = "2.0.104" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" | ||||
| checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
| @ -141,18 +150,18 @@ dependencies = [ | ||||
| 
 | ||||
| [[package]] | ||||
| name = "thiserror" | ||||
| version = "1.0.44" | ||||
| version = "1.0.69" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" | ||||
| checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" | ||||
| dependencies = [ | ||||
|  "thiserror-impl", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "thiserror-impl" | ||||
| version = "1.0.44" | ||||
| version = "1.0.69" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" | ||||
| checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
| @ -161,9 +170,9 @@ dependencies = [ | ||||
| 
 | ||||
| [[package]] | ||||
| name = "unicode-ident" | ||||
| version = "1.0.11" | ||||
| version = "1.0.18" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" | ||||
| checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows-sys" | ||||
|  | ||||
| @ -5,7 +5,7 @@ use std::{ | ||||
| 
 | ||||
| use crate::{ | ||||
|     ast, | ||||
|     lexer::{self, FullToken, Position}, | ||||
|     lexer::{self, Cursor, FullToken, Position}, | ||||
|     mir::{self, pass, Metadata, SourceModuleId}, | ||||
|     token_stream::{self, TokenRange}, | ||||
| }; | ||||
| @ -79,6 +79,7 @@ impl Ord for ErrorKind { | ||||
| pub struct ErrModule { | ||||
|     pub name: String, | ||||
|     pub tokens: Option<Vec<FullToken>>, | ||||
|     pub source: Option<String>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, PartialEq, Eq, Default)] | ||||
| @ -95,6 +96,7 @@ impl ModuleMap { | ||||
|             ErrModule { | ||||
|                 name: name.into(), | ||||
|                 tokens: None, | ||||
|                 source: None, | ||||
|             }, | ||||
|         ); | ||||
|         Some(id) | ||||
| @ -106,6 +108,12 @@ impl ModuleMap { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn set_source(&mut self, id: mir::SourceModuleId, source: String) { | ||||
|         if let Some(module) = self.module_map.get_mut(&id) { | ||||
|             module.source = Some(source); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn get_module(&self, id: &mir::SourceModuleId) -> Option<&ErrModule> { | ||||
|         self.module_map.get(id) | ||||
|     } | ||||
| @ -179,11 +187,17 @@ impl std::fmt::Display for ReidError { | ||||
|             let module = self.map.get_module(&meta.source_module_id).unwrap(); | ||||
|             let (position_fmt, line_fmt) = if let Some(tokens) = &module.tokens { | ||||
|                 let range_tokens = meta.range.into_tokens(&tokens); | ||||
|                 let position = get_position(&range_tokens).unwrap(); | ||||
|                 let full_lines = get_full_lines(&tokens, position); | ||||
|                 let highlight_position = get_position(&range_tokens).unwrap(); | ||||
|                 let full_lines = get_full_lines(&tokens, highlight_position); | ||||
|                 let lines_position = get_position(&full_lines).unwrap(); | ||||
|                 ( | ||||
|                     fmt_positions(get_position(&full_lines).unwrap()), | ||||
|                     Some(fmt_tokens(&full_lines, &range_tokens)), | ||||
|                     fmt_positions(highlight_position), | ||||
|                     Some(fmt_lines( | ||||
|                         module.source.as_ref().unwrap(), | ||||
|                         lines_position, | ||||
|                         highlight_position, | ||||
|                         8, | ||||
|                     )?), | ||||
|                 ) | ||||
|             } else if let Some(position) = meta.position { | ||||
|                 (fmt_positions((position, position)), None) | ||||
| @ -209,9 +223,9 @@ impl std::fmt::Display for ReidError { | ||||
|             writeln!(f)?; | ||||
|             write!(f, "  Error: ")?; | ||||
|             writeln!(f, "{}", color_err(format!("{}", error))?)?; | ||||
|             writeln!(f, "{:>20}{}", color_warn("At: ")?, position_fmt)?; | ||||
|             write!(f, "{:>20}{}", color_warn("At: ")?, position_fmt)?; | ||||
|             if let Some(line_fmt) = line_fmt { | ||||
|                 writeln!(f, "{:>20}{}", color_warn("")?, line_fmt)?; | ||||
|                 writeln!(f, "{}", line_fmt)?; | ||||
|             } | ||||
|         } | ||||
|         Ok(()) | ||||
| @ -255,26 +269,37 @@ fn get_full_lines<'v>( | ||||
|         .collect::<Vec<_>>() | ||||
| } | ||||
| 
 | ||||
| fn fmt_tokens(tokens: &Vec<&FullToken>, highlighted: &Vec<&FullToken>) -> String { | ||||
|     let mut text = String::new(); | ||||
|     let mut last_likes_space = false; | ||||
|     for (i, token) in tokens.iter().enumerate() { | ||||
|         if token.token.needs_space() || (token.token.likes_space() && last_likes_space) { | ||||
|             text += " "; | ||||
|         } | ||||
|         last_likes_space = token.token.likes_space(); | ||||
| fn fmt_lines( | ||||
|     source: &String, | ||||
|     (line_start, line_end): (Position, Position), | ||||
|     (highlight_start, highlight_end): (Position, Position), | ||||
|     ident: usize, | ||||
| ) -> Result<String, std::fmt::Error> { | ||||
|     let mut cursor = Cursor { | ||||
|         position: Position(0, 1), | ||||
|         char_stream: source.chars(), | ||||
|     }; | ||||
| 
 | ||||
|         let mut token_fmt = format!("{}", token.token.to_string()); | ||||
|         if highlighted.contains(token) { | ||||
|             token_fmt = color_underline(token_fmt).unwrap(); | ||||
|     let mut text = String::new(); | ||||
| 
 | ||||
|     while let Some(c) = cursor.next() { | ||||
|         if cursor.position.1 > line_end.1 { | ||||
|             break; | ||||
|         } | ||||
|         text += &token_fmt; | ||||
|         if token.token.is_newline() && i > (tokens.len() - 1) { | ||||
|             text += "\n" | ||||
|         if cursor.position.1 >= line_start.1 { | ||||
|             if c == '\n' { | ||||
|                 write!(text, "\n{}", " ".repeat(ident))?; | ||||
|             } else { | ||||
|                 if cursor.position > highlight_start && cursor.position <= highlight_end { | ||||
|                     write!(text, "{}", color_highlight(c)?)?; | ||||
|                 } else { | ||||
|                     text.write_char(c)?; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     text | ||||
|     Ok(text) | ||||
| } | ||||
| 
 | ||||
| fn fmt_positions((start, end): (Position, Position)) -> String { | ||||
| @ -287,54 +312,6 @@ fn fmt_positions((start, end): (Position, Position)) -> String { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl lexer::Token { | ||||
|     fn likes_space(&self) -> bool { | ||||
|         match self { | ||||
|             lexer::Token::Identifier(_) => true, | ||||
|             lexer::Token::DecimalValue(_) => true, | ||||
|             lexer::Token::StringLit(_) => true, | ||||
|             lexer::Token::LetKeyword => true, | ||||
|             lexer::Token::MutKeyword => true, | ||||
|             lexer::Token::ImportKeyword => true, | ||||
|             lexer::Token::ReturnKeyword => true, | ||||
|             lexer::Token::FnKeyword => true, | ||||
|             lexer::Token::PubKeyword => true, | ||||
|             lexer::Token::Arrow => true, | ||||
|             lexer::Token::If => true, | ||||
|             lexer::Token::Else => true, | ||||
|             lexer::Token::True => true, | ||||
|             lexer::Token::False => true, | ||||
|             lexer::Token::Extern => true, | ||||
|             lexer::Token::Struct => true, | ||||
|             lexer::Token::Equals => true, | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn needs_space(&self) -> bool { | ||||
|         match self { | ||||
|             lexer::Token::LetKeyword => true, | ||||
|             lexer::Token::MutKeyword => true, | ||||
|             lexer::Token::ImportKeyword => true, | ||||
|             lexer::Token::ReturnKeyword => true, | ||||
|             lexer::Token::FnKeyword => true, | ||||
|             lexer::Token::PubKeyword => true, | ||||
|             lexer::Token::Arrow => true, | ||||
|             lexer::Token::Equals => true, | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn is_newline(&self) -> bool { | ||||
|         match self { | ||||
|             lexer::Token::Semi => true, | ||||
|             lexer::Token::BraceOpen => true, | ||||
|             lexer::Token::BraceClose => true, | ||||
|             _ => false, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn color_err(elem: impl std::fmt::Display) -> Result<String, std::fmt::Error> { | ||||
|     let mut text = format!("{}", elem); | ||||
| 
 | ||||
| @ -359,7 +336,7 @@ fn color_warn(elem: impl std::fmt::Display) -> Result<String, std::fmt::Error> { | ||||
|     Ok(text) | ||||
| } | ||||
| 
 | ||||
| fn color_underline(elem: impl std::fmt::Display) -> Result<String, std::fmt::Error> { | ||||
| fn color_highlight(elem: impl std::fmt::Display) -> Result<String, std::fmt::Error> { | ||||
|     let mut text = format!("{}", elem); | ||||
| 
 | ||||
|     #[cfg(feature = "color")] | ||||
|  | ||||
| @ -167,7 +167,7 @@ impl Debug for FullToken { | ||||
| } | ||||
| 
 | ||||
| /// (Column, Line)
 | ||||
| #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] | ||||
| #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Ord)] | ||||
| pub struct Position(pub u32, pub u32); | ||||
| 
 | ||||
| impl Position { | ||||
| @ -180,13 +180,23 @@ impl Position { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| struct Cursor<'a> { | ||||
| impl PartialOrd for Position { | ||||
|     fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { | ||||
|         match self.1.partial_cmp(&other.1) { | ||||
|             Some(core::cmp::Ordering::Equal) => {} | ||||
|             ord => return ord, | ||||
|         } | ||||
|         self.0.partial_cmp(&other.0) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct Cursor<'a> { | ||||
|     pub position: Position, | ||||
|     char_stream: Chars<'a>, | ||||
|     pub char_stream: Chars<'a>, | ||||
| } | ||||
| 
 | ||||
| impl<'a> Cursor<'a> { | ||||
|     fn next(&mut self) -> Option<char> { | ||||
|     pub fn next(&mut self) -> Option<char> { | ||||
|         let next = self.char_stream.next(); | ||||
|         if let Some('\n') = next { | ||||
|             self.position.1 += 1; | ||||
|  | ||||
| @ -68,6 +68,7 @@ pub fn parse_module<'map, T: Into<String>>( | ||||
|     map: &'map mut ModuleMap, | ||||
| ) -> Result<(mir::SourceModuleId, Vec<FullToken>), ReidError> { | ||||
|     let id = map.add_module(name.into()).unwrap(); | ||||
|     map.set_source(id, source.to_owned()); | ||||
| 
 | ||||
|     let tokens = ReidError::from_lexer(lexer::tokenize(source), map.clone(), id)?; | ||||
| 
 | ||||
| @ -137,8 +138,6 @@ pub fn perform_all_passes<'map>( | ||||
| 
 | ||||
|     let refs = TypeRefs::default(); | ||||
| 
 | ||||
|     let mut errors = Vec::new(); | ||||
| 
 | ||||
|     let state = context.pass(&mut TypeInference { refs: &refs }); | ||||
| 
 | ||||
|     #[cfg(debug_assertions)] | ||||
| @ -148,13 +147,16 @@ pub fn perform_all_passes<'map>( | ||||
|     #[cfg(debug_assertions)] | ||||
|     dbg!(&state); | ||||
| 
 | ||||
|     errors.extend( | ||||
|         state | ||||
|             .errors | ||||
|             .iter() | ||||
|             .map(|e| ErrorRapKind::TypeInferenceError(e.clone())) | ||||
|             .collect::<Vec<_>>(), | ||||
|     ); | ||||
|     if !state.errors.is_empty() { | ||||
|         return Err(ReidError::from_kind::<()>( | ||||
|             state | ||||
|                 .errors | ||||
|                 .iter() | ||||
|                 .map(|e| ErrorRapKind::TypeInferenceError(e.clone())) | ||||
|                 .collect::<Vec<_>>(), | ||||
|             module_map.clone(), | ||||
|         )); | ||||
|     } | ||||
| 
 | ||||
|     let state = context.pass(&mut TypeCheck { refs: &refs }); | ||||
| 
 | ||||
| @ -163,16 +165,15 @@ pub fn perform_all_passes<'map>( | ||||
|     #[cfg(debug_assertions)] | ||||
|     dbg!(&state); | ||||
| 
 | ||||
|     errors.extend( | ||||
|         state | ||||
|             .errors | ||||
|             .iter() | ||||
|             .map(|e| ErrorRapKind::TypeInferenceError(e.clone())) | ||||
|             .collect::<Vec<_>>(), | ||||
|     ); | ||||
| 
 | ||||
|     if !errors.is_empty() { | ||||
|         return Err(ReidError::from_kind::<()>(errors, module_map.clone())); | ||||
|     if !state.errors.is_empty() { | ||||
|         return Err(ReidError::from_kind::<()>( | ||||
|             state | ||||
|                 .errors | ||||
|                 .iter() | ||||
|                 .map(|e| ErrorRapKind::TypeCheckError(e.clone())) | ||||
|                 .collect::<Vec<_>>(), | ||||
|             module_map.clone(), | ||||
|         )); | ||||
|     } | ||||
| 
 | ||||
|     Ok(()) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user