[VER] 0.4.0-alpha
All checks were successful
Release Build / build-windows-x64 (push) Successful in 54s
Release Build / build-linux-x64 (push) Successful in 1m21s

[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

@@ -24,6 +24,10 @@
#include <memory>
#include <unordered_map>
#ifndef SourceInfo
#define SourceInfo(ptr) (ptr->sourcePath), (ptr->sourceLines)
#endif
namespace Fig
{
@@ -210,11 +214,10 @@ namespace Fig
return evalIndexExpr(ie, ctx);
}
default: {
// throw EvaluatorError(
// u8"TypeError",
// std::format("Expression '{}' doesn't refer to a lvalue", exp->typeName().toBasicString()),
// exp);
throw EvaluatorError(
u8"TypeError",
std::format("Expression '{}' doesn't refer to a lvalue", exp->typeName().toBasicString()),
exp);
}
}
}
@@ -316,7 +319,7 @@ namespace Fig
return std::make_shared<Object>(implements(si.parentType, it.type, ctx));
}
if (ValueType::isTypeBuiltin(lhsType) && rhsType == ValueType::StructType)
if (ValueType::isTypeBuiltin(lhsType) && rhsType == ValueType::StructType)
{
const StructType &st = rhs->as<StructType>();
const TypeInfo &type = st.type;
@@ -329,24 +332,20 @@ namespace Fig
e.g:
"123" is String
L OP R
其中 L 类型为 String
而 R 类型为 StructType (builtins.hpp) 中注册
拿到 R 的 StructType, 其中的 type 为 String
*/
if (lhs->getTypeInfo() == type)
{
return Object::getTrueInstance();
}
if (lhs->getTypeInfo() == type) { return Object::getTrueInstance(); }
return Object::getFalseInstance();
}
throw EvaluatorError(
u8"TypeError",
std::format("Unsupported operator `is` for '{}' && '{}'",
lhsType.toString().toBasicString(),
rhsType.toString().toBasicString()),
bin->lexp);
throw EvaluatorError(u8"TypeError",
std::format("Unsupported operator `is` for '{}' && '{}'",
lhsType.toString().toBasicString(),
rhsType.toString().toBasicString()),
bin->lexp);
}
case Operator::BitAnd: {
@@ -1017,11 +1016,8 @@ namespace Fig
return std::make_shared<Object>(std::move(map));
}
default:
{
throw RuntimeError(FString(
std::format("err type of expr: {}", magic_enum::enum_name(type))
));
default: {
throw RuntimeError(FString(std::format("err type of expr: {}", magic_enum::enum_name(type))));
}
}
return Object::getNullInstance(); // ignore warning
@@ -1478,11 +1474,13 @@ namespace Fig
case BreakSt: {
if (!ctx->parent)
{
throw EvaluatorError(u8"BreakOutsideLoopError", u8"`break` statement outside loop", stmt);
throw EvaluatorError(
u8"BreakOutsideLoopError", u8"`break` statement outside loop", stmt);
}
if (!ctx->isInLoopContext())
{
throw EvaluatorError(u8"BreakOutsideLoopError", u8"`break` statement outside loop", stmt);
throw EvaluatorError(
u8"BreakOutsideLoopError", u8"`break` statement outside loop", stmt);
}
return StatementResult::breakFlow();
}
@@ -1490,11 +1488,13 @@ namespace Fig
case ContinueSt: {
if (!ctx->parent)
{
throw EvaluatorError(u8"ContinueOutsideLoopError", u8"`continue` statement outside loop", stmt);
throw EvaluatorError(
u8"ContinueOutsideLoopError", u8"`continue` statement outside loop", stmt);
}
if (!ctx->isInLoopContext())
{
throw EvaluatorError(u8"ContinueOutsideLoopError", u8"`continue` statement outside loop", stmt);
throw EvaluatorError(
u8"ContinueOutsideLoopError", u8"`continue` statement outside loop", stmt);
}
return StatementResult::continueFlow();
}
@@ -1620,28 +1620,30 @@ namespace Fig
ContextPtr Evaluator::loadModule(const std::filesystem::path &path)
{
FString modSourcePath(path.string());
std::ifstream file(path);
assert(file.is_open());
std::string source((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
file.close();
Lexer lexer((FString(source)));
Parser parser(lexer);
std::vector<Ast::AstBase> asts;
std::vector<FString> modSourceLines = Utils::splitSource(FString(source));
std::vector<FString> sourceLines = Utils::splitSource(FString(source));
Lexer lexer((FString(source)), modSourcePath, modSourceLines);
Parser parser(lexer, modSourcePath, modSourceLines);
std::vector<Ast::AstBase> asts;
asts = parser.parseAll();
Evaluator evaluator;
evaluator.SetSourcePath(FString(path.string()));
evaluator.SetSourcePath(modSourcePath);
evaluator.SetSourceLines(modSourceLines);
ContextPtr modctx = std::make_shared<Context>(FString(std::format("<Module at {}>", path.string())), nullptr);
evaluator.SetGlobalContext(modctx);
evaluator.RegisterBuiltinsValue();
evaluator.Run(asts);
evaluator.Run(asts); // error upward pass-by, log outside, we have already keep info in evaluator error
return evaluator.global;
}
@@ -1663,8 +1665,9 @@ namespace Fig
if (ctx->containsInThisScope(modName))
{
throw EvaluatorError(
u8"RedeclarationError", std::format("{} has already been declared.", modName.toBasicString()), i);
throw EvaluatorError(u8"RedeclarationError",
std::format("{} has already been declared.", modName.toBasicString()),
i);
}
ctx->def(
modName, ValueType::Module, AccessModifier::PublicConst, std::make_shared<Object>(Module(modName, modCtx)));

View File

@@ -1,6 +1,6 @@
#include "Ast/Statements/ImplementSt.hpp"
#include "Ast/Statements/InterfaceDefSt.hpp"
#include "Value/Type.hpp"
#include <Ast/Statements/ImplementSt.hpp>
#include <Ast/Statements/InterfaceDefSt.hpp>
#include <Value/Type.hpp>
#include <Ast/ast.hpp>
#include <Context/context.hpp>
@@ -63,12 +63,18 @@ namespace Fig
public:
FString sourcePath;
std::vector<FString> sourceLines;
void SetSourcePath(const FString &sp)
{
sourcePath = sp;
}
void SetSourceLines(const std::vector<FString> &sl)
{
sourceLines = sl;
}
void SetGlobalContext(ContextPtr ctx)
{
assert(ctx != nullptr);

View File

@@ -10,7 +10,10 @@ namespace Fig
public:
FString typeName;
using AddressableError::AddressableError;
EvaluatorError(FString _typeName, FString msg, Ast::AstBase ast, std::source_location loc = std::source_location::current())
EvaluatorError(FString _typeName,
FString msg,
Ast::AstBase ast,
std::source_location loc = std::source_location::current())
{
message = msg;
line = ast->getAAI().line;
@@ -20,8 +23,13 @@ namespace Fig
typeName = std::move(_typeName);
sourcePath = *ast->getAAI().sourcePath;
sourceLines = *ast->getAAI().sourceLines;
}
EvaluatorError(FString _typeName, std::string_view msg, Ast::AstBase ast, std::source_location loc = std::source_location::current())
EvaluatorError(FString _typeName,
std::string_view msg,
Ast::AstBase ast,
std::source_location loc = std::source_location::current())
{
message = FString::fromBasicString(std::string(msg.data()));
line = ast->getAAI().line;
@@ -30,13 +38,11 @@ namespace Fig
src_loc = std::move(loc);
typeName = std::move(_typeName);
sourcePath = *ast->getAAI().sourcePath;
sourceLines = *ast->getAAI().sourceLines;
}
virtual FString getErrorType() const override
{
return typeName;
}
virtual FString getErrorType() const override { return typeName; }
};
};
}; // namespace Fig

View File

@@ -89,7 +89,9 @@ int main(int argc, char **argv)
std::string source((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
file.close();
Fig::Lexer lexer((Fig::FString(source)));
std::vector<FString> sourceLines = Fig::Utils::splitSource(Fig::FString(source));
Fig::Lexer lexer((Fig::FString(source)), sourcePath, sourceLines);
// Token tok;
// while ((tok = lexer.nextToken()).getType() != TokenType::EndOfFile)
@@ -97,11 +99,9 @@ int main(int argc, char **argv)
// std::println("{}", tok.toString().toBasicString());
// }
Fig::Parser parser(lexer);
Fig::Parser parser(lexer, sourcePath, sourceLines);
std::vector<Fig::Ast::AstBase> asts;
std::vector<FString> sourceLines = Fig::Utils::splitSource(Fig::FString(source));
try
{
asts = parser.parseAll();
@@ -109,7 +109,7 @@ int main(int argc, char **argv)
catch (const Fig::AddressableError &e)
{
addressableErrorCount++;
ErrorLog::logAddressableError(e, sourcePath, sourceLines);
ErrorLog::logAddressableError(e);
return 1;
}
catch (const Fig::UnaddressableError &e)
@@ -134,6 +134,7 @@ int main(int argc, char **argv)
Fig::Evaluator evaluator;
evaluator.SetSourcePath(sourcePath);
evaluator.SetSourceLines(sourceLines);
evaluator.CreateGlobalContext();
evaluator.RegisterBuiltinsValue();
@@ -144,7 +145,7 @@ int main(int argc, char **argv)
catch (const Fig::AddressableError &e)
{
addressableErrorCount++;
ErrorLog::logAddressableError(e, sourcePath, sourceLines);
ErrorLog::logAddressableError(e);
evaluator.printStackTrace();
return 1;
}