feat: 添加If语句及块语句解析支持

This commit is contained in:
2026-02-20 15:46:33 +08:00
parent 2631f76da1
commit eb20993e27
6 changed files with 288 additions and 23 deletions

View File

@@ -15,4 +15,5 @@
#include <Ast/Expr/PrefixExpr.hpp>
#include <Ast/Stmt/ExprStmt.hpp>
#include <Ast/Stmt/IfStmt.hpp>
#include <Ast/Stmt/VarDecl.hpp>

View File

@@ -15,10 +15,11 @@ namespace Fig
{
enum class AstType : std::uint8_t
{
AstNode, // 基类
Program, // 程序
Expr, // 表达式
Stmt, // 语句
AstNode, // 基类
Program, // 程序
Expr, // 表达式
Stmt, // 语句
BlockStmt, // 块语句
/* Expressions */
IdentiExpr, // 标识符表达式
@@ -30,8 +31,10 @@ namespace Fig
CallExpr, // 后缀表达式,函数调用
/* Statements */
ExprStmt, // 表达式语句,如 println(1)
VarDecl, // 变量声明
ExprStmt, // 表达式语句,如 println(1)
VarDecl, // 变量声明
IfStmt, // If语句
ElseIfStmt, // ElseIf语句不准悬空
};
struct AstNode
{
@@ -81,7 +84,29 @@ namespace Fig
virtual String toString() const override
{
return "Program";
return "<Program>";
}
};
struct BlockStmt final : public Stmt
{
DynArray<Stmt *> nodes;
BlockStmt()
{
type = AstType::BlockStmt;
}
BlockStmt(DynArray<Stmt *> _nodes)
{
type = AstType::BlockStmt;
nodes = std::move(_nodes);
if (!_nodes.empty())
{
location = std::move(_nodes.back()->location);
}
}
virtual String toString() const override
{
return "<BlockStmt>";
}
};
}; // namespace Fig

69
src/Ast/Stmt/IfStmt.hpp Normal file
View File

@@ -0,0 +1,69 @@
/*!
@file src/Ast/Stmt/IfStmt.hpp
@brief IfStmt定义
@author PuqiAR (im@puqiar.top)
@date 2026-02-20
*/
#pragma once
#include <Ast/Base.hpp>
namespace Fig
{
struct ElseIfStmt final : public Stmt
{
Expr *cond;
BlockStmt *consequent;
ElseIfStmt()
{
type = AstType::ElseIfStmt;
}
ElseIfStmt(Expr *_cond, BlockStmt *_consequent, SourceLocation _location) :
cond(_cond), consequent(_consequent)
{
type = AstType::ElseIfStmt;
location = std::move(_location);
}
virtual String toString() const override
{
return std::format("<ElseIf ({}) then {}>", cond->toString(), consequent->toString());
}
};
struct IfStmt final : public Stmt
{
Expr *cond;
BlockStmt *consequent;
DynArray<ElseIfStmt *> elifs;
BlockStmt *alternate;
IfStmt()
{
type = AstType::IfStmt;
}
IfStmt(Expr *_cond,
BlockStmt *_consequent,
DynArray<ElseIfStmt *> _elifs,
BlockStmt *_alternate,
SourceLocation _location) :
cond(_cond), consequent(_consequent), elifs(std::move(_elifs)), alternate(_alternate)
{
type = AstType::IfStmt;
location = std::move(_location);
}
virtual String toString() const override
{
return std::format("<If ({}) then {}, else if * {}, else {}>",
cond->toString(),
consequent->toString(),
elifs.size(),
alternate->toString());
}
};
}; // namespace Fig