From 8eda74c9a506649edfd882df42a482d5515ffe20 Mon Sep 17 00:00:00 2001 From: greg Date: Sat, 5 Jan 2019 17:18:10 -0800 Subject: [PATCH] Starting to keep track of locations of errors in file --- schala-lang/codegen/src/lib.rs | 4 ++-- schala-lang/language/src/lib.rs | 8 ++++++- schala-lang/language/src/parsing.rs | 34 ++++++++++++++++++++--------- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/schala-lang/codegen/src/lib.rs b/schala-lang/codegen/src/lib.rs index 7ba53ec..b28ddbc 100644 --- a/schala-lang/codegen/src/lib.rs +++ b/schala-lang/codegen/src/lib.rs @@ -19,7 +19,7 @@ impl Fold for RecursiveDescentFn { let new_block: syn::Block = parse_quote! { { - let next_token_before_parse = self.peek_with_token_offset(); + let next_token_before_parse = self.token_handler.peek_token(); let record = ParseRecord { production_name: stringify!(#ident).to_string(), next_token: format!("{}", next_token_before_parse.to_string_with_metadata()), @@ -34,7 +34,7 @@ impl Fold for RecursiveDescentFn { } match result { Err(ParseError { token: None, msg }) => { - let next_token_after_parse = self.peek_with_token_offset(); + let next_token_after_parse = self.token_handler.peek_token(); println!("HERE? {:?}", next_token_after_parse); Err(ParseError { token: Some(next_token_after_parse), msg }) }, diff --git a/schala-lang/language/src/lib.rs b/schala-lang/language/src/lib.rs index 57d060e..8585e28 100644 --- a/schala-lang/language/src/lib.rs +++ b/schala-lang/language/src/lib.rs @@ -124,7 +124,13 @@ fn parsing(handle: &mut Schala, input: Vec, comp: Option<&mut Some(ref x) => println!("Bad parsing debug option: {}", x), }; }); - ast.map_err(|err| err.msg) + ast.map_err(|error: parsing::ParseError| { + let location_frag = match error.token { + Some(tok) => format!(" at line: {} column: {}", tok.offset.0, tok.offset.1), + None => "".into() + }; + format!("'{}'{}", error.msg, location_frag) + }) } fn symbol_table(handle: &mut Schala, input: ast::AST, comp: Option<&mut UnfinishedComputation>) -> Result { diff --git a/schala-lang/language/src/parsing.rs b/schala-lang/language/src/parsing.rs index d79f14d..c38640b 100644 --- a/schala-lang/language/src/parsing.rs +++ b/schala-lang/language/src/parsing.rs @@ -23,6 +23,13 @@ impl ParseError { token: None }) } + + fn new_with_token(msg: &str, t: Token) -> ParseResult{ + Err(ParseError { + msg: msg.to_string(), + token: Some(t) + }) + } } pub type ParseResult = Result; @@ -47,19 +54,26 @@ struct ParserRestrictions { struct TokenHandler { tokens: Peekable>, + end_of_file: (usize, usize), } impl TokenHandler { fn new(tokens: Vec) -> TokenHandler { + let end_of_file = match tokens.last() { + None => (0, 0), + Some(s) => { + s.offset.clone() + } + }; let tokens = tokens.into_iter().peekable(); - TokenHandler { tokens } + TokenHandler { tokens, end_of_file } } fn peek(&mut self) -> TokenKind { self.tokens.peek().map(|ref t| { t.kind.clone() }).unwrap_or(TokenKind::EOF) } - fn peek_with_token_offset(&mut self) -> Token { - self.tokens.peek().map(|t: &Token| { t.clone()}).unwrap_or(Token { kind: TokenKind::EOF, offset: (0,0)}) + fn peek_token(&mut self) -> Token { + self.tokens.peek().map(|t: &Token| { t.clone()}).unwrap_or(Token { kind: TokenKind::EOF, offset: self.end_of_file}) } fn next(&mut self) -> TokenKind { self.tokens.next().map(|ref t| { t.kind.clone() }).unwrap_or(TokenKind::EOF) @@ -79,9 +93,6 @@ impl Parser { fn peek(&mut self) -> TokenKind { self.token_handler.peek() } - fn peek_with_token_offset(&mut self) -> Token { - self.token_handler.peek_with_token_offset() - } fn next(&mut self) -> TokenKind { self.token_handler.next() } @@ -544,7 +555,7 @@ impl Parser { fn precedence_expr(&mut self, precedence: i32) -> ParseResult { let record = ParseRecord { production_name: "precedence_expr".to_string(), - next_token: format!("{}", self.peek_with_token_offset().to_string_with_metadata()), + next_token: format!("{}", self.token_handler.peek_token().to_string_with_metadata()), level: self.parse_level, }; self.parse_level += 1; @@ -994,7 +1005,10 @@ impl Parser { #[recursive_descent_method] fn literal(&mut self) -> ParseResult { use self::ExpressionType::*; - match self.peek() { + + let tok = self.token_handler.peek_token(); + let kind = tok.kind.clone(); + match kind { DigitGroup(_) | HexLiteral(_) | BinNumberSigil | Period => self.number_literal(), Keyword(Kw::True) => { self.next(); @@ -1006,9 +1020,9 @@ impl Parser { }, StrLiteral(s) => { self.next(); - Ok(Expression(StringLiteral(s), None)) + Ok(Expression(StringLiteral(s.clone()), None)) } - e => ParseError::new(&format!("Expected a literal expression, got {:?}", e)), + e => ParseError::new_with_token(&format!("Expected a literal expression, got {:?}", e), tok), } }