From f53f7ec82c9d790dfce802d3a7db181178ca8b05 Mon Sep 17 00:00:00 2001 From: potapo <2720187907@qq.com> Date: Thu, 26 Mar 2026 19:40:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=87=BD=E6=95=B0=E8=BF=94=E5=9B=9E=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/ir/IR.h | 52 ++++++- include/irgen/IRGen.h | 58 +++++--- src/ir/IRBuilder.cpp | 217 ++++++++++++++++++++++++++++++ src/ir/IRPrinter.cpp | 66 ++++++++- src/ir/Instruction.cpp | 70 ++++++++++ src/ir/Module.cpp | 9 ++ src/irgen/IRGenDecl.cpp | 136 +++++++++++++++++-- src/irgen/IRGenExp.cpp | 291 ++++++++++++++++++++++++++++++---------- 8 files changed, 796 insertions(+), 103 deletions(-) diff --git a/include/ir/IR.h b/include/ir/IR.h index 4ea12dc..5f87875 100644 --- a/include/ir/IR.h +++ b/include/ir/IR.h @@ -216,7 +216,16 @@ class ConstantInt : public ConstantValue { }; // 后续还需要扩展更多指令类型。 -enum class Opcode { Add, Sub, Mul, Alloca, Load, Store, Ret }; +enum class Opcode { + Add, Sub, Mul, + Alloca, Load, Store, Ret, + Div, Mod, + ICmpEQ, ICmpNE, + ICmpSLT, ICmpSLE, + ICmpSGT, ICmpSGE, + And, Or, Not, + GEP, Call, + }; // User 是所有“会使用其他 Value 作为输入”的 IR 对象的抽象基类。 // 当前实现中只有 Instruction 继承自 User。 @@ -287,6 +296,26 @@ class StoreInst : public Instruction { Value* GetPtr() const; }; +class GEPInst : public Instruction { + public: + GEPInst(std::shared_ptr ptr_ty, + Value* base, + const std::vector& indices, + const std::string& name); + Value* GetBase() const; + const std::vector& GetIndices() const; +}; + +class CallInst : public Instruction { + public: + CallInst(std::shared_ptr ret_ty, + Function* callee, + const std::vector& args, + const std::string& name); + Function* GetCallee() const; + const std::vector& GetArgs() const; +}; + // BasicBlock 已纳入 Value 体系,便于后续向更完整 IR 类图靠拢。 // 当前其类型仍使用 void 作为占位,后续可替换为专门的 label type。 class BasicBlock : public Value { @@ -346,6 +375,7 @@ class Module { // 创建函数时当前只显式传入返回类型,尚未接入完整的 FunctionType。 Function* CreateFunction(const std::string& name, std::shared_ptr ret_type); + Function* FindFunction(const std::string& name) const; const std::vector>& GetFunctions() const; private: @@ -369,6 +399,26 @@ class IRBuilder { StoreInst* CreateStore(Value* val, Value* ptr); ReturnInst* CreateRet(Value* v); + BinaryInst* CreateDiv(Value* lhs, Value* rhs, const std::string& name); + BinaryInst* CreateMod(Value* lhs, Value* rhs, const std::string& name); + BinaryInst* CreateMul(Value* lhs, Value* rhs, const std::string& name); + BinaryInst* CreateSub(Value* lhs, Value* rhs, const std::string& name); + + // 比较运算接口 + BinaryInst* CreateICmpEQ(Value* lhs, Value* rhs, const std::string& name); + BinaryInst* CreateICmpNE(Value* lhs, Value* rhs, const std::string& name); + BinaryInst* CreateICmpSLT(Value* lhs, Value* rhs, const std::string& name); + BinaryInst* CreateICmpSLE(Value* lhs, Value* rhs, const std::string& name); + BinaryInst* CreateICmpSGT(Value* lhs, Value* rhs, const std::string& name); + BinaryInst* CreateICmpSGE(Value* lhs, Value* rhs, const std::string& name); + + BinaryInst* CreateAnd(Value* lhs, Value* rhs, const std::string& name); + BinaryInst* CreateOr(Value* lhs, Value* rhs, const std::string& name); + BinaryInst* CreateNot(Value* val, const std::string& name); + + GEPInst* CreateGEP(Value* base, const std::vector& indices, const std::string& name); + CallInst* CreateCall(Function* callee, const std::vector& args, const std::string& name); + private: Context& ctx_; BasicBlock* insert_block_; diff --git a/include/irgen/IRGen.h b/include/irgen/IRGen.h index 30b71c7..bf48098 100644 --- a/include/irgen/IRGen.h +++ b/include/irgen/IRGen.h @@ -21,7 +21,7 @@ class Value; } class IRGenImpl final : public SysYBaseVisitor { - public: +public: IRGenImpl(ir::Module& module, const SemanticContext& sema); // 顶层 @@ -29,36 +29,49 @@ class IRGenImpl final : public SysYBaseVisitor { std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override; // 块 - std::any visitBlock(SysYParser::BlockContext* ctx) override; + std::any visitBlock(SysYParser::BlockContext* ctx) override; // 注意:规则名为 Block std::any visitBlockItem(SysYParser::BlockItemContext* ctx) override; // 声明 std::any visitDecl(SysYParser::DeclContext* ctx) override; std::any visitVarDef(SysYParser::VarDefContext* ctx) override; + std::any visitConstDecl(SysYParser::ConstDeclContext* ctx) override; + std::any visitConstDef(SysYParser::ConstDefContext* ctx) override; + std::any visitInitVal(SysYParser::InitValContext* ctx) override; + std::any visitConstInitVal(SysYParser::ConstInitValContext* ctx) override; // 语句 std::any visitStmt(SysYParser::StmtContext* ctx) override; // 表达式 - std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) override; + std::any visitExp(SysYParser::ExpContext* ctx) override; + std::any visitCond(SysYParser::CondContext* ctx) override; std::any visitLVal(SysYParser::LValContext* ctx) override; - std::any visitAddExp(SysYParser::AddExpContext* ctx) override; + std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) override; + std::any visitUnaryExp(SysYParser::UnaryExpContext* ctx) override; + std::any visitFuncRParams(SysYParser::FuncRParamsContext* ctx) override; std::any visitMulExp(SysYParser::MulExpContext* ctx) override; + std::any visitAddExp(SysYParser::AddExpContext* ctx) override; std::any visitRelExp(SysYParser::RelExpContext* ctx) override; std::any visitEqExp(SysYParser::EqExpContext* ctx) override; - std::any visitCond(SysYParser::CondContext* ctx) override; + std::any visitLAndExp(SysYParser::LAndExpContext* ctx) override; + std::any visitLOrExp(SysYParser::LOrExpContext* ctx) override; + std::any visitConstExp(SysYParser::ConstExpContext* ctx) override; - private: - enum class BlockFlow { + // 辅助函数 + ir::Value* EvalExpr(SysYParser::ExpContext& expr); // 只保留一处 + ir::Value* EvalCond(SysYParser::CondContext& cond); + ir::Value* visitCallExp(SysYParser::UnaryExpContext* ctx); + +private: + // 辅助函数声明 + enum class BlockFlow{ Continue, Terminated, }; BlockFlow VisitBlockItemResult(SysYParser::BlockItemContext& item); - ir::Value* EvalExpr(SysYParser::ExpContext& expr); - ir::Value* EvalCond(SysYParser::CondContext& cond); - - // 辅助函数 + BlockFlow HandleReturnStmt(SysYParser::StmtContext* ctx); BlockFlow HandleIfStmt(SysYParser::StmtContext* ctx); BlockFlow HandleWhileStmt(SysYParser::StmtContext* ctx); @@ -66,20 +79,27 @@ class IRGenImpl final : public SysYBaseVisitor { BlockFlow HandleContinueStmt(SysYParser::StmtContext* ctx); BlockFlow HandleAssignStmt(SysYParser::StmtContext* ctx); - ir::Module& module_; - const SemanticContext& sema_; - ir::Function* func_; - ir::IRBuilder builder_; - // 名称绑定由 Sema 负责;IRGen 只维护“声明 -> 存储槽位”的代码生成状态。 - std::unordered_map storage_map_; - - // 循环栈,用于 break/continue + // 循环上下文结构 struct LoopContext { ir::BasicBlock* condBlock; ir::BasicBlock* bodyBlock; ir::BasicBlock* exitBlock; }; + + struct ArrayInfo { + std::vector elements; + std::vector dimensions; + }; + std::vector loopStack_; + + ir::Module& module_; + const SemanticContext& sema_; + ir::Function* func_; + ir::IRBuilder builder_; + std::unordered_map storage_map_; + std::unordered_map array_info_map_; + }; std::unique_ptr GenerateIR(SysYParser::CompUnitContext& tree, diff --git a/src/ir/IRBuilder.cpp b/src/ir/IRBuilder.cpp index 90f03c4..950a1aa 100644 --- a/src/ir/IRBuilder.cpp +++ b/src/ir/IRBuilder.cpp @@ -86,4 +86,221 @@ ReturnInst* IRBuilder::CreateRet(Value* v) { return insert_block_->Append(Type::GetVoidType(), v); } +BinaryInst* IRBuilder::CreateDiv(Value* lhs, Value* rhs, const std::string& name) { + if (!insert_block_) { + throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); + } + if (!lhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateDiv 缺少 lhs")); + } + if (!rhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateDiv 缺少 rhs")); + } + return insert_block_->Append(Opcode::Div, lhs->GetType(), lhs, rhs, name); +} + +BinaryInst* IRBuilder::CreateMod(Value* lhs, Value* rhs, const std::string& name) { + if (!insert_block_) { + throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); + } + if (!lhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateMod 缺少 lhs")); + } + if (!rhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateMod 缺少 rhs")); + } + return insert_block_->Append(Opcode::Mod, lhs->GetType(), lhs, rhs, name); +} + +BinaryInst* IRBuilder::CreateICmpEQ(Value* lhs, Value* rhs, const std::string& name) { + if (!insert_block_) { + throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); + } + if (!lhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpEQ 缺少 lhs")); + } + if (!rhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpEQ 缺少 rhs")); + } + // 比较运算返回int32类型,0表示假,1表示真 + return insert_block_->Append(Opcode::ICmpEQ, Type::GetInt32Type(), lhs, rhs, name); +} + +// 不等于比较 +BinaryInst* IRBuilder::CreateICmpNE(Value* lhs, Value* rhs, const std::string& name) { + if (!insert_block_) { + throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); + } + if (!lhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpNE 缺少 lhs")); + } + if (!rhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpNE 缺少 rhs")); + } + return insert_block_->Append(Opcode::ICmpNE, Type::GetInt32Type(), lhs, rhs, name); +} + +// 有符号小于 +BinaryInst* IRBuilder::CreateICmpSLT(Value* lhs, Value* rhs, const std::string& name) { + if (!insert_block_) { + throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); + } + if (!lhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpSLT 缺少 lhs")); + } + if (!rhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpSLT 缺少 rhs")); + } + return insert_block_->Append(Opcode::ICmpSLT, Type::GetInt32Type(), lhs, rhs, name); +} + +// 有符号小于等于 +BinaryInst* IRBuilder::CreateICmpSLE(Value* lhs, Value* rhs, const std::string& name) { + if (!insert_block_) { + throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); + } + if (!lhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpSLE 缺少 lhs")); + } + if (!rhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpSLE 缺少 rhs")); + } + return insert_block_->Append(Opcode::ICmpSLE, Type::GetInt32Type(), lhs, rhs, name); +} + +// 有符号大于 +BinaryInst* IRBuilder::CreateICmpSGT(Value* lhs, Value* rhs, const std::string& name) { + if (!insert_block_) { + throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); + } + if (!lhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpSGT 缺少 lhs")); + } + if (!rhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpSGT 缺少 rhs")); + } + return insert_block_->Append(Opcode::ICmpSGT, Type::GetInt32Type(), lhs, rhs, name); +} + +// 有符号大于等于 +BinaryInst* IRBuilder::CreateICmpSGE(Value* lhs, Value* rhs, const std::string& name) { + if (!insert_block_) { + throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); + } + if (!lhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpSGE 缺少 lhs")); + } + if (!rhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpSGE 缺少 rhs")); + } + return insert_block_->Append(Opcode::ICmpSGE, Type::GetInt32Type(), lhs, rhs, name); +} + +BinaryInst* IRBuilder::CreateAnd(Value* lhs, Value* rhs, const std::string& name) { + if (!insert_block_) { + throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); + } + if (!lhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateAnd 缺少 lhs")); + } + if (!rhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateAnd 缺少 rhs")); + } + return insert_block_->Append(Opcode::And, Type::GetInt32Type(), lhs, rhs, name); +} + +BinaryInst* IRBuilder::CreateOr(Value* lhs, Value* rhs, const std::string& name) { + if (!insert_block_) { + throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); + } + if (!lhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateOr 缺少 lhs")); + } + if (!rhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateOr 缺少 rhs")); + } + return insert_block_->Append(Opcode::Or, Type::GetInt32Type(), lhs, rhs, name); +} + +BinaryInst* IRBuilder::CreateNot(Value* val, const std::string& name) { + if (!insert_block_) { + throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); + } + if (!val) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateNot 缺少 operand")); + } + auto zero = CreateConstInt(0); + return CreateICmpEQ(val, zero, name); +} + +GEPInst* IRBuilder::CreateGEP(Value* base, + const std::vector& indices, + const std::string& name) { + if (!insert_block_) { + throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); + } + if (!base) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateGEP 缺少 base")); + } + + // 检查所有索引 + for (size_t i = 0; i < indices.size(); ++i) { + if (!indices[i]) { + throw std::runtime_error( + FormatError("ir", "IRBuilder::CreateGEP 索引 " + std::to_string(i) + " 为空")); + } + } + + // GEP返回指针类型,假设与base类型相同 + return insert_block_->Append(base->GetType(), base, indices, name); +} + +CallInst* IRBuilder::CreateCall(Function* callee, + const std::vector& args, + const std::string& name) { + if (!insert_block_) { + throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); + } + if (!callee) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateCall 缺少 callee")); + } + + // 检查所有参数 + for (size_t i = 0; i < args.size(); ++i) { + if (!args[i]) { + throw std::runtime_error( + FormatError("ir", "IRBuilder::CreateCall 参数 " + std::to_string(i) + " 为空")); + } + } + + // Call返回函数的返回类型 + return insert_block_->Append(callee->GetType(), callee, args, name); +} + +BinaryInst* IRBuilder::CreateMul(Value* lhs, Value* rhs, const std::string& name) { + if (!insert_block_) { + throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); + } + if (!lhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateMul 缺少 lhs")); + } + if (!rhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateMul 缺少 rhs")); + } + return CreateBinary(Opcode::Mul, lhs, rhs, name); +} + +BinaryInst* IRBuilder::CreateSub(Value* lhs, Value* rhs, const std::string& name) { + if (!insert_block_) { + throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点")); + } + if (!lhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateSub 缺少 lhs")); + } + if (!rhs) { + throw std::runtime_error(FormatError("ir", "IRBuilder::CreateSub 缺少 rhs")); + } + return CreateBinary(Opcode::Sub, lhs, rhs, name); +} + } // namespace ir diff --git a/src/ir/IRPrinter.cpp b/src/ir/IRPrinter.cpp index 5b11d63..2475063 100644 --- a/src/ir/IRPrinter.cpp +++ b/src/ir/IRPrinter.cpp @@ -43,6 +43,32 @@ static const char* OpcodeToString(Opcode op) { return "store"; case Opcode::Ret: return "ret"; + case Opcode::Div: + return "div"; + case Opcode::Mod: + return "mod"; + case Opcode::ICmpEQ: + return "icmp eq"; + case Opcode::ICmpNE: + return "icmp ne"; + case Opcode::ICmpSLT: + return "icmp slt"; + case Opcode::ICmpSLE: + return "icmp sle"; + case Opcode::ICmpSGT: + return "icmp sgt"; + case Opcode::ICmpSGE: + return "icmp sge"; + case Opcode::And: + return "and"; + case Opcode::Or: + return "or"; + case Opcode::Not: + return "not"; + case Opcode::GEP: + return "getelementptr"; + case Opcode::Call: + return "call"; } return "?"; } @@ -68,7 +94,18 @@ void IRPrinter::Print(const Module& module, std::ostream& os) { switch (inst->GetOpcode()) { case Opcode::Add: case Opcode::Sub: - case Opcode::Mul: { + case Opcode::Mul: + case Opcode::Div: + case Opcode::Mod: + case Opcode::And: + case Opcode::Not: + case Opcode::Or: + case Opcode::ICmpEQ: + case Opcode::ICmpNE: + case Opcode::ICmpSLT: + case Opcode::ICmpSLE: + case Opcode::ICmpSGT: + case Opcode::ICmpSGE:{ auto* bin = static_cast(inst); os << " " << bin->GetName() << " = " << OpcodeToString(bin->GetOpcode()) << " " @@ -100,6 +137,33 @@ void IRPrinter::Print(const Module& module, std::ostream& os) { << ValueToString(ret->GetValue()) << "\n"; break; } + case Opcode::GEP:{ + // 简化打印:只打印基本信息和操作数数量 + os << " " << inst->GetName() << " = getelementptr "; + os << TypeToString(*inst->GetType()) << " ("; + for (size_t i = 0; i < inst->GetNumOperands(); ++i) { + if (i > 0) os << ", "; + os << ValueToString(inst->GetOperand(i)); + } + os << ")\n"; + break; + } + case Opcode::Call:{ + // 简化打印:只打印基本信息和操作数数量 + os << " " << inst->GetName() << " = call "; + os << TypeToString(*inst->GetType()) << " ("; + for (size_t i = 0; i < inst->GetNumOperands(); ++i) { + if (i > 0) os << ", "; + os << ValueToString(inst->GetOperand(i)); + } + os << ")\n"; + break; + } + default: { + // 处理未知操作码 + os << " ; 未知指令: " << OpcodeToString(inst->GetOpcode()) << "\n"; + break; + } } } } diff --git a/src/ir/Instruction.cpp b/src/ir/Instruction.cpp index 7928716..351b6fb 100644 --- a/src/ir/Instruction.cpp +++ b/src/ir/Instruction.cpp @@ -148,4 +148,74 @@ Value* StoreInst::GetValue() const { return GetOperand(0); } Value* StoreInst::GetPtr() const { return GetOperand(1); } +GEPInst::GEPInst(std::shared_ptr ptr_ty, + Value* base, + const std::vector& indices, + const std::string& name) + : Instruction(Opcode::GEP, ptr_ty, name) { + // 添加base作为第一个操作数 + AddOperand(base); + + // 添加所有索引作为后续操作数 + for (auto* index : indices) { + AddOperand(index); + } +} + +Value* GEPInst::GetBase() const { + // 第一个操作数是base + return GetOperand(0); +} + +const std::vector& GEPInst::GetIndices() const { + // 需要返回索引列表,但Instruction只存储操作数 + // 这是一个设计问题:要么修改架构,要么提供辅助方法 + + // 简化实现:返回空vector(或创建临时vector) + static std::vector indices; + indices.clear(); + + // 索引从操作数1开始 + for (size_t i = 1; i < GetNumOperands(); ++i) { + indices.push_back(GetOperand(i)); + } + + return indices; +} + +// CallInst构造函数实现 +CallInst::CallInst(std::shared_ptr ret_ty, + Function* callee, + const std::vector& args, + const std::string& name) + : Instruction(Opcode::Call, ret_ty, name) { + // 添加callee作为第一个操作数 + AddOperand(callee); + + // 添加所有参数作为后续操作数 + for (auto* arg : args) { + AddOperand(arg); + } +} + +Function* CallInst::GetCallee() const { + // 第一个操作数是callee + return dynamic_cast(GetOperand(0)); +} + +const std::vector& CallInst::GetArgs() const { + // 需要返回参数列表,但Instruction只存储操作数 + // 简化实现:返回空vector(或创建临时vector) + static std::vector args; + args.clear(); + + // 参数从操作数1开始 + for (size_t i = 1; i < GetNumOperands(); ++i) { + args.push_back(GetOperand(i)); + } + + return args; +} + } // namespace ir + diff --git a/src/ir/Module.cpp b/src/ir/Module.cpp index 928efdc..c3a61f5 100644 --- a/src/ir/Module.cpp +++ b/src/ir/Module.cpp @@ -14,6 +14,15 @@ Function* Module::CreateFunction(const std::string& name, return functions_.back().get(); } +Function* Module::FindFunction(const std::string& name) const { + for (const auto& func : functions_) { + if (func->GetName() == name) { + return func.get(); + } + } + return nullptr; +} + const std::vector>& Module::GetFunctions() const { return functions_; } diff --git a/src/irgen/IRGenDecl.cpp b/src/irgen/IRGenDecl.cpp index 7ca55d0..34428c3 100644 --- a/src/irgen/IRGenDecl.cpp +++ b/src/irgen/IRGenDecl.cpp @@ -37,9 +37,53 @@ std::any IRGenImpl::visitDecl(SysYParser::DeclContext* ctx) { } } - // 处理 constDecl(暂不支持) + // 处理 constDecl if (ctx->constDecl()) { - throw std::runtime_error(FormatError("irgen", "常量声明暂未实现")); + auto* constDecl = ctx->constDecl(); + + if (constDecl->bType() && constDecl->bType()->Int()) { + for (auto* constDef : constDecl->constDef()) { + constDef->accept(this); + } + } else if (constDecl->bType() && constDecl->bType()->Float()) { + throw std::runtime_error(FormatError("irgen", "float常量暂未实现")); + } else { + throw std::runtime_error(FormatError("irgen", "未知的常量类型")); + } + } + return {}; +} + +// 实现常量定义 +std::any IRGenImpl::visitConstDef(SysYParser::ConstDefContext* ctx) { + if (!ctx || !ctx->Ident()) { + throw std::runtime_error(FormatError("irgen", "非法常量定义")); + } + + std::string const_name = ctx->Ident()->getText(); + + // 检查是否为数组 + bool is_array = !ctx->constExp().empty(); + + if (is_array) { + // 数组常量 + throw std::runtime_error(FormatError("irgen", "数组常量暂未实现")); + } else { + // 标量常量 + if (!ctx->constInitVal()) { + throw std::runtime_error(FormatError("irgen", "常量缺少初始值")); + } + + // 处理常量初始化值 + auto* const_init_val = ctx->constInitVal(); + + if (const_init_val->constExp()) { + // 常量表达式求值需要语义分析支持 + throw std::runtime_error(FormatError("irgen", "常量表达式求值暂未实现")); + } else { + // 聚合初始化 + throw std::runtime_error(FormatError("irgen", "常量聚合初始化暂未实现")); + } } return {}; @@ -61,23 +105,87 @@ std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) { throw std::runtime_error(FormatError("irgen", "声明重复生成存储槽位: " + varName)); } - // 分配存储 - auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp()); - storage_map_[ctx] = slot; + bool is_array = !ctx->constExp().empty(); - ir::Value* init = nullptr; - // 使用 initVal() 而不是 initValue() - if (auto* initVal = ctx->initVal()) { - if (initVal->exp()) { - init = EvalExpr(*initVal->exp()); + if (is_array) { + // 数组变量 + // 获取数组维度(简化处理) + int array_size = 10; // 默认数组大小 + + if (!ctx->constExp().empty()) { + // 尝试获取数组大小(需要常量表达式求值) + // 简化:假设第一个维度为10 + array_size = 10; + } + + // 分配数组存储(简化:为每个元素分配独立存储) + if (array_size > 100) { + throw std::runtime_error(FormatError("irgen", "数组大小太大")); + } + + std::vector element_slots; + for (int i = 0; i < array_size; i++) { + auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp() + "_" + std::to_string(i)); + element_slots.push_back(slot); + } + // 处理初始化 + if (auto* initVal = ctx->initVal()) { + if (initVal->exp()) { + // 标量初始化(只初始化第一个元素) + ir::Value* init = EvalExpr(*initVal->exp()); + builder_.CreateStore(init, element_slots[0]); + + // 其他元素初始化为0 + for (int i = 1; i < array_size; i++) { + builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]); + } + } else { + // 聚合初始化 + throw std::runtime_error(FormatError("irgen", "数组聚合初始化暂未实现")); + } + }else { + // 无初始化,所有元素初始化为0 + for (int i = 0; i < array_size; i++) { + builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]); + } + } + + // 存储第一个元素的地址 + storage_map_[ctx] = element_slots[0]; + + // 保存数组信息 + ArrayInfo info; + info.elements = element_slots; + info.dimensions = {array_size}; + array_info_map_[ctx] = info; + } else { + // 标量变量 + auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp()); + storage_map_[ctx] = slot; + + ir::Value* init = nullptr; + if (auto* initVal = ctx->initVal()) { + if (initVal->exp()) { + init = EvalExpr(*initVal->exp()); + } else { + // 聚合初始化(对于标量,大括号内应该只有一个值) + auto initVals = initVal->initVal(); + if (initVals.empty()) { + init = builder_.CreateConstInt(0); + } else if (initVals.size() == 1) { + init = std::any_cast(initVals[0]->accept(this)); + } else { + throw std::runtime_error( + FormatError("irgen", "标量变量聚合初始化只能有一个值")); + } + } } else { - // 数组初始化暂不支持 init = builder_.CreateConstInt(0); } - } else { - init = builder_.CreateConstInt(0); + + builder_.CreateStore(init, slot); } - builder_.CreateStore(init, slot); return {}; } + diff --git a/src/irgen/IRGenExp.cpp b/src/irgen/IRGenExp.cpp index acf9d9c..9a72deb 100644 --- a/src/irgen/IRGenExp.cpp +++ b/src/irgen/IRGenExp.cpp @@ -105,100 +105,255 @@ std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) { // 加法表达式 std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) { - if (!ctx) { - throw std::runtime_error(FormatError("irgen", "非法加法表达式")); - } - - // 注意:mulExp() 返回的是 MulExpContext*,不是 vector - // 需要递归处理 AddExp 的左结合性 - // AddExp : MulExp | AddExp ('+' | '-') MulExp - - // 先处理左操作数 - ir::Value* result = nullptr; - - // 如果有左子节点(AddExp),递归处理 - if (ctx->addExp()) { - result = std::any_cast(ctx->addExp()->accept(this)); - } else { - // 否则是 MulExp - result = std::any_cast(ctx->mulExp()->accept(this)); + if (!ctx) throw std::runtime_error(FormatError("irgen", "非法加法表达式")); + + if (!ctx->addExp()) { + return ctx->mulExp()->accept(this); } - - // 如果有运算符和右操作数 - if (ctx->AddOp() || ctx->SubOp()) { - ir::Value* rhs = std::any_cast(ctx->mulExp()->accept(this)); - - if (ctx->AddOp()) { - result = builder_.CreateAdd(result, rhs, module_.GetContext().NextTemp()); - } else if (ctx->SubOp()) { - // 减法:a - b = a + (-b) - // 暂时用加法,后续需要实现真正的减法 - result = builder_.CreateAdd(result, rhs, module_.GetContext().NextTemp()); - } + + ir::Value* left = std::any_cast(ctx->addExp()->accept(this)); + ir::Value* right = std::any_cast(ctx->mulExp()->accept(this)); + if (ctx->AddOp()) { + return builder_.CreateAdd(left, right, module_.GetContext().NextTemp()); + } else if (ctx->SubOp()) { + return builder_.CreateSub(left, right, module_.GetContext().NextTemp()); } - - return static_cast(result); + throw std::runtime_error(FormatError("irgen", "未知的加法操作符")); } // 在 IRGenExp.cpp 中添加 -// 简化版 visitMulExp +// visitMulExp std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) { - if (!ctx) { - throw std::runtime_error(FormatError("irgen", "非法乘法表达式")); - } - - // 暂时只返回 unaryExp 的值 - if (ctx->unaryExp()) { + if (!ctx) throw std::runtime_error(FormatError("irgen", "非法乘法表达式")); + + // 如果是基本形式 UnaryExp + if (!ctx->mulExp()) { return ctx->unaryExp()->accept(this); } - - // 如果有 mulExp 子节点,递归处理 - if (ctx->mulExp()) { - return ctx->mulExp()->accept(this); + + // 否则有左子节点和操作符 + ir::Value* left = std::any_cast(ctx->mulExp()->accept(this)); + ir::Value* right = std::any_cast(ctx->unaryExp()->accept(this)); + std::string op; + if (ctx->MulOp()) op = "*"; + else if (ctx->DivOp()) op = "/"; + else if (ctx->QuoOp()) op = "%"; + else throw std::runtime_error(FormatError("irgen", "缺少乘法类操作符")); + + if (op == "*") { + return builder_.CreateMul(left, right, module_.GetContext().NextTemp()); + } else if (op == "/") { + return builder_.CreateDiv(left, right, module_.GetContext().NextTemp()); + } else if (op == "%") { + return builder_.CreateMod(left, right, module_.GetContext().NextTemp()); } - - throw std::runtime_error(FormatError("irgen", "乘法表达式暂未实现")); + throw std::runtime_error(FormatError("irgen", "未知的乘法操作符")); } -// 关系表达式(暂未完整实现) +// 关系表达式 std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) { - if (!ctx) { - throw std::runtime_error(FormatError("irgen", "非法关系表达式")); - } - - // 简化:返回 addExp 的值 - if (ctx->addExp()) { + if (!ctx) throw std::runtime_error(FormatError("irgen", "非法关系表达式")); + + if (!ctx->relExp()) { return ctx->addExp()->accept(this); } - - throw std::runtime_error(FormatError("irgen", "关系表达式暂未实现")); + + ir::Value* left = std::any_cast(ctx->relExp()->accept(this)); + ir::Value* right = std::any_cast(ctx->addExp()->accept(this)); + + if (ctx->LOp()) { + return builder_.CreateICmpSLT(left, right, module_.GetContext().NextTemp()); + } else if (ctx->GOp()) { + return builder_.CreateICmpSGT(left, right, module_.GetContext().NextTemp()); + } else if (ctx->LeOp()) { + return builder_.CreateICmpSLE(left, right, module_.GetContext().NextTemp()); + } else if (ctx->GeOp()) { + return builder_.CreateICmpSGE(left, right, module_.GetContext().NextTemp()); + } + throw std::runtime_error(FormatError("irgen", "未知的关系操作符")); } -// 相等表达式(暂未完整实现) +// 相等表达式 std::any IRGenImpl::visitEqExp(SysYParser::EqExpContext* ctx) { - if (!ctx) { - throw std::runtime_error(FormatError("irgen", "非法相等表达式")); - } - - // 简化:返回 relExp 的值 - if (ctx->relExp()) { + if (!ctx) throw std::runtime_error(FormatError("irgen", "非法相等表达式")); + + if (!ctx->eqExp()) { return ctx->relExp()->accept(this); } - - throw std::runtime_error(FormatError("irgen", "相等表达式暂未实现")); + + ir::Value* left = std::any_cast(ctx->eqExp()->accept(this)); + ir::Value* right = std::any_cast(ctx->relExp()->accept(this)); + + if (ctx->EqOp()) { + return builder_.CreateICmpEQ(left, right, module_.GetContext().NextTemp()); + } else if (ctx->NeOp()) { + return builder_.CreateICmpNE(left, right, module_.GetContext().NextTemp()); + } + throw std::runtime_error(FormatError("irgen", "未知的相等操作符")); +} + +// 逻辑与 +std::any IRGenImpl::visitLAndExp(SysYParser::LAndExpContext* ctx) { + if (!ctx) throw std::runtime_error(FormatError("irgen", "非法逻辑与表达式")); + + if (!ctx->lAndExp()) { + return ctx->eqExp()->accept(this); + } + + ir::Value* left = std::any_cast(ctx->lAndExp()->accept(this)); + ir::Value* right = std::any_cast(ctx->eqExp()->accept(this)); + auto zero = builder_.CreateConstInt(0); + auto left_bool = builder_.CreateICmpNE(left, zero, module_.GetContext().NextTemp()); + auto right_bool = builder_.CreateICmpNE(right, zero, module_.GetContext().NextTemp()); + return builder_.CreateAnd(left_bool, right_bool, module_.GetContext().NextTemp()); +} + +// 逻辑或 +std::any IRGenImpl::visitLOrExp(SysYParser::LOrExpContext* ctx) { + if (!ctx) throw std::runtime_error(FormatError("irgen", "非法逻辑或表达式")); + + if (!ctx->lOrExp()) { + return ctx->lAndExp()->accept(this); + } + + ir::Value* left = std::any_cast(ctx->lOrExp()->accept(this)); + ir::Value* right = std::any_cast(ctx->lAndExp()->accept(this)); + auto zero = builder_.CreateConstInt(0); + auto left_bool = builder_.CreateICmpNE(left, zero, module_.GetContext().NextTemp()); + auto right_bool = builder_.CreateICmpNE(right, zero, module_.GetContext().NextTemp()); + return builder_.CreateOr(left_bool, right_bool, module_.GetContext().NextTemp()); +} + +std::any IRGenImpl::visitExp(SysYParser::ExpContext* ctx) { + if (!ctx) throw std::runtime_error(FormatError("irgen", "非法表达式")); + return ctx->addExp()->accept(this); } -// 条件表达式 std::any IRGenImpl::visitCond(SysYParser::CondContext* ctx) { + if (!ctx) throw std::runtime_error(FormatError("irgen", "非法条件表达式")); + return ctx->lOrExp()->accept(this); +} + +ir::Value* IRGenImpl::visitCallExp(SysYParser::UnaryExpContext* ctx) { + if (!ctx || !ctx->Ident()) { + throw std::runtime_error(FormatError("irgen", "非法函数调用")); + } + + std::string funcName = ctx->Ident()->getText(); + + // 语义检查(如果需要) + // auto* funcDecl = sema_.ResolveFuncCall(ctx); + // if (!funcDecl) throw ... + + // 收集实参 + std::vector args; + if (ctx->funcRParams()) { + auto argList = ctx->funcRParams()->accept(this); + args = std::any_cast>(argList); + } + + // 查找函数对象 + ir::Function* callee = module_.FindFunction(funcName); + if (!callee) { + throw std::runtime_error(FormatError("irgen", "未找到函数: " + funcName)); + } + + // 生成调用指令 + return builder_.CreateCall(callee, args, module_.GetContext().NextTemp()); +} + +// 实现一元表达式 +std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) { if (!ctx) { - throw std::runtime_error(FormatError("irgen", "非法条件表达式")); + throw std::runtime_error(FormatError("irgen", "非法一元表达式")); + } + + // 基本表达式 + if (ctx->primaryExp()) { + return ctx->primaryExp()->accept(this); } - // 简化:返回 lOrExp 的值 - if (ctx->lOrExp()) { - return ctx->lOrExp()->accept(this); + // 函数调用 + if (ctx->Ident()) { + return visitCallExp(ctx); } - throw std::runtime_error(FormatError("irgen", "条件表达式暂未实现")); + // 一元运算 + if (ctx->unaryOp() && ctx->unaryExp()) { + auto* operand = std::any_cast(ctx->unaryExp()->accept(this)); + std::string op = ctx->unaryOp()->getText(); + + if (op == "+") { + // +x 等价于 x + return operand; + } else if (op == "-") { + // -x 等价于 0 - x + ir::Value* zero = builder_.CreateConstInt(0); + return static_cast( + builder_.CreateBinary(ir::Opcode::Sub, zero, operand, + module_.GetContext().NextTemp())); + } else if (op == "!") { + return builder_.CreateNot(operand, module_.GetContext().NextTemp()); + } + } + + throw std::runtime_error(FormatError("irgen", "暂不支持的一元表达式形式")); +} + +// 实现函数调用 +std::any IRGenImpl::visitFuncRParams(SysYParser::FuncRParamsContext* ctx) { + if (!ctx) return std::vector{}; + std::vector args; + for (auto* exp : ctx->exp()) { + args.push_back(EvalExpr(*exp)); + } + return args; +} + +std::any IRGenImpl::visitConstDecl(SysYParser::ConstDeclContext* ctx) { + // 常量声明在编译时求值,不分配存储。只需遍历常量定义,将常量值存入符号表即可。 + // 由于 IRGen 阶段不需要常量的存储槽位,这里只触发子节点访问(常量定义会处理值)。 + for (auto* constDef : ctx->constDef()) { + constDef->accept(this); + } + return {}; +} + +std::any IRGenImpl::visitConstInitVal(SysYParser::ConstInitValContext* ctx) { + // 常量初始化值可能是单一常量表达式,也可能是大括号列表(聚合)。 + // 为简化,我们仅支持单一表达式(标量常量),数组常量暂未实现。 + if (ctx->constExp()) { + // 常量表达式求值:需要语义分析支持常量折叠,这里我们返回求值后的常量值。 + // 假设 sema_ 有方法 EvaluateConstExp 返回 int。 + auto* constExp = ctx->constExp(); + // 通过语义分析求值(暂未实现,先抛异常) + // int val = sema_.EvaluateConstExp(constExp); + // return builder_.CreateConstInt(val); + throw std::runtime_error(FormatError("irgen", "常量表达式求值暂未实现")); + } else { + // 聚合初始化:返回数组值,暂未实现 + throw std::runtime_error(FormatError("irgen", "常量聚合初始化暂未实现")); + } +} + +std::any IRGenImpl::visitInitVal(SysYParser::InitValContext* ctx) { + // 返回初始化的值(可能是单个表达式或聚合列表) + if (ctx->exp()) { + return EvalExpr(*ctx->exp()); + } else { + // 聚合初始化:需要返回一个列表,暂未实现 + throw std::runtime_error(FormatError("irgen", "聚合初始化暂未实现")); + } +} + +std::any IRGenImpl::visitConstExp(SysYParser::ConstExpContext* ctx) { + // 常量表达式由 AddExp 构成,我们直接复用表达式求值(但需要常量折叠)。 + // 由于常量表达式在编译时求值,IR 生成阶段其实不需要计算值,语义分析会提供。 + // 这里我们只用来获取 IR 值(例如数组大小),但数组大小需要在 IR 生成前就知道。 + // 暂时复用 EvalExpr(但 EvalExpr 生成 IR 指令,这不合适)。实际上常量表达式应在语义分析阶段求值,IRGen 直接使用结果。 + // 为避免复杂,我们暂时返回表达式的 IR 值(但会产生计算指令,不适合数组大小)。 + // 更好的做法是调用语义分析求值。 + // 这里先抛异常,等待语义团队提供接口。 + throw std::runtime_error(FormatError("irgen", "常量表达式求值暂未实现")); }