slang_ir/location.rs
1/// Represents a location in the source code (position, line, column, length)
2#[derive(Debug, Clone, Copy)]
3pub struct Location {
4 /// The position in the source code (byte offset)
5 pub position: usize,
6 /// The line number (1-based)
7 pub line: usize,
8 /// The column number (1-based)
9 pub column: usize,
10 /// The length of the token/node in characters
11 pub length: usize,
12}
13
14impl Location {
15 /// Creates a new SourceLocation
16 ///
17 /// ### Arguments
18 /// * `position` - Position in the source (byte offset)
19 /// * `line` - Line number (1-based)
20 /// * `column` - Column number (1-based)
21 /// * `length` - Length of the token/node in characters
22 ///
23 /// ### Returns
24 /// A new SourceLocation
25 pub fn new(position: usize, line: usize, column: usize, length: usize) -> Self {
26 Self {
27 position,
28 line,
29 column,
30 length,
31 }
32 }
33
34 /// Creates a new SourceLocation with the old 3-parameter signature for backward compatibility
35 ///
36 /// ### Arguments
37 /// * `position` - Position in the source (byte offset)
38 /// * `line` - Line number (1-based)
39 /// * `column` - Column number (1-based)
40 ///
41 /// ### Returns
42 /// A new SourceLocation with length = 1 (default for single character tokens)
43 pub fn new_simple(position: usize, line: usize, column: usize) -> Self {
44 Self {
45 position,
46 line,
47 column,
48 length: 1,
49 }
50 }
51
52 /// Get the end position of this location
53 ///
54 /// ### Returns
55 /// The byte offset position at the end of this location
56 pub fn end_position(&self) -> usize {
57 self.position + self.length
58 }
59
60 /// Get the end column of this location (assuming single line)
61 ///
62 /// ### Returns
63 /// The column number at the end of this location
64 pub fn end_column(&self) -> usize {
65 self.column + self.length
66 }
67
68 /// Create a span from this location to another location
69 ///
70 /// ### Arguments
71 ///
72 /// * `other` - The other SourceLocation to create a span to
73 ///
74 /// ### Returns
75 /// A new SourceLocation representing the span from this location to the other
76 pub fn span_to(&self, other: &Location) -> Location {
77 let start_pos = self.position.min(other.position);
78 let end_pos = self.end_position().max(other.end_position());
79
80 Location {
81 position: start_pos,
82 line: self.line.min(other.line),
83 column: if self.line == other.line {
84 self.column.min(other.column)
85 } else {
86 self.column
87 },
88 length: end_pos - start_pos,
89 }
90 }
91}
92
93impl Default for Location {
94 /// Creates a default SourceLocation at the start of the source code
95 fn default() -> Self {
96 Self {
97 position: 0,
98 line: 1,
99 column: 1,
100 length: 1,
101 }
102 }
103}