Skip to content

Commit c2f816f

Browse files
Add source_map.hxx: Implement source location mapping for accurate token position tracking
1 parent 9f55b75 commit c2f816f

1 file changed

Lines changed: 63 additions & 0 deletions

File tree

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#if !defined(SOURCE_MAP_HXX)
2+
#define SOURCE_MAP_HXX
3+
4+
#include <vector>
5+
#include <algorithm>
6+
#include "aliases.hxx"
7+
#include "token.hxx"
8+
#include "properties.hxx"
9+
10+
WHEEL_LEXER_NAMESPACE
11+
struct SourceMap {
12+
private:
13+
std::vector<uint32_t> line_starts;
14+
15+
public:
16+
SourceMap () {
17+
line_starts.push_back(0);
18+
}
19+
20+
WHEEL_ALWAYS_INLINE void build_table(StringView source) noexcept {
21+
line_starts.clear();
22+
line_starts.push_back(0);
23+
24+
for (size_t index = 0; index < source.size(); ++index) {
25+
char character = source[index];
26+
27+
if(is_crlf_sequence(character, (index > 0) ? source[index -1] : '\0' )) {
28+
continue;
29+
}
30+
31+
if(is_newline_like(character)) {
32+
line_starts.push_back(static_cast<uint32_t>(index + 1));
33+
}
34+
}
35+
}
36+
37+
WHEEL_ALWAYS_INLINE_NODISCARD SourceLocation source_location(size_t offset) const {
38+
if(offset > UINT32_MAX) {
39+
return SourceLocation {0, 0, offset};
40+
}
41+
42+
uint32_t safe_offset = static_cast<uint32_t>(offset);
43+
auto it = std::upper_bound(line_starts.begin(), line_starts.end(), safe_offset);
44+
45+
if (it != line_starts.begin()) {
46+
--it;
47+
}
48+
49+
size_t line_index = std::distance(line_starts.begin(), it);
50+
uint32_t line_start_offset = line_starts[line_index];
51+
uint32_t column = (safe_offset - line_start_offset) + 1;
52+
53+
return SourceLocation {
54+
.line = line_index + 1,
55+
.column = column,
56+
.offset = safe_offset
57+
};
58+
}
59+
};
60+
61+
END_NAMESPACE
62+
63+
#endif // SOURCE_MAP_HXX

0 commit comments

Comments
 (0)