From 72185fecd54d9215dc4ff8fc5a1838a83d0f941d Mon Sep 17 00:00:00 2001 From: harupy Date: Wed, 4 Jan 2023 13:16:03 +0900 Subject: [PATCH] Add with_col_offset and with_row_offset to Location --- codegen/src/symboltable.rs | 2 +- core/src/location.rs | 40 +++++++++++++++++++++++++++++++++++++ parser/src/error.rs | 2 +- parser/src/string_parser.rs | 8 ++------ 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/codegen/src/symboltable.rs b/codegen/src/symboltable.rs index 3182f3d..a12ad5f 100644 --- a/codegen/src/symboltable.rs +++ b/codegen/src/symboltable.rs @@ -168,7 +168,7 @@ impl SymbolTableError { pub fn into_codegen_error(self, source_path: String) -> CodegenError { CodegenError { error: CodegenErrorType::SyntaxError(self.error), - location: Location::new(self.location.row(), self.location.column() + 1), + location: self.location.with_col_offset(1), source_path, } } diff --git a/core/src/location.rs b/core/src/location.rs index 7f1adc4..b7b2c8b 100644 --- a/core/src/location.rs +++ b/core/src/location.rs @@ -58,6 +58,34 @@ impl Location { self.row += 1; self.column = 0; } + + pub fn with_col_offset>(&self, offset: T) -> Self + where + >::Error: std::fmt::Debug, + { + let column = (self.column as isize + + offset + .try_into() + .expect("offset should be able to convert to isize")) as u32; + Location { + row: self.row, + column, + } + } + + pub fn with_row_offset>(&self, offset: T) -> Self + where + >::Error: std::fmt::Debug, + { + let row = (self.row as isize + + offset + .try_into() + .expect("offset should be able to convert to isize")) as u32; + Location { + row, + column: self.column, + } + } } #[cfg(test)] @@ -77,4 +105,16 @@ mod tests { assert!(Location::new(1, 1) < Location::new(2, 1)); assert!(Location::new(1, 2) < Location::new(2, 1)); } + + #[test] + fn test_with_col_offset() { + assert_eq!(Location::new(1, 1).with_col_offset(1), Location::new(1, 2)); + assert_eq!(Location::new(1, 1).with_col_offset(-1), Location::new(1, 0)); + } + + #[test] + fn test_with_row_offset() { + assert_eq!(Location::new(1, 1).with_row_offset(1), Location::new(2, 1)); + assert_eq!(Location::new(1, 1).with_row_offset(-1), Location::new(0, 1)); + } } diff --git a/parser/src/error.rs b/parser/src/error.rs index 7a4f60b..6df758b 100644 --- a/parser/src/error.rs +++ b/parser/src/error.rs @@ -213,7 +213,7 @@ pub(crate) fn parse_error_from_lalrpop( let expected = (expected.len() == 1).then(|| expected[0].clone()); ParseError { error: ParseErrorType::UnrecognizedToken(token.1, expected), - location: Location::new(token.0.row(), token.0.column() + 1), + location: token.0.with_col_offset(1), source_path, } } diff --git a/parser/src/string_parser.rs b/parser/src/string_parser.rs index b305493..52818bf 100644 --- a/parser/src/string_parser.rs +++ b/parser/src/string_parser.rs @@ -32,7 +32,7 @@ impl<'a> StringParser<'a> { kind, str_start, str_end, - location: Location::new(str_start.row(), str_start.column() + offset), + location: str_start.with_col_offset(offset), } } @@ -523,11 +523,7 @@ impl<'a> StringParser<'a> { fn parse_fstring_expr(source: &str, location: Location) -> Result { let fstring_body = format!("({source})"); - parse_expression_located( - &fstring_body, - "", - Location::new(location.row(), location.column() - 1), - ) + parse_expression_located(&fstring_body, "", location.with_col_offset(-1)) } pub fn parse_string(