hoshi-lang dev
Yet another programming language
Loading...
Searching...
No Matches
def.cpp
Go to the documentation of this file.
1//
2// Created by XIaokang00010 on 2023/2/10.
3//
4
5#include <cstdio>
6#include <cstdlib>
7#include <filesystem>
8#include <fstream>
9#include <iostream>
10#include <share/def.hpp>
12#include <stdlib.h>
13
14namespace yoi {
15 thread_local yoi::wstr __current_file_path = L"";
17 std::mutex consoleMutex;
18
22
26
27 std::map<std::string, ExceptionHandleType> exception_categories = {
28 {"NULLABLE_VALUE_SUPPLY_TO_RAW", ExceptionHandleType::Suppress},
29 {"INTERNAL", ExceptionHandleType::Panic},
30 {"UCRT_NOT_FOUND", ExceptionHandleType::Warning},
31 {"ELYSIA_RUNTIME_NOT_FOUND", ExceptionHandleType::Warning},
32 {"MODULE_NOT_MODIFIED", ExceptionHandleType::Suppress},
33 };
34
35 void parseString(std::wistream &input, wstr &value) {
36 wchar ch = '\0';
37 while (input) {
38 if (!input.get(ch)) break;
39 if (ch == '\\') {
40 if (!input.get(ch)) break;
41 switch (ch) {
42 case '\\':
43 case '"':
44 case '\'':
45 case '/':
46 value.push_back(ch);
47 break;
48 case 'b':
49 value.push_back('\b');
50 break;
51 case 'f':
52 value.push_back('\f');
53 break;
54 case 'n':
55 value.push_back('\n');
56 break;
57 case 'r':
58 value.push_back('\r');
59 break;
60 case 't':
61 value.push_back('\t');
62 break;
63 case 'e':
64 value.push_back('\033');
65 break;
66 case 'u': {
67 wchar fuckutf{};
68 for (int64_t i = 3; input && i >= 0; i--) {
69 if (!input.get(ch)) break;
70 if ('a' <= ch and ch <= 'z')
71 fuckutf += ((ch - 'a' + 10) * (1 << 4 * i));
72 else if ('A' <= ch and ch <= 'Z')
73 fuckutf += ((ch - 'A' + 10) * (1 << 4 * i));
74 else
75 fuckutf += ((ch - '0') * (1 << 4 * i));
76 }
77 value.push_back(fuckutf);
78 break;
79 }
80 case '0':
81 value.push_back('\0');
82 break;
83 default:
84 value.push_back(ch);
85 break;
86 }
87 } else {
88 value.push_back(ch);
89 }
90 }
91
92 }
93
94 wstr escapeString(const wstr &value) {
95 wstr result;
96 for (auto ch : value) {
97 switch (ch) {
98 case L'\\': result += L"\\\\"; break;
99 case L'\"': result += L"\\\""; break;
100 case L'\'': result += L"\\\'"; break;
101 case L'\b': result += L"\\b"; break;
102 case L'\f': result += L"\\f"; break;
103 case L'\n': result += L"\\n"; break;
104 case L'\r': result += L"\\r"; break;
105 case L'\t': result += L"\\t"; break;
106 case L'\033': result += L"\\e"; break;
107 case L'\0': result += L"\\0"; break;
108 default:
109 if (ch < 32 || ch > 126) {
110 wchar_t buf[7];
111 swprintf(buf, 7, L"\\u%04x", (unsigned int)ch);
112 result += buf;
113 } else {
114 result += ch;
115 }
116 break;
117 }
118 }
119 return result;
120 }
121
122
123 void set_current_file_path(const std::wstring &path) {
124 __current_file_path = path;
125 }
126
127 std::wstring get_line_hint_for_error(const std::wstring &file, yoi::indexT line, yoi::indexT col) {
128 std::fstream fileStream(yoi::wstring2string(file), std::ios::in);
129 if (!fileStream.is_open()) {
130 return L"";
131 }
132 std::string lineStr;
133 for (yoi::indexT i = 0; i < line; i++) {
134 std::getline(fileStream, lineStr);
135 }
136 std::wstring result = yoi::string2wstring(lineStr) + L"\n";
137 result += std::wstring(col - 1, ' ') + L"^";
138 return result;
139 }
140
141 void panic(yoi::indexT line, yoi::indexT col, const std::string &msg) {
142 // If a diagnostic engine is registered, report the error through it first.
143 // The engine's report() will throw immediately in Immediate mode (default),
144 // or record and return in Collect mode.
146 __current_diagnostic_engine->report(line, col, msg,
149 }
150
151 // Fallback: format the message and throw (reached when no engine is set,
152 // or when the engine is in Collect mode and we still need to abort).
153 auto message = msg;
154 if (!__current_file_path.empty()) {
155 message += " near " + yoi::wstring2string(__current_file_path) + ":" + std::to_string(line + 1) + ":" + std::to_string(col + 1);
156 message += "\n" + yoi::wstring2string(get_line_hint_for_error(__current_file_path, line + 1, col + 1));
157 } else {
158 message += " near line " + std::to_string(line) + " col " + std::to_string(col);
159 }
160
161 throw std::runtime_error(message);
162 }
163
164 void warning(yoi::indexT line, yoi::indexT col, const std::string& msg, const std::string& label) {
165 // Check legacy exception_categories first (backward compat with -W/-S/-E CLI flags).
166 if (exception_categories.find(label) != exception_categories.end()) {
168 return;
169 }
171 panic(line, col, msg);
172 return;
173 }
174 }
175
176 // Map legacy label to diagnostic category for structured reporting.
178 if (label == "NULLABLE_VALUE_SUPPLY_TO_RAW") {
180 } else if (label == "UCRT_NOT_FOUND") {
182 } else if (label == "ELYSIA_RUNTIME_NOT_FOUND") {
184 } else if (label == "MODULE_NOT_MODIFIED") {
186 } else if (label == "INTERNAL") {
188 }
189
190 // Report to diagnostic engine if available.
192 __current_diagnostic_engine->report(line, col, msg,
194 }
195
196 // Existing stderr output behavior (preserved for CLI).
197 auto message = msg;
198 if (!__current_file_path.empty()) {
199 message += " near " + yoi::wstring2string(__current_file_path) + ":" + std::to_string(line + 1) + ":" + std::to_string(col + 1);
200 message += "\n" + yoi::wstring2string(get_line_hint_for_error(__current_file_path, line + 1, col + 1));
201 } else {
202 message += " near line " + std::to_string(line) + " col " + std::to_string(col);
203 }
204
205 std::lock_guard<std::mutex> lock(consoleMutex);
206 std::cerr << "[hoshi-lang warning] " << message << std::endl;
207 }
208
217 void yoi_assert(bool condition, yoi::indexT line, yoi::indexT col, const std::string &msg) {
218 if (not condition) {
219 // throw std::runtime_error("At line " + std::to_string(line) + " col " + std::to_string(col) + ": " + msg);
220 panic(line, col, msg);
221 }
222 }
223
224 std::wstring string2wstring(const std::string &v) {
225 std::wstring result;
227 return result;
228 }
229
230 std::string wstring2string(const std::wstring &v) {
231 std::string result;
233 return result;
234 }
235
236 yoi::wstr realpath(const std::wstring &path) {
237 std::wstring result;
238 std::filesystem::path p(wstring2string(path));
239 std::error_code ec;
240 if (auto res = std::filesystem::absolute(p, ec); ec)
241 throw std::runtime_error("Unable to resolve real path: [Errno " + std::to_string(ec.value()) + "]" +
242 ec.message());
243 else
244 return string2wstring(res.string());
245 }
246 std::wstring whereIsHoshiLang() {
247 std::string path;
248 int length, dirnameLength;
249
250 if (auto e = getenv("HOSHI_HOME"); e != nullptr) {
251 return string2wstring(e) + L"/bin";
252 } else {
253 length = wai_getExecutablePath(nullptr, 0, &dirnameLength);
254 path.resize(length + 1);
255 wai_getExecutablePath(path.data(), length, &dirnameLength);
256 path[length] = '\0';
257 return yoi::string2wstring(
258 path.substr(0, path.rfind(std::filesystem::path::preferred_separator)));
259 }
260 }
261} // namespace yoi
static bool utf8ToUnicode(const std::string &utf8, std::wstring &unicode)
Definition utfutils.hpp:13
static void unicodeToUtf8(const std::wstring &unicode, std::string &utf8)
Definition utfutils.hpp:77
void report(const Diagnostic &diag)
DiagnosticCategory
Definition diagnostic.h:21
std::string wstring2string(const std::wstring &v)
Definition def.cpp:230
wstr::value_type wchar
Definition def.hpp:52
void warning(yoi::indexT line, yoi::indexT col, const std::string &msg, const std::string &label)
Definition def.cpp:164
void parseString(std::wistream &input, wstr &value)
Definition def.cpp:35
std::mutex consoleMutex
Definition def.cpp:17
std::wstring string2wstring(const std::string &v)
Definition def.cpp:224
yoi::wstr realpath(const std::wstring &path)
Definition def.cpp:236
thread_local DiagnosticEngine * __current_diagnostic_engine
Definition def.cpp:16
std::wstring whereIsHoshiLang()
Definition def.cpp:246
DiagnosticEngine * get_diagnostic_engine()
Get the current thread-local diagnostic engine pointer (may be nullptr).
Definition def.cpp:23
thread_local yoi::wstr __current_file_path
Definition def.cpp:15
wstr escapeString(const wstr &value)
Definition def.cpp:94
void yoi_assert(bool condition, yoi::indexT line, yoi::indexT col, const std::string &msg)
Asserts a condition that would be true and throws a runtime_error if it is false.
Definition def.cpp:217
std::wstring get_line_hint_for_error(const std::wstring &file, yoi::indexT line, yoi::indexT col)
Definition def.cpp:127
void set_diagnostic_engine(DiagnosticEngine *engine)
Definition def.cpp:19
void set_current_file_path(const std::wstring &path)
Definition def.cpp:123
std::wstring wstr
Definition def.hpp:51
std::map< std::string, ExceptionHandleType > exception_categories
Definition def.cpp:27
uint64_t indexT
Definition def.hpp:54
void panic(yoi::indexT line, yoi::indexT col, const std::string &msg)
Definition def.cpp:141