diff options
Diffstat (limited to 'src/yuescript/yue_parser.cpp')
| -rw-r--r-- | src/yuescript/yue_parser.cpp | 90 |
1 files changed, 64 insertions, 26 deletions
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp index f564f6a..ad76517 100644 --- a/src/yuescript/yue_parser.cpp +++ b/src/yuescript/yue_parser.cpp | |||
| @@ -1342,40 +1342,78 @@ std::string ParseInfo::errorMessage(std::string_view msg, int errLine, int errCo | |||
| 1342 | return buf.str(); | 1342 | return buf.str(); |
| 1343 | } | 1343 | } |
| 1344 | const int ASCII = 255; | 1344 | const int ASCII = 255; |
| 1345 | int length = errLine; | 1345 | const int contextLines = 2; |
| 1346 | auto begin = codes->begin(); | 1346 | |
| 1347 | auto end = codes->end(); | 1347 | std::vector<std::pair<input::iterator, input::iterator>> lines; |
| 1348 | int count = 0; | 1348 | auto lineStart = codes->begin(); |
| 1349 | |||
| 1349 | for (auto it = codes->begin(); it != codes->end(); ++it) { | 1350 | for (auto it = codes->begin(); it != codes->end(); ++it) { |
| 1350 | if (*it == '\n') { | 1351 | if (*it == '\n') { |
| 1351 | if (count + 1 == length) { | 1352 | lines.emplace_back(lineStart, it); |
| 1352 | end = it; | 1353 | lineStart = it + 1; |
| 1353 | break; | 1354 | } |
| 1355 | } | ||
| 1356 | |||
| 1357 | if (lineStart != codes->end()) { | ||
| 1358 | lines.emplace_back(lineStart, codes->end()); | ||
| 1359 | } | ||
| 1360 | |||
| 1361 | int totalLines = static_cast<int>(lines.size()); | ||
| 1362 | int startLine = std::max(1, errLine - contextLines); | ||
| 1363 | int endLine = std::min(totalLines, errLine + contextLines); | ||
| 1364 | |||
| 1365 | int maxLineNum = endLine + lineOffset; | ||
| 1366 | int lineNumWidth = 1; | ||
| 1367 | int temp = maxLineNum; | ||
| 1368 | while (temp >= 10) { | ||
| 1369 | temp /= 10; | ||
| 1370 | lineNumWidth++; | ||
| 1371 | } | ||
| 1372 | |||
| 1373 | std::ostringstream buf; | ||
| 1374 | buf << errLine + lineOffset << ": " << msg << '\n'; | ||
| 1375 | |||
| 1376 | int errorDisplayCol = 0; | ||
| 1377 | if (errLine >= 1 && errLine <= totalLines) { | ||
| 1378 | auto& errorLineRange = lines[errLine - 1]; | ||
| 1379 | |||
| 1380 | auto it = errorLineRange.first; | ||
| 1381 | int displayCol = 0; | ||
| 1382 | for (int i = 0; i < errCol && it != errorLineRange.second; ++i) { | ||
| 1383 | if (*it == '\t') { | ||
| 1384 | displayCol += 2; | ||
| 1385 | } else if (*it > ASCII) { | ||
| 1386 | displayCol += 2; | ||
| 1354 | } else { | 1387 | } else { |
| 1355 | begin = it + 1; | 1388 | displayCol++; |
| 1356 | } | 1389 | } |
| 1357 | count++; | 1390 | ++it; |
| 1358 | } | 1391 | } |
| 1392 | errorDisplayCol = displayCol; | ||
| 1359 | } | 1393 | } |
| 1360 | int oldCol = errCol; | 1394 | |
| 1361 | int col = std::max(0, oldCol - 1); | 1395 | for (int lineNum = startLine; lineNum <= endLine; ++lineNum) { |
| 1362 | auto it = begin; | 1396 | int displayLineNum = lineNum + lineOffset; |
| 1363 | for (int i = 0; i < oldCol && it != end; ++i) { | 1397 | if (displayLineNum <= 0) continue; |
| 1364 | if (*it > ASCII) { | 1398 | std::string lineNumStr = std::to_string(displayLineNum); |
| 1365 | ++col; | 1399 | |
| 1400 | int padding = lineNumWidth - static_cast<int>(lineNumStr.size()); | ||
| 1401 | buf << std::string(padding, ' ') << lineNumStr << " | "; | ||
| 1402 | |||
| 1403 | if (lineNum >= 1 && lineNum <= totalLines) { | ||
| 1404 | auto& lineRange = lines[lineNum - 1]; | ||
| 1405 | std::string line = utf8_encode({lineRange.first, lineRange.second}); | ||
| 1406 | Utils::replace(line, "\t"sv, " "sv); | ||
| 1407 | buf << line; | ||
| 1408 | } | ||
| 1409 | buf << '\n'; | ||
| 1410 | |||
| 1411 | if (lineNum == errLine) { | ||
| 1412 | buf << std::string(lineNumWidth, ' ') << " "; | ||
| 1413 | buf << std::string(errorDisplayCol - 1, ' ') << "^"sv << '\n'; | ||
| 1366 | } | 1414 | } |
| 1367 | ++it; | ||
| 1368 | } | ||
| 1369 | auto line = utf8_encode({begin, end}); | ||
| 1370 | while (col < static_cast<int>(line.size()) | ||
| 1371 | && (line[col] == ' ' || line[col] == '\t')) { | ||
| 1372 | col++; | ||
| 1373 | } | 1415 | } |
| 1374 | Utils::replace(line, "\t"sv, " "sv); | 1416 | |
| 1375 | std::ostringstream buf; | ||
| 1376 | buf << errLine + lineOffset << ": "sv << msg << '\n' | ||
| 1377 | << line << '\n' | ||
| 1378 | << std::string(col, ' ') << "^"sv; | ||
| 1379 | return buf.str(); | 1417 | return buf.str(); |
| 1380 | } | 1418 | } |
| 1381 | 1419 | ||
