diff --git a/src/lib.rs b/src/lib.rs index 04f3f8f..6ed733f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,3 @@ pub mod backend; pub mod ir; -pub mod pass_result; pub mod syntax; diff --git a/src/pass_result.rs b/src/pass_result.rs deleted file mode 100644 index ff2c066..0000000 --- a/src/pass_result.rs +++ /dev/null @@ -1,36 +0,0 @@ -pub mod errors; -pub mod warnings; - -use crate::syntax::ParserError; - -pub use self::errors::Error; -pub use self::warnings::Warning; - -pub struct PassResult { - pub result: Option, - pub warnings: Vec, - pub errors: Vec, -} - -impl From for PassResult { - fn from(value: ParserError) -> Self { - PassResult { - result: None, - warnings: vec![], - errors: vec![Error::ParserError(value)], - } - } -} - -impl From for PassResult -where - Error: From, -{ - fn from(x: E) -> Self { - PassResult { - result: None, - warnings: vec![], - errors: vec![Error::from(x)], - } - } -} diff --git a/src/pass_result/errors.rs b/src/pass_result/errors.rs deleted file mode 100644 index 0c04343..0000000 --- a/src/pass_result/errors.rs +++ /dev/null @@ -1,124 +0,0 @@ -use crate::syntax::{Location, ParserError}; -use codespan_reporting::diagnostic::Diagnostic; -use codespan_reporting::files; -use std::io; - -#[derive(Debug)] -pub enum Error { - IOError(io::Error), - InternalFileDBError(files::Error), - ParserError(ParserError), - BindingSiteFailure(Location, String), - UnboundVariable(Location, String), - InternalError(Location, String), -} - -fn display_expected(expected: &[String]) -> String { - match expected.len() { - 0 => "".to_string(), - 1 => format!("; expected {}", expected[0]), - 2 => format!("; expected {} or {}", expected[0], expected[1]), - n => format!( - "; expected {}or {}", - comma_separate(&expected[0..n - 1]), - expected[n - 1] - ), - } -} - -fn comma_separate(strings: &[String]) -> String { - let mut result = String::new(); - - for s in strings.iter() { - result.push_str(s); - result.push_str(", "); - } - - result -} - -impl<'a> From<&'a ParserError> for Diagnostic { - fn from(value: &ParserError) -> Self { - match value { - // this was just a token we didn't understand - ParserError::InvalidToken(location) => location - .labelled_error("extremely odd token") - .with_message("encountered extremely confusing token"), - - // unexpected EOF! - ParserError::UnrecognizedEOF(location, expected) => location.error().with_message( - format!("expected enf of file{}", display_expected(expected)), - ), - - // encountered a token where it shouldn't be - ParserError::UnrecognizedToken(start, end, token, expected) => { - let expected_str = - format!("unexpected token {}{}", token, display_expected(expected)); - let unexpected_str = format!("unexpected token {}", token); - let mut labels = start.range_label(end); - - Diagnostic::error() - .with_labels( - labels - .drain(..) - .map(|l| l.with_message(unexpected_str.clone())) - .collect(), - ) - .with_message(expected_str) - } - - // I think we get this when we get a token, but were expected EOF - ParserError::ExtraToken(start, token, end) => { - let expected_str = - format!("unexpected token {} after the expected end of file", token); - let unexpected_str = format!("unexpected token {}", token); - let mut labels = start.range_label(end); - - Diagnostic::error() - .with_labels( - labels - .drain(..) - .map(|l| l.with_message(unexpected_str.clone())) - .collect(), - ) - .with_message(expected_str) - } - - // simple lexer errors - ParserError::LexFailure(location) => { - location.error().with_message("unexpected character") - } - - ParserError::FileDatabaseError(e) => Diagnostic::error().with_message(e.to_string()), - - ParserError::ReadError(e) => Diagnostic::error().with_message(e.to_string()), - } - } -} - -impl From for Diagnostic { - fn from(x: Error) -> Self { - match &x { - Error::IOError(e) => Diagnostic::error().with_message(format!("{}", e)), - - Error::InternalFileDBError(e) => Diagnostic::error().with_message(format!("{}", e)), - - Error::ParserError(pe) => pe.into(), - - Error::BindingSiteFailure(location, name) => location - .labelled_error("discovered here") - .with_message(format!( - "Internal Error: Lost binding site for bound variable {}", - name - )), - - Error::UnboundVariable(location, name) => location - .labelled_error("unbound here") - .with_message(format!("Unbound variable '{}'", name)), - - Error::InternalError(location, string) => location - .labelled_error("this is related") - .with_message(format!("Internal error: {}", string)), - } - } -} diff --git a/src/pass_result/warnings.rs b/src/pass_result/warnings.rs deleted file mode 100644 index bb14086..0000000 --- a/src/pass_result/warnings.rs +++ /dev/null @@ -1,22 +0,0 @@ -use crate::syntax::Location; -use codespan_reporting::diagnostic::Diagnostic; - -#[derive(Debug, PartialEq, Eq)] -pub enum Warning { - ShadowedVariable(Location, Location, String), -} - -impl From for Diagnostic { - fn from(x: Warning) -> Self { - match &x { - Warning::ShadowedVariable(original, new, name) => Diagnostic::warning() - .with_labels(vec![ - new.primary_label().with_message("variable rebound here"), - original - .secondary_label() - .with_message("original binding site"), - ]) - .with_message(format!("Variable '{}' is rebound", name)), - } - } -} diff --git a/src/syntax.rs b/src/syntax.rs index 4f44395..de64c7d 100644 --- a/src/syntax.rs +++ b/src/syntax.rs @@ -1,4 +1,4 @@ -use codespan_reporting::files::SimpleFiles; +use codespan_reporting::{files::SimpleFiles, diagnostic::Diagnostic}; use lalrpop_util::lalrpop_mod; use logos::Logos; @@ -74,6 +74,89 @@ impl ParserError { } } +fn display_expected(expected: &[String]) -> String { + match expected.len() { + 0 => "".to_string(), + 1 => format!("; expected {}", expected[0]), + 2 => format!("; expected {} or {}", expected[0], expected[1]), + n => format!( + "; expected {}or {}", + comma_separate(&expected[0..n - 1]), + expected[n - 1] + ), + } +} + +fn comma_separate(strings: &[String]) -> String { + let mut result = String::new(); + + for s in strings.iter() { + result.push_str(s); + result.push_str(", "); + } + + result +} + +impl<'a> From<&'a ParserError> for Diagnostic { + fn from(value: &ParserError) -> Self { + match value { + // this was just a token we didn't understand + ParserError::InvalidToken(location) => location + .labelled_error("extremely odd token") + .with_message("encountered extremely confusing token"), + + // unexpected EOF! + ParserError::UnrecognizedEOF(location, expected) => location.error().with_message( + format!("expected enf of file{}", display_expected(expected)), + ), + + // encountered a token where it shouldn't be + ParserError::UnrecognizedToken(start, end, token, expected) => { + let expected_str = + format!("unexpected token {}{}", token, display_expected(expected)); + let unexpected_str = format!("unexpected token {}", token); + let mut labels = start.range_label(end); + + Diagnostic::error() + .with_labels( + labels + .drain(..) + .map(|l| l.with_message(unexpected_str.clone())) + .collect(), + ) + .with_message(expected_str) + } + + // I think we get this when we get a token, but were expected EOF + ParserError::ExtraToken(start, token, end) => { + let expected_str = + format!("unexpected token {} after the expected end of file", token); + let unexpected_str = format!("unexpected token {}", token); + let mut labels = start.range_label(end); + + Diagnostic::error() + .with_labels( + labels + .drain(..) + .map(|l| l.with_message(unexpected_str.clone())) + .collect(), + ) + .with_message(expected_str) + } + + // simple lexer errors + ParserError::LexFailure(location) => { + location.error().with_message("unexpected character") + } + + ParserError::FileDatabaseError(e) => Diagnostic::error().with_message(e.to_string()), + + ParserError::ReadError(e) => Diagnostic::error().with_message(e.to_string()), + } + } +} + impl Program { pub fn parse_file( file_database: &mut SimpleFiles,