3 #include "source_file/source_file.h"
7 void SourceFile::open(
const str &filename) {
9 ifs.open(filename, std::ios::in);
11 Error(ErrorType::FILE_NOT_FOUND,
"Cannot open file: " + filename).raise();
16 str content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
21 void SourceFile::from_string(
const str &code) {
22 size_t line_start = 0;
23 size_t code_len = code.length();
24 for (
size_t c = 0; c < code_len; ++c) {
25 if (code[c] ==
'\n' || c == code.length() - 1) {
27 if (code[c] ==
'\n') {
28 line = code.substr(line_start, c - line_start);
30 line = code.substr(line_start, c - line_start + 1);
34 for (
size_t i = 0; i < line.length(); ++i) {
35 if (!isspace(line[i])) {
36 line = line.substr(i);
41 _lines.push_back(line);
48 if (c.l >= _lines.size()) {
52 str line = _lines[c.l];
56 return c.c < line.size();
65 if (
end.l >= _lines.size() ||
end.c > _lines[
end.l].size()) {
66 end.l = (uint32_t)_lines.size() - 1;
67 end.c = (uint32_t)_lines.back().size();
73 TAN_ASSERT(start.c <=
end.c);
74 ret = _lines[s_row].substr(start.c,
end.c - start.c);
76 ret += _lines[s_row].substr(start.c) +
"\n";
77 for (
auto r = s_row + 1; r < e_row; ++r) {
78 ret += _lines[r] +
"\n";
81 ret += _lines[e_row].substr(0,
end.c);
93 if (ptr.l >= _lines.size()) {
96 size_t n_cols = _lines[ptr.l].length();
97 if (ptr.c + 1 >= n_cols) {
98 if (ptr.l < _lines.size()) {
108 str SourceFile::get_filename()
const {
return _filename; }
111 if (_lines.empty()) {
112 return SrcLoc(0, 1,
this);
114 return SrcLoc((uint32_t)_lines.size() - 1, (uint32_t)_lines.back().length(),
this);
117 char SourceFile::at(
const SrcLoc &ptr)
const {
118 TAN_ASSERT(ptr.l != -1u && ptr.c != -1u);
119 if (ptr.l >= this->size()) {
122 if (ptr.c >= this->_lines[ptr.l].length()) {
125 return _lines[ptr.l][ptr.c];
131 TAN_ASSERT(index < _lines.size());
132 return _lines[index];
135 SrcLoc::SrcLoc(uint32_t r, uint32_t c,
const SourceFile *src) : l(r), c(c), _src((
SourceFile *)src) {}
137 bool SrcLoc::operator==(
const SrcLoc &other)
const {
return l == other.l && c == other.c; }
139 bool SrcLoc::operator!=(
const SrcLoc &other)
const {
return !(*
this == other); }
141 bool SrcLoc::operator<=(
const SrcLoc &other)
const {
144 }
else if (l > other.l) {
151 bool SrcLoc::operator<(
const SrcLoc &other)
const {
154 }
else if (l > other.l) {
161 bool SrcLoc::operator>(
const SrcLoc &other)
const {
164 }
else if (l < other.l) {
171 SrcLoc &SrcLoc::operator++() {
176 SrcLoc SrcLoc::operator++(
int) {
182 char SrcLoc::operator*() {
184 return _src->at(*
this);
187 SourceSpan::SourceSpan(
188 const SourceFile *src, uint32_t start_line, uint32_t start_col, uint32_t end_line, uint32_t end_col)
189 : SourceSpan(SrcLoc(start_line, start_col, src), SrcLoc(end_line, end_col, src)) {}
191 SourceSpan::SourceSpan(
const SourceFile *src, uint32_t line, uint32_t col) : SourceSpan(src, line, col, line, col) {}
193 SourceSpan::SourceSpan(
const SrcLoc &start,
const SrcLoc &end) : _start(start), _end(end) {
194 TAN_ASSERT(start._src ==
end._src);
195 TAN_ASSERT(start.l <=
end.l);
196 if (start.l ==
end.l) {
197 TAN_ASSERT(start.c <=
end.c);
201 SourceFile *SourceSpan::src()
const {
return _start._src; }
203 const SrcLoc &SourceSpan::start()
const {
return _start; }
205 const SrcLoc &SourceSpan::end()
const {
return _end; }
bool is_cursor_valid(const SrcLoc &c) const
Check if a cursor is in bound.
SrcLoc begin() const
The start of source file (inclusive).
str get_line(size_t index) const
Return source at a specific line.
str substr(const SrcLoc &start) const
Get a substring from start to the end of the current line.
SrcLoc end() const
The end of source file (exclusive).
SrcLoc forward(SrcLoc c)
Return a copy of code_ptr that points to the next character.