feat: 在解析器中实现 Lambda 和 new 表达式
- 增加了对 Lambda 表达式的初步解析支持,包括参数处理和返回类型。Lambda闭包尚未支持。 - 引入了用于对象初始化的新的表达式,支持可选的命名参数。 - 改进了表达式语法错误的错误报告。 - 更新了解析器和分析器以处理新的表达式类型并验证其语义。 - 修改了现有测试以涵盖新功能并确保其正确性。 - 改进了各种解析和语义错误的诊断。
This commit is contained in:
@@ -17,7 +17,8 @@ namespace Fig
|
||||
ost << color << msg << TerminalColors::Reset;
|
||||
}
|
||||
|
||||
void ColoredPrint(const char *color, const std::string &msg, std::ostream &ost = CoreIO::GetStdErr())
|
||||
void
|
||||
ColoredPrint(const char *color, const std::string &msg, std::ostream &ost = CoreIO::GetStdErr())
|
||||
{
|
||||
ost << color << msg << TerminalColors::Reset;
|
||||
}
|
||||
@@ -30,7 +31,10 @@ namespace Fig
|
||||
std::string MultipleStr(const char *c, size_t n)
|
||||
{
|
||||
std::string buf;
|
||||
for (size_t i = 0; i < n; ++i) { buf += c; }
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
buf += c;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -40,6 +44,7 @@ namespace Fig
|
||||
switch (type)
|
||||
{
|
||||
case UnusedSymbol: return "UnusedSymbol";
|
||||
case UnnecessarySemicolon: return "UnnecessarySemicolon";
|
||||
|
||||
case MayBeNull: return "MaybeNull";
|
||||
|
||||
@@ -61,7 +66,8 @@ namespace Fig
|
||||
case TooManyConstants: return "TooManyConstants";
|
||||
|
||||
case RegisterOverflow: return "RegisterOverflow";
|
||||
case InternalError: return "InternalError";
|
||||
case InternalError:
|
||||
return "InternalError";
|
||||
// default: return "Some one forgot to add case to `ErrorTypeToString`";
|
||||
}
|
||||
return "UnknownError";
|
||||
@@ -69,10 +75,10 @@ namespace Fig
|
||||
|
||||
void PrintSystemInfos()
|
||||
{
|
||||
std::ostream &err = CoreIO::GetStdErr();
|
||||
std::ostream &err = CoreIO::GetStdErr();
|
||||
std::stringstream build_info;
|
||||
build_info << "\r🌘 Fig v" << Core::VERSION << " on " << Core::PLATFORM << ' ' << Core::ARCH << '['
|
||||
<< Core::COMPILER << ']' << '\n'
|
||||
build_info << "\r🌘 Fig v" << Core::VERSION << " on " << Core::PLATFORM << ' ' << Core::ARCH
|
||||
<< '[' << Core::COMPILER << ']' << '\n'
|
||||
<< " Build Time: " << Core::COMPILE_TIME;
|
||||
|
||||
const std::string &build_info_str = build_info.str();
|
||||
@@ -83,35 +89,43 @@ namespace Fig
|
||||
|
||||
void PrintErrorInfo(const Error &error, const SourceManager &srcManager)
|
||||
{
|
||||
static constexpr const char *MinorColor = "\033[38;2;138;227;198m";
|
||||
static constexpr const char *MediumColor = "\033[38;2;255;199;95m";
|
||||
static constexpr const char *MinorColor = "\033[38;2;138;227;198m";
|
||||
static constexpr const char *MediumColor = "\033[38;2;255;199;95m";
|
||||
static constexpr const char *CriticalColor = "\033[38;2;255;107;107m";
|
||||
|
||||
namespace TC = TerminalColors;
|
||||
namespace TC = TerminalColors;
|
||||
std::ostream &err = CoreIO::GetStdErr();
|
||||
|
||||
uint8_t level = ErrorLevel(error.type);
|
||||
// const char *level_name = (level == 1 ? "Minor" : (level == 2 ? "Medium" : "Critical"));
|
||||
const char *level_color = (level == 1 ? MinorColor : (level == 2 ? MediumColor : CriticalColor));
|
||||
const char *level_color =
|
||||
(level == 1 ? MinorColor : (level == 2 ? MediumColor : CriticalColor));
|
||||
|
||||
err << "🔥 "
|
||||
<< level_color
|
||||
//<< '(' << level_name << ')'
|
||||
<< 'E' << static_cast<int>(error.type) << TC::Reset << ": " << level_color << ErrorTypeToString(error.type)
|
||||
<< TC::Reset << '\n';
|
||||
<< 'E' << static_cast<int>(error.type) << TC::Reset << ": " << level_color
|
||||
<< ErrorTypeToString(error.type) << TC::Reset << '\n';
|
||||
|
||||
const SourceLocation &location = error.location;
|
||||
|
||||
err << TC::DarkGray << " ┌─> Fn " << TC::Cyan << '\'' << location.packageName << '.' << location.functionName
|
||||
<< '\'' << " " << location.fileName << " (" << TC::DarkGray << location.sp.line << ":" << location.sp.column
|
||||
<< TC::Cyan << ')' << TC::Reset << '\n';
|
||||
err << TC::DarkGray << " ┌─> Fn " << TC::Cyan << '\'' << location.packageName << '.'
|
||||
<< location.functionName << '\'' << " " << location.fileName << " (" << TC::DarkGray
|
||||
<< location.sp.line << ":" << location.sp.column << TC::Cyan << ')' << TC::Reset
|
||||
<< '\n';
|
||||
err << TC::DarkGray << " │" << '\n' << " │" << TC::Reset << '\n';
|
||||
|
||||
// 尝试打印上3行 下2行
|
||||
|
||||
int64_t line_start = location.sp.line - 3, line_end = location.sp.line + 2;
|
||||
while (!srcManager.HasLine(line_end)) { --line_end; }
|
||||
while (!srcManager.HasLine(line_start)) { ++line_start; }
|
||||
while (!srcManager.HasLine(line_end))
|
||||
{
|
||||
--line_end;
|
||||
}
|
||||
while (!srcManager.HasLine(line_start))
|
||||
{
|
||||
++line_start;
|
||||
}
|
||||
|
||||
const auto &getLineNumWidth = [](size_t l) {
|
||||
unsigned int cnt = 0;
|
||||
@@ -127,30 +141,39 @@ namespace Fig
|
||||
{
|
||||
unsigned int offset = 2 + 2 + 1;
|
||||
// ' └─ '
|
||||
if (i == location.sp.line) { err << TC::DarkGray << " └─ " << TC::Reset; }
|
||||
else if (i < location.sp.line) { err << TC::DarkGray << " │ " << TC::Reset; }
|
||||
if (i == location.sp.line)
|
||||
{
|
||||
err << TC::DarkGray << " └─ " << TC::Reset;
|
||||
}
|
||||
else if (i < location.sp.line)
|
||||
{
|
||||
err << TC::DarkGray << " │ " << TC::Reset;
|
||||
}
|
||||
else
|
||||
{
|
||||
err << MultipleStr(" ", offset);
|
||||
}
|
||||
unsigned int cur_line_number_width = getLineNumWidth(i);
|
||||
|
||||
err << MultipleStr(" ", max_line_number_width - cur_line_number_width) << TC::Yellow << i << TC::Reset;
|
||||
err << MultipleStr(" ", max_line_number_width - cur_line_number_width) << TC::Yellow
|
||||
<< i << TC::Reset;
|
||||
err << " │ " << srcManager.GetLine(i) << '\n';
|
||||
if (i == location.sp.line)
|
||||
{
|
||||
unsigned int error_col_offset = offset + 1 + max_line_number_width + 2;
|
||||
err << MultipleStr(" ", error_col_offset) << MultipleStr(" ", location.sp.column - 1) << TC::LightGreen
|
||||
err << MultipleStr(" ", error_col_offset)
|
||||
<< MultipleStr(" ", location.sp.column - 1) << TC::LightGreen
|
||||
<< MultipleStr("^", location.sp.tok_length) << TC::Reset << '\n';
|
||||
|
||||
err << MultipleStr(" ", error_col_offset)
|
||||
<< MultipleStr(" ", location.sp.column - 1 + location.sp.tok_length / 2) << "╰─ " << level_color
|
||||
<< error.message << TC::Reset << "\n\n";
|
||||
<< MultipleStr(" ", location.sp.column - 1 + location.sp.tok_length / 2)
|
||||
<< "╰─ " << level_color << error.message << TC::Reset << "\n\n";
|
||||
}
|
||||
}
|
||||
err << "\n";
|
||||
err << "❓ " << TC::DarkGray << "Thrower: " << error.thrower_loc.function_name() << " ("
|
||||
<< error.thrower_loc.file_name() << ":" << error.thrower_loc.line() << ")" << TC::Reset << "\n";
|
||||
<< error.thrower_loc.file_name() << ":" << error.thrower_loc.line() << ")" << TC::Reset
|
||||
<< "\n";
|
||||
err << "💡 " << TC::Blue << "Suggestion: " << error.suggestion << TC::Reset;
|
||||
err << '\n';
|
||||
}
|
||||
@@ -158,7 +181,7 @@ namespace Fig
|
||||
void ReportError(const Error &error, const SourceManager &srcManager)
|
||||
{
|
||||
assert(srcManager.read && "ReportError: srcManager doesn't read source");
|
||||
assert(srcManager.HasLine(error.location.sp.line));
|
||||
// assert(srcManager.HasLine(error.location.sp.line));
|
||||
|
||||
PrintSystemInfos();
|
||||
PrintErrorInfo(error, srcManager);
|
||||
|
||||
Reference in New Issue
Block a user