-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLogger.h
178 lines (151 loc) · 5.84 KB
/
Logger.h
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#pragma once
#include <iostream>
#include <sstream>
#include <string_view>
#include <string>
#include <cassert>
#include <cstdarg>
#include "Token.h"
#include "Utils.h"
namespace lwscript
{
namespace Logger
{
namespace Record
{
inline STD_STRING mCurFilePath = TEXT("interpreter");
inline STD_STRING mSourceCode = TEXT("");
}
inline void Output(STD_OSTREAM &os, STD_STRING s)
{
os << s;
}
template <typename T, typename... Args>
inline void Output(STD_OSTREAM &os, STD_STRING s, const T &next, const Args &...args)
{
auto index = s.find_first_of(TEXT("{}"));
if (index == STD_STRING::npos)
Output(os, s);
else
{
STD_STRING_STREAM sstr;
sstr << next;
s.replace(index, 2, sstr.str());
sstr.clear();
Output(os, s, args...);
}
}
template <typename... Args>
inline void Println(const STD_STRING &s, const Args &...args)
{
Output(COUT, s + TEXT("\n"), args...);
}
template <typename... Args>
inline void Print(const STD_STRING &s, const Args &...args)
{
Output(COUT, s, args...);
}
inline void RecordSource(STD_STRING_VIEW sourceCode)
{
Record::mSourceCode = sourceCode;
}
template <typename... Args>
inline void AssemblyLogInfo(const STD_STRING &headerHint, const STD_STRING &colorHint, uint64_t lineNum, uint64_t column, uint64_t pos, const STD_STRING &fmt, const Args &...args)
{
auto start = pos;
auto end = pos;
if (Record::mCurFilePath != TEXT("interpreter"))
{
while ((Record::mSourceCode[start - 1] != TCHAR('\n') && Record::mSourceCode[start - 1] != TCHAR('\r')) && start - 1 > 0)
start--;
while ((Record::mSourceCode[end] != TCHAR('\n') && Record::mSourceCode[end] != TCHAR('\r')) && end < Record::mSourceCode.size())
end++;
}
else
{
start = 0;
end = Record::mSourceCode.size();
}
auto startStr = headerHint + TEXT(":") + Record::mCurFilePath + TEXT("(line ") + TO_STRING(lineNum) + TEXT(",column ") + TO_STRING(column) + TEXT("): ");
auto lineSrcCode = Record::mSourceCode.substr(start, end - start);
Println(TEXT("\033[{}m{}{}\033[0m"), colorHint, startStr, lineSrcCode);
auto blankSize = startStr.size() + pos - start;
STD_STRING errorHintStr;
errorHintStr.insert(0, blankSize, TCHAR(' '));
errorHintStr += TEXT("^ ") + STD_STRING(fmt);
Println(TEXT("\033[{}m") + errorHintStr + TEXT("\033[0m"), colorHint, args...);
}
template <typename... Args>
inline void Error(const STD_STRING &fmt, const Args &...args)
{
Println(TEXT("\033[31m[ERROR]:") + fmt + TEXT("\033[0m"), args...);
#ifndef NDEBUG
assert(0);
#else
exit(1);
#endif
}
template <typename... Args>
inline void Error(uint64_t pos, const STD_STRING &fmt, const Args &...args)
{
auto lineNum = 1;
for (uint64_t i = 0; i < pos; ++i)
if (Record::mSourceCode[i] == TCHAR('\n') || Record::mSourceCode[i] == TCHAR('\r'))
lineNum++;
AssemblyLogInfo(TEXT("[ERROR]"), TEXT("31"), lineNum, 1, pos, fmt, args...);
#ifndef NDEBUG
assert(0);
#else
exit(1);
#endif
}
template <typename... Args>
inline void Error(const Token *tok, const STD_STRING &fmt, const Args &...args)
{
AssemblyLogInfo(TEXT("[ERROR]"), TEXT("31"), tok->sourceLocation.line, tok->sourceLocation.column, tok->sourceLocation.pos, fmt, args...);
#ifndef NDEBUG
assert(0);
#else
exit(1);
#endif
}
template <typename... Args>
inline void Warn(const STD_STRING &fmt, const Args &...args)
{
Println(TEXT("\033[33m[WARN]:") + fmt + TEXT("\033[0m"), args...);
}
template <typename... Args>
void Warn(int32_t pos, const STD_STRING &fmt, const Args &...args)
{
auto lineNum = 1;
for (int32_t i = 0; i < pos; ++i)
if (Record::mSourceCode[i] == TCHAR('\n') || Record::mSourceCode[i] == TCHAR('\r'))
lineNum++;
AssemblyLogInfo(TEXT("[WARN]"), TEXT("33"), lineNum, 1, pos, fmt, args...);
}
template <typename... Args>
void Warn(const Token *tok, const STD_STRING &fmt, const Args &...args)
{
AssemblyLogInfo(TEXT("[WARN]"), TEXT("33"), tok->sourceLocation.line, tok->sourceLocation.column, tok->sourceLocation.pos, fmt, args...);
}
template <typename... Args>
inline void Info(const STD_STRING &fmt, const Args &...args)
{
Println(TEXT("\033[32m[INFO]:") + fmt + TEXT("\033[0m"), args...);
}
template <typename... Args>
void Info(int32_t pos, const STD_STRING &fmt, const Args &...args)
{
auto lineNum = 1;
for (int32_t i = 0; i < pos; ++i)
if (Record::mSourceCode[i] == TCHAR('\n') || Record::mSourceCode[i] == TCHAR('\r'))
lineNum++;
AssemblyLogInfo(TEXT("[INFO]"), TEXT("32"), lineNum, 1, pos, fmt, args...);
}
template <typename... Args>
void Info(const Token *tok, const STD_STRING &fmt, const Args &...args)
{
AssemblyLogInfo(TEXT("[INFO]"), TEXT("32"), tok->sourceLocation.line, tok->sourceLocation.column, tok->sourceLocation.pos, fmt, args...);
}
}
}