Rustfmt on error.rs

This commit is contained in:
Greg Shuflin 2021-10-14 04:16:20 -07:00
parent 0cb0145cc5
commit 90ede076cc

View File

@ -1,99 +1,113 @@
use crate::parsing::ParseError;
use crate::schala::{SourceReference, Stage}; use crate::schala::{SourceReference, Stage};
use crate::source_map::Location; use crate::source_map::Location;
use crate::tokenizing::{Token, TokenKind}; use crate::tokenizing::{Token, TokenKind};
use crate::parsing::ParseError;
use crate::typechecking::TypeError; use crate::typechecking::TypeError;
pub struct SchalaError { pub struct SchalaError {
errors: Vec<Error>, errors: Vec<Error>,
//TODO unify these sometime //TODO unify these sometime
formatted_parse_error: Option<String>, formatted_parse_error: Option<String>,
} }
impl SchalaError { impl SchalaError {
pub(crate) fn display(&self) -> String {
pub(crate) fn display(&self) -> String { if let Some(ref err) = self.formatted_parse_error {
if let Some(ref err) = self.formatted_parse_error { err.clone()
err.clone() } else {
} else { self.errors[0].text.as_ref().cloned().unwrap_or_default()
self.errors[0].text.as_ref().cloned().unwrap_or_default() }
} }
}
pub(crate) fn from_type_error(err: TypeError) -> Self { pub(crate) fn from_type_error(err: TypeError) -> Self {
Self { Self {
formatted_parse_error: None, formatted_parse_error: None,
errors: vec![ errors: vec![Error {
Error { location: None, text: Some(err.msg), stage: Stage::Typechecking } location: None,
] text: Some(err.msg),
stage: Stage::Typechecking,
}],
}
} }
}
pub(crate) fn from_string(text: String, stage: Stage) -> Self { pub(crate) fn from_string(text: String, stage: Stage) -> Self {
Self { Self {
formatted_parse_error: None, formatted_parse_error: None,
errors: vec![ errors: vec![Error {
Error { location: None, text: Some(text), stage } location: None,
] text: Some(text),
stage,
}],
}
} }
}
pub(crate) fn from_parse_error(parse_error: ParseError, source_reference: &SourceReference) -> Self { pub(crate) fn from_parse_error(
Self { parse_error: ParseError,
formatted_parse_error: Some(format_parse_error(parse_error, source_reference)), source_reference: &SourceReference,
errors: vec![], ) -> Self {
Self {
formatted_parse_error: Some(format_parse_error(parse_error, source_reference)),
errors: vec![],
}
} }
}
pub(crate) fn from_tokens(tokens: &[Token]) -> Option<SchalaError> { pub(crate) fn from_tokens(tokens: &[Token]) -> Option<SchalaError> {
let token_errors: Vec<Error> = tokens.iter() let token_errors: Vec<Error> = tokens
.filter_map(|tok| match tok.kind { .iter()
TokenKind::Error(ref err) => Some(Error { .filter_map(|tok| match tok.kind {
location: Some(tok.location), TokenKind::Error(ref err) => Some(Error {
text: Some(err.clone()), location: Some(tok.location),
stage: Stage::Tokenizing, text: Some(err.clone()),
}), stage: Stage::Tokenizing,
_ => None }),
}).collect(); _ => None,
})
.collect();
if token_errors.is_empty() { if token_errors.is_empty() {
None None
} else { } else {
Some(SchalaError { Some(SchalaError {
errors: token_errors, errors: token_errors,
formatted_parse_error: None, formatted_parse_error: None,
}) })
}
} }
}
} }
#[allow(dead_code)] #[allow(dead_code)]
struct Error { struct Error {
location: Option<Location>, location: Option<Location>,
text: Option<String>, text: Option<String>,
stage: Stage, stage: Stage,
} }
fn format_parse_error(error: ParseError, source_reference: &SourceReference) -> String { fn format_parse_error(error: ParseError, source_reference: &SourceReference) -> String {
let line_num = error.token.location.line_num; let line_num = error.token.location.line_num;
let ch = error.token.location.char_num; let ch = error.token.location.char_num;
let line_from_program = source_reference.get_line(line_num); let line_from_program = source_reference.get_line(line_num);
let location_pointer = format!("{}^", " ".repeat(ch)); let location_pointer = format!("{}^", " ".repeat(ch));
let line_num_digits = format!("{}", line_num).chars().count(); let line_num_digits = format!("{}", line_num).chars().count();
let space_padding = " ".repeat(line_num_digits); let space_padding = " ".repeat(line_num_digits);
let production = match error.production_name { let production = match error.production_name {
Some(n) => format!("\n(from production \"{}\")", n), Some(n) => format!("\n(from production \"{}\")", n),
None => "".to_string() None => "".to_string(),
}; };
format!(r#" format!(
r#"
{error_msg}{production} {error_msg}{production}
{space_padding} | {space_padding} |
{line_num} | {} {line_num} | {}
{space_padding} | {} {space_padding} | {}
"#, line_from_program, location_pointer, error_msg=error.msg, space_padding=space_padding, line_num=line_num, production=production "#,
) line_from_program,
location_pointer,
error_msg = error.msg,
space_padding = space_padding,
line_num = line_num,
production = production
)
} }