You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
6.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// IRGen语法树 → IR
// 按语法树节点类型分发到 IRGenFunc/IRGenStmt/IRGenExp/IRGenDecl
#pragma once
#include <any>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include "SysYBaseVisitor.h"
#include "SysYParser.h"
#include "ir/IR.h"
#include "sem/Sema.h"
class IRGenImpl final : public SysYBaseVisitor {
public:
IRGenImpl(ir::Module& module, const SemanticContext& sema);
// ── 顶层 ──────────────────────────────────────────────────────────────────
std::any visitCompUnit(SysYParser::CompUnitContext* ctx) override;
// ── 函数 ──────────────────────────────────────────────────────────────────
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
// ── 块与块内项 ─────────────────────────────────────────────────────────────
std::any visitBlock(SysYParser::BlockContext* ctx) override;
std::any visitBlockItem(SysYParser::BlockItemContext* ctx) override;
// ── 声明 ──────────────────────────────────────────────────────────────────
std::any visitDecl(SysYParser::DeclContext* ctx) override;
std::any visitVarDecl(SysYParser::VarDeclContext* ctx) override;
std::any visitVarDef(SysYParser::VarDefContext* ctx) override;
std::any visitConstDecl(SysYParser::ConstDeclContext* ctx) override;
// ── 语句 ──────────────────────────────────────────────────────────────────
std::any visitStmt(SysYParser::StmtContext* ctx) override;
// ── 表达式(返回 ir::Value*i32 ─────────────────────────────────────────
std::any visitExp(SysYParser::ExpContext* ctx) override;
std::any visitAddExp(SysYParser::AddExpContext* ctx) override;
std::any visitMulExp(SysYParser::MulExpContext* ctx) override;
std::any visitUnaryExp(SysYParser::UnaryExpContext* ctx) override;
std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) override;
std::any visitLVar(SysYParser::LVarContext* ctx) override;
std::any visitNumber(SysYParser::NumberContext* ctx) override;
// ── 条件(返回 ir::Value*i1 ────────────────────────────────────────────
std::any visitCond(SysYParser::CondContext* ctx) override;
std::any visitLOrExp(SysYParser::LOrExpContext* ctx) override;
std::any visitLAndExp(SysYParser::LAndExpContext* ctx) override;
std::any visitEqExp(SysYParser::EqExpContext* ctx) override;
std::any visitRelExp(SysYParser::RelExpContext* ctx) override;
private:
// BlockFlow 用于通知调用者当前块是否已终结
enum class BlockFlow { Continue, Terminated };
// ── 辅助函数 ──────────────────────────────────────────────────────────────
// 求值表达式,返回 i32 值
ir::Value* EvalExpr(SysYParser::ExpContext& expr);
ir::Value* EvalExprAdd(SysYParser::AddExpContext& expr);
// 求值条件,返回 i1 值(供 if/while 使用)
ir::Value* EvalCond(SysYParser::CondContext& cond);
// 把整型值转为 i1 条件icmp ne i32 val, 0
ir::Value* ToI1(ir::Value* v);
// 把 i1 值零扩展为 i32
ir::Value* ToI32(ir::Value* v);
// 隐式类型转换确保两个操作数类型一致int 转 float
void ImplicitConvert(ir::Value*& lhs, ir::Value*& rhs);
// 转换为 float如果是 int
ir::Value* ToFloat(ir::Value* v);
// 转换为 int如果是 float
ir::Value* ToInt(ir::Value* v);
// 访问一条块内项,返回流控状态
BlockFlow VisitBlockItemResult(SysYParser::BlockItemContext& item);
// 访问 stmt返回流控状态
BlockFlow VisitStmt(SysYParser::StmtContext& stmt);
// 向外部函数声明注册(幂等)
void EnsureExternalDecl(const std::string& name);
// ── 状态 ──────────────────────────────────────────────────────────────────
ir::Module& module_;
const SemanticContext& sema_;
ir::Function* func_ = nullptr;
ir::IRBuilder builder_;
// 局部变量/参数的存储槽位:声明上下文 → alloca Value*
std::unordered_map<antlr4::ParserRuleContext*, ir::Value*> storage_map_;
// 全局变量/常量的存储槽位(不随函数切换清空)
std::unordered_map<antlr4::ParserRuleContext*, ir::Value*> global_storage_map_;
// 数组维度信息:声明上下文 → 各维度大小(从外到内)
std::unordered_map<antlr4::ParserRuleContext*, std::vector<int>> array_dims_;
std::unordered_map<antlr4::ParserRuleContext*, std::vector<int>> global_array_dims_;
// 辅助:求常量表达式的整数值(失败返回 0
int EvalConstExprInt(SysYParser::ConstExpContext* ctx);
// 辅助:计算一个 lVar 的元素地址(支持多维数组)
ir::Value* EvalLVarAddr(SysYParser::LVarContext* ctx);
// 是否处于全局作用域visitCompUnit 中处理 decl 时)
bool in_global_scope_ = false;
// 循环上下文break/continue 的目标块)
struct LoopCtx {
ir::BasicBlock* cond_bb; // continue 跳到这里
ir::BasicBlock* after_bb; // break 跳到这里
};
std::vector<LoopCtx> loop_stack_;
};
std::unique_ptr<ir::Module> GenerateIR(SysYParser::CompUnitContext& tree,
const SemanticContext& sema);