-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathAnalysisError.h
More file actions
65 lines (56 loc) · 2.5 KB
/
AnalysisError.h
File metadata and controls
65 lines (56 loc) · 2.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#pragma once
#include "Token.h"
#include "Style.h"
class AnalysisError {
const std::vector<Token *> &tokenStream;
std::vector<Token *>::const_iterator errorIter, lineStartIter, lineEndIter;
const std::string reason;
const std::string verbose;
private:
inline std::vector<Token *>::const_iterator findLineStart(std::vector<Token *>::const_iterator pos) {
int line = (*pos)->getLine();
for (; pos > tokenStream.begin(); pos--) {
if ((*pos)->getLine() != line) return ++pos;
}
return tokenStream.begin();
};
inline std::vector<Token *>::const_iterator findLineEnd(std::vector<Token *>::const_iterator pos) {
int line = (*pos)->getLine();
for (; pos < tokenStream.end(); pos++) {
if ((*pos)->getLine() != line) return pos;
}
return tokenStream.end();
};
public:
AnalysisError(const std::vector<Token *> &tokenStream, std::vector<Token *>::const_iterator errorPosition, const std::string &reason, const std::string &verbose = "")
:tokenStream(tokenStream), errorIter(errorPosition),
lineStartIter(findLineStart(errorPosition)), lineEndIter(findLineEnd(errorPosition)),
reason(reason), verbose(verbose){
}
friend inline std::ostream &operator<<(std::ostream &out, const AnalysisError &error) {
out << std::endl << Style(Style::Foreground::Red, Style::Format::Bold) << error.reason << " at line " << (*error.errorIter)->getLine() << ':' << Style() << std::endl;
std::size_t errStartPos = 0, totalLength = 0;
for (auto iter = error.lineStartIter; iter < error.lineEndIter; iter++) {
if ((*iter)->getType() == Token::Type::Linewrap || (*iter)->getType() == Token::Type::End) continue;
if (iter == error.errorIter) {
errStartPos = totalLength;
out << Style(Style::Foreground::Yellow,Style::Format::Bold) << (*iter)->getRaw() << Style();
}
else {
out << (*iter)->getRaw();
}
totalLength += (*iter)->getRaw().length();
}
out << std::endl;
for (std::size_t i = 0; i < errStartPos; i++) out << ' ';
out << Style(Style::Foreground::Yellow);
for (std::size_t i = 0; i < (*error.errorIter)->getRaw().length(); i++) out << '~';
out << Style();
out << std::endl;
if (error.verbose.length() > 0) {
out << error.verbose;
out << std::endl;
}
return out;
}
};