feat: 添加“while 语句”支持,并对解析器进行重构以处理控制流相关内容

- 引入了 WhileStmt 结构来表示 while 循环语句。
- 在解析器中实现了对 while 语句的解析逻辑。
- 在分析器中为 while 语句添加了语义分析。
- 重构了现有的解析器方法,以利用 StateProtector 进行状态管理。
- 更新了对各种表达式和语句的错误处理。
- 移除了未使用的终止符管理方法,并简化了表达式解析。
- 将 FigLSPServer.cpp 重命名为 LSPServer.cpp,并调整了构建配置。
- 增强了重复声明和类型错误的错误报告。
- 在多个文件中改进了代码格式和一致性。
This commit is contained in:
2026-02-25 17:31:00 +08:00
parent b7bb889676
commit a0fb8cdffb
25 changed files with 670 additions and 355 deletions

View File

@@ -29,12 +29,14 @@ namespace Fig
struct LocalVar
{
bool isPublic; // 是否向上级/同级其他域公开
String name;
std::uint8_t reg; // 寄存器(相对 frame base 的寄存器 id)
int depth; // 作用域深度
int localId; // AST 传来的纯数字 ID
std::uint8_t reg; // 分配到的物理寄存器 ID
int depth; // 物理作用域深度(用于 EndScope 释放寄存器)
};
static constexpr int MAX_LOCALS = 250;
static constexpr int MAX_CONSTANTS = UINT16_MAX;
// 任何跨函数、跨模块的编译,都压入弹出这个 State
struct FuncState
{
@@ -46,9 +48,12 @@ namespace Fig
int scopeDepth = 0;
DynArray<LocalVar> locals;
std::uint8_t fastRegMap[UINT8_MAX + 1]; // 256, 索引 = localId, 值 = 寄存器 id
FuncState(String _name, FuncState *enc = nullptr) : name(std::move(_name)), enclosing(enc)
{
proto = new Proto();
std::fill_n(fastRegMap, 256, UINT8_MAX); // 255代表未分配
}
// 注意:这里不 delete proto因为 proto 是要作为编译产物吐出去的
};
@@ -100,7 +105,7 @@ namespace Fig
std::uint8_t AllocReg()
{
if (current->freeReg >= 250)
if (current->freeReg >= 255)
{
assert(false && "Register overflow!");
}
@@ -137,6 +142,13 @@ namespace Fig
std::uint16_t AddConstant(Value v)
{
// TODO: 查重
auto it =
std::find(current->proto->constants.begin(), current->proto->constants.end(), v);
if (it != current->proto->constants.end())
{
return std::distance(current->proto->constants.begin(), it);
}
current->proto->constants.push_back(v);
return static_cast<std::uint16_t>(current->proto->constants.size() - 1);
}
@@ -156,73 +168,18 @@ namespace Fig
}
}
bool HasLocalInCurrentScope(const String &name)
{
// 逆向查重
for (auto it = current->locals.rbegin(); it != current->locals.rend(); ++it)
{
if (it->depth < current->scopeDepth)
break; // 已经超出了当前深度,提前阻断
if (it->name == name)
return true;
}
return false;
}
bool HasLocal(const String &name)
{
for (auto it = current->locals.rbegin(); it != current->locals.rend(); ++it)
{
if (it->name == name)
{
if (it->depth == current->scopeDepth)
{
return true; // 同级不管 public直接捕获
}
else if (it->isPublic)
{
return true; // 不同级变量 public才能被捕捉
}
}
}
return false;
}
std::uint8_t ResolveLocal(const String &name)
{
// 变量遮蔽: 永远先使用同级已有的变量, 所以逆向遍历
for (auto it = current->locals.rbegin(); it != current->locals.rend(); ++it)
{
if (it->name == name)
{
if (it->depth < current->scopeDepth && !it->isPublic)
{
assert(
false
&& "ResolveLocal: Attempt to access a private variable from an outer scope!");
}
return it->reg;
}
}
// 如果在本 Frame 没找到,那就是外层函数的变量 (闭包 Upvalue) 或者全局变量 (Global)。
assert(
false
&& "ResolveLocal: Variable not found in current frame (Upvalue/Global not implemented yet)!");
return UINT8_MAX;
}
std::uint8_t DeclareLocal(bool isPublic, const String &name)
std::uint8_t DeclareLocal(int localId)
{
std::uint8_t reg = AllocReg();
current->locals.push_back(LocalVar{isPublic, name, reg, current->scopeDepth});
current->locals.push_back(LocalVar{localId, reg, current->scopeDepth});
current->fastRegMap[localId] = reg;
return reg;
}
std::uint8_t DeclareLocal(bool isPublic, const String &name, std::uint8_t reg)
std::uint8_t DeclareLocal(int localId, std::uint8_t reg) // 表示复用哪个寄存器
{
current->locals.push_back(LocalVar{isPublic, name, reg, current->scopeDepth});
current->locals.push_back(LocalVar{localId, reg, current->scopeDepth});
current->fastRegMap[localId] = reg;
return reg;
}
@@ -261,23 +218,25 @@ namespace Fig
return location;
}
Result<std::uint8_t, Error> CompileIdentiExpr(IdentiExpr *);
Result<std::uint8_t, Error> CompileLiteral(LiteralExpr *);
Result<std::uint8_t, Error> compileIdentiExpr(IdentiExpr *);
Result<std::uint8_t, Error> compileLiteral(LiteralExpr *);
Result<std::uint8_t, Error> CompileAssignment(
Result<std::uint8_t, Error> compileAssignment(
InfixExpr *); // 编译赋值,由 CompileInfixExpr调用
Result<std::uint8_t, Error> CompileInfixExpr(InfixExpr *);
Result<std::uint8_t, Error> compileInfixExpr(InfixExpr *);
Result<std::uint8_t, Error> CompileLeftValue(
Result<std::uint8_t, Error> compileLeftValue(
Expr *); // 左值对象,可以是变量、结构体字段或模块对象
Result<std::uint8_t, Error> CompileExpr(Expr *);
Result<std::uint8_t, Error> compileExpr(Expr *);
/* Statements */
Result<void, Error> CompileVarDecl(VarDecl *);
Result<void, Error> CompileBlockStmt(BlockStmt *);
Result<void, Error> CompileIfStmt(IfStmt *);
Result<void, Error> CompileStmt(Stmt *);
Result<void, Error> compileVarDecl(VarDecl *);
Result<void, Error> compileBlockStmt(BlockStmt *);
Result<void, Error> compileIfStmt(IfStmt *);
Result<void, Error> compileWhileStmt(WhileStmt *);
Result<void, Error> compileStmt(Stmt *);
};
inline void DisassembleInstruction(Instruction inst, std::size_t index)