summaryrefslogtreecommitdiff
path: root/src/locators/source_location.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/locators/source_location.rs')
-rw-r--r--src/locators/source_location.rs75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/locators/source_location.rs b/src/locators/source_location.rs
new file mode 100644
index 0000000..9fd1b2b
--- /dev/null
+++ b/src/locators/source_location.rs
@@ -0,0 +1,75 @@
+use std::path::PathBuf;
+
+
+#[derive(Clone)]
+pub struct SourceSpan {
+ /// The source characters which this span represents.
+ pub string: String,
+ /// The location of this span in the merged source file.
+ pub in_merged: SourceLocation,
+ /// The location of this span in the original source file.
+ pub in_source: Option<SourceLocation>,
+}
+
+impl SourceSpan {
+ pub fn location(&self) -> &SourceLocation {
+ self.in_source.as_ref().unwrap_or(&self.in_merged)
+ }
+}
+
+
+#[derive(Clone)]
+pub struct SourceLocation {
+ /// File path the source was loaded from.
+ pub path: Option<PathBuf>,
+ /// Position of the first character of the string.
+ pub start: Position,
+ /// Position of the final character of the string.
+ pub end: Position,
+}
+
+impl std::fmt::Display for SourceLocation {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
+ let y = self.start.line + 1;
+ let x = self.start.column + 1;
+ match &self.path {
+ Some(path) => write!(f, "{}:{y}:{x}", path.as_os_str().to_string_lossy()),
+ None => write!(f, "<unknown>:{y}:{x}"),
+ }
+ }
+}
+
+
+#[derive(Clone, Copy)]
+pub struct Position {
+ /// The number of lines that precede this line in the source file.
+ pub line: usize,
+ /// The number of characters that precede this character in the line.
+ pub column: usize,
+}
+
+impl Position {
+ pub fn to_next_char(&mut self) {
+ self.column += 1;
+ }
+
+ pub fn to_next_line(&mut self) {
+ self.line += 1;
+ self.column = 0;
+ }
+
+ pub fn advance(&mut self, c: char) {
+ match c {
+ '\n' => self.to_next_line(),
+ _ => self.to_next_char(),
+ }
+ }
+}
+
+impl std::fmt::Display for Position {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
+ let y = self.line + 1;
+ let x = self.column + 1;
+ write!(f, "{y}:{x}")
+ }
+}