diff --git a/schala-lang/codegen/src/lib.rs b/schala-lang/codegen/src/lib.rs index 38ea171..38dd902 100644 --- a/schala-lang/codegen/src/lib.rs +++ b/schala-lang/codegen/src/lib.rs @@ -34,7 +34,6 @@ impl Fold for RecursiveDescentFn { } result.map_err(|mut parse_error: ParseError| { - parse_error.production_name = Some(stringify!(#ident).to_string()); parse_error }) } diff --git a/schala-lang/language/src/error.rs b/schala-lang/language/src/error.rs index 3f0cddd..78a9afc 100644 --- a/schala-lang/language/src/error.rs +++ b/schala-lang/language/src/error.rs @@ -82,27 +82,18 @@ struct Error { } fn format_parse_error(error: ParseError, source_reference: &SourceReference) -> String { - /* - let line_num = error.token.location.line_num; - let ch = error.token.location.char_num; - */ - let line_num = 1; - let ch = 4; + let offset = error.location.offset; + let (line_start, line_num, line_from_program) = source_reference.get_line(offset); + let ch = offset - line_start; - let line_from_program = source_reference.get_line(line_num as usize); let location_pointer = format!("{}^", " ".repeat(ch)); let line_num_digits = format!("{}", line_num).chars().count(); let space_padding = " ".repeat(line_num_digits); - let production = match error.production_name { - Some(n) => format!("\n(from production \"{}\")", n), - None => "".to_string(), - }; - format!( r#" -{error_msg}{production} +{error_msg} {space_padding} | {line_num} | {} {space_padding} | {} @@ -112,6 +103,5 @@ fn format_parse_error(error: ParseError, source_reference: &SourceReference) -> error_msg = error.msg, space_padding = space_padding, line_num = line_num, - production = production ) } diff --git a/schala-lang/language/src/parsing/mod.rs b/schala-lang/language/src/parsing/mod.rs index 02b554d..7d82575 100644 --- a/schala-lang/language/src/parsing/mod.rs +++ b/schala-lang/language/src/parsing/mod.rs @@ -182,15 +182,15 @@ use crate::{ /// Represents a parsing error #[derive(Debug)] pub struct ParseError { - pub production_name: Option, pub msg: String, + pub location: Location, pub token: Token, } impl ParseError { fn new_with_token(msg: M, token: Token) -> ParseResult where M: Into { - Err(ParseError { msg: msg.into(), token, production_name: None }) + Err(ParseError { msg: msg.into(), location: Default::default(), token, }) } } @@ -298,7 +298,7 @@ impl Parser { next_token = Some(&r.next_token); format!(", next token: {}", r.next_token) }; - buf.push_str(&format!("{}`{}`{}\n", indent, r.production_name, effective_token)); + buf.push_str(&format!("{}`{}`{}\n", indent, "XXX", effective_token)); } buf } diff --git a/schala-lang/language/src/parsing/new.rs b/schala-lang/language/src/parsing/new.rs index c5b60d2..8069c9e 100644 --- a/schala-lang/language/src/parsing/new.rs +++ b/schala-lang/language/src/parsing/new.rs @@ -25,13 +25,14 @@ impl Parser { pub(crate) fn parse( &mut self, input: &str, - _source_reference: &SourceReference, ) -> Result { - schala_parser::program(input, self).map_err(|err: peg::error::ParseError<_>| { + use peg::str::LineCol; + + schala_parser::program(input, self).map_err(|err: peg::error::ParseError| { let msg = err.to_string(); ParseError { - production_name: Some("some-production".to_string()), msg, + location: err.location.offset.into(), token: crate::tokenizing::Token { kind: crate::tokenizing::TokenKind::Semicolon, location: Default::default(), diff --git a/schala-lang/language/src/schala.rs b/schala-lang/language/src/schala.rs index 4a6fb6f..25c79d2 100644 --- a/schala-lang/language/src/schala.rs +++ b/schala-lang/language/src/schala.rs @@ -141,7 +141,8 @@ impl SourceReference { self.last_source = Some(source.to_string()); } - pub fn get_line(&self, line: usize) -> String { + // (line_start, line_num, the string itself) + pub fn get_line(&self, line: usize) -> (usize, usize, String) { //TODO make sure this is utf8-safe let start_idx = match self.newline_offsets.binary_search(&line) { Ok(index) | Err(index) => index, @@ -153,7 +154,7 @@ impl SourceReference { let end = self.newline_offsets.get(start_idx + 1).cloned().unwrap_or_else(|| last_source.len()); let slice = &last_source.as_bytes()[start..end]; - std::str::from_utf8(slice).unwrap().to_string() + (start, start_idx, std::str::from_utf8(slice).unwrap().to_string()) } } diff --git a/schala-lang/language/src/util.rs b/schala-lang/language/src/util.rs index fd5b4a9..c8ca959 100644 --- a/schala-lang/language/src/util.rs +++ b/schala-lang/language/src/util.rs @@ -52,10 +52,8 @@ where T: Hash + Eq /// Quickly create an AST from a string, with no error checking. For test use only #[cfg(test)] pub fn quick_ast(input: &str) -> crate::ast::AST { - let mut source_reference = crate::schala::SourceReference::new(); let mut parser = crate::parsing::new::Parser::new(); - source_reference.load_new_source(input); - let output = parser.parse(input, &source_reference); + let output = parser.parse(input); output.unwrap() }