[VER] 0.4.0-alpha

[Fix] 修复恶性Bug: Parser: parseExpression没有正确解析二元表达式,没有用到 right binding power的问题,表现在生成类似 a * b * c时,结果为 a * (b * c) 的Bug
[Impl][Fix] 修复跨文件(如import)报错信息错误的问题,现在Ast跟踪保存文件信息,报错统一从Error父类获取
[...] 忘了,好困不管了
This commit is contained in:
2026-01-19 04:13:55 +08:00
parent d398d457b5
commit 9e3f17711f
13 changed files with 176 additions and 127 deletions

View File

@@ -22,7 +22,7 @@ namespace Fig
// 逻辑
{Ast::Operator::And, {5, 6}},
{Ast::Operator::Or, {4, 5}},
{Ast::Operator::Not, {30, 31}}, // 一元
// {Ast::Operator::Not, {30, 31}}, // 一元
// 比较
{Ast::Operator::Equal, {7, 8}},
@@ -37,7 +37,7 @@ namespace Fig
{Ast::Operator::BitAnd, {6, 7}},
{Ast::Operator::BitOr, {4, 5}},
{Ast::Operator::BitXor, {5, 6}},
{Ast::Operator::BitNot, {30, 31}}, // 一元
// {Ast::Operator::BitNot, {30, 31}}, // 一元
{Ast::Operator::ShiftLeft, {15, 16}},
{Ast::Operator::ShiftRight, {15, 16}},
@@ -214,7 +214,7 @@ namespace Fig
variaPara = pname;
next(); // skip `...`
if (!isThis(TokenType::RightParen))
throw SyntaxError(
throwAddressableError<SyntaxError>(
u8"Expects right paren, variable parameter function can only have one parameter",
currentAAI.line,
currentAAI.column);
@@ -433,7 +433,7 @@ namespace Fig
}
else
{
throw SyntaxError(FString(u8"Invalid syntax"), currentAAI.line, currentAAI.column);
throwAddressableError<SyntaxError>(FString(u8"Invalid syntax"), currentAAI.line, currentAAI.column);
}
}
return makeAst<Ast::InterfaceDefAst>(interfaceName, methods, isPublic);
@@ -480,7 +480,7 @@ namespace Fig
}
else
{
throw SyntaxError(FString(u8"Invalid syntax"), currentAAI.line, currentAAI.column);
throwAddressableError<SyntaxError>(FString(u8"Invalid syntax"), currentAAI.line, currentAAI.column);
}
}
@@ -556,7 +556,8 @@ namespace Fig
{
if (finallyBlock != nullptr)
{
throw SyntaxError(u8"Duplicate try finally-block", currentAAI.line, currentAAI.column);
throwAddressableError<SyntaxError>(
u8"Duplicate try finally-block", currentAAI.line, currentAAI.column);
}
next(); // consume `finally`
expect(TokenType::LeftBrace);
@@ -678,11 +679,7 @@ namespace Fig
}
else
{
throw SyntaxError(
u8"invalid syntax",
currentAAI.line,
currentAAI.column
);
throwAddressableError<SyntaxError>(u8"invalid syntax", currentAAI.line, currentAAI.column);
}
return stmt;
}
@@ -1208,11 +1205,11 @@ namespace Fig
if (!isTokenOp(tok)) break;
op = Ast::TokenToOp.at(tok.getType());
Precedence lbp = getLeftBindingPower(op);
auto [lbp, rbp] = getBindingPower(op);
if (bp >= lbp) break;
next(); // consume op
lhs = makeAst<Ast::BinaryExprAst>(lhs, op, parseExpression(bp, stop, stop2));
lhs = makeAst<Ast::BinaryExprAst>(lhs, op, parseExpression(rbp, stop, stop2));
}
return lhs;
@@ -1232,10 +1229,8 @@ namespace Fig
auto stmt = __parseStatement();
if (!output.empty() && stmt->getType() == Ast::AstType::PackageSt)
{
throw SyntaxError(
u8"Package must be at the beginning of the file",
currentAAI.line,
currentAAI.column);
throwAddressableError<SyntaxError>(
u8"Package must be at the beginning of the file", currentAAI.line, currentAAI.column);
}
pushNode(stmt);
}

View File

@@ -6,6 +6,7 @@
#include <Core/fig_string.hpp>
#include <Error/error.hpp>
#include <memory>
#include <print>
#include <source_location>
#include <unordered_map>
@@ -22,6 +23,9 @@ namespace Fig
std::vector<Ast::AstBase> output;
std::vector<Token> previousTokens;
std::shared_ptr<FString> sourcePathPtr;
std::shared_ptr<std::vector<FString>> sourceLinesPtr;
size_t tokenPruduced = 0;
size_t currentTokenIndex = 0;
@@ -72,7 +76,11 @@ namespace Fig
static const std::unordered_map<Ast::Operator, std::pair<Precedence, Precedence>> opPrecedence;
static const std::unordered_map<Ast::Operator, Precedence> unaryOpPrecedence;
Parser(const Lexer &_lexer) : lexer(_lexer) {}
Parser(const Lexer &_lexer, FString _sourcePath, std::vector<FString> _sourceLines) : lexer(_lexer)
{
sourcePathPtr = std::make_shared<FString>(_sourcePath);
sourceLinesPtr = std::make_shared<std::vector<FString>>(_sourceLines);
}
AddressableError *getError() const { return error.get(); }
@@ -83,7 +91,7 @@ namespace Fig
std::source_location loc = std::source_location::current())
{
static_assert(std::is_base_of_v<AddressableError, _ErrT>, "_ErrT must derive from AddressableError");
_ErrT spError(msg, line, column, loc);
_ErrT spError(msg, line, column, *sourcePathPtr, *sourceLinesPtr, loc);
error = std::make_unique<_ErrT>(spError);
throw spError;
}
@@ -92,7 +100,7 @@ namespace Fig
{
static_assert(std::is_base_of_v<AddressableError, _ErrT>, "_ErrT must derive from AddressableError");
// line, column provide by `currentAAI`
_ErrT spError(msg, currentAAI.line, currentAAI.column, loc);
_ErrT spError(msg, currentAAI.line, currentAAI.column, *sourcePathPtr, *sourceLinesPtr, loc);
error = std::make_unique<_ErrT>(spError);
throw spError;
}
@@ -135,7 +143,10 @@ namespace Fig
CTI也需要显示转换否则转换完的pruduced又会被转回去变为 int64_t max
*/
currentTokenIndex++;
setCurrentAAI(Ast::AstAddressInfo{.line = currentToken().line, .column = currentToken().column});
setCurrentAAI(Ast::AstAddressInfo{.line = currentToken().line,
.column = currentToken().column,
.sourcePath = sourcePathPtr,
.sourceLines = sourceLinesPtr});
return;
}
if (isEOF()) return;
@@ -143,7 +154,11 @@ namespace Fig
tokenPruduced++;
if (tok == IllegalTok) throw lexer.getError();
currentTokenIndex = tokenPruduced - 1;
setCurrentAAI(Ast::AstAddressInfo{.line = tok.line, .column = tok.column});
setCurrentAAI(Ast::AstAddressInfo{.line = tok.line,
.column = tok.column,
.sourcePath = sourcePathPtr,
.sourceLines = sourceLinesPtr});
previousTokens.push_back(tok);
}
inline const Token &currentToken()
@@ -298,9 +313,8 @@ namespace Fig
Ast::ListExpr __parseListExpr(); // entry: current is `[`
Ast::MapExpr __parseMapExpr(); // entry: current is `{`
Ast::InitExpr __parseInitExpr(
Ast::Expression); // entry: current is `{`, ahead is struct type exp.
Ast::Expression __parseTupleOrParenExpr(); // entry: current is `(`
Ast::InitExpr __parseInitExpr(Ast::Expression); // entry: current is `{`, ahead is struct type exp.
Ast::Expression __parseTupleOrParenExpr(); // entry: current is `(`
Ast::FunctionLiteralExpr __parseFunctionLiteralExpr(); // entry: current is Token::LParen after Token::Function