#include "irgen/IRGen.h" #include #include "SysYParser.h" #include "ir/IR.h" #include "utils/Log.h" // 表达式生成当前也只实现了很小的一个子集。 // 目前支持: // - 整数字面量 // - 普通局部变量读取 // - 括号表达式 // - 二元加法 // // 还未支持: // - 减乘除与一元运算 // - 赋值表达式 // - 函数调用 // - 数组、指针、下标访问 // - 条件与比较表达式 // - ... ir::Value* IRGenImpl::EvalExpr(SysYParser::ExpContext& expr) { std::cout << "[DEBUG IRGEN] EvalExpr: " << expr.getText() << std::endl; return std::any_cast(expr.accept(this)); } ir::Value* IRGenImpl::EvalCond(SysYParser::CondContext& cond) { return std::any_cast(cond.accept(this)); } std::any IRGenImpl::visitExp(SysYParser::ExpContext* ctx) { if (!ctx) { throw std::runtime_error(FormatError("irgen", "缺少表达式")); } std::cout << "[DEBUG IRGEN] visitExp: " << ctx->getText() << std::endl; return ctx->addExp()->accept(this); } // 基本表达式:数字、变量、括号表达式 std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) { std::cout << "[DEBUG IRGEN] visitPrimaryExp: " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx) { throw std::runtime_error(FormatError("irgen", "缺少基本表达式")); } // 处理数字字面量 if (ctx->DECIMAL_INT()) { int value = std::stoi(ctx->DECIMAL_INT()->getText()); return static_cast(builder_.CreateConstInt(value)); } if (ctx->HEX_INT()) { std::string hex = ctx->HEX_INT()->getText(); int value = std::stoi(hex, nullptr, 16); return static_cast(builder_.CreateConstInt(value)); } if (ctx->OCTAL_INT()) { std::string oct = ctx->OCTAL_INT()->getText(); int value = std::stoi(oct, nullptr, 8); return static_cast(builder_.CreateConstInt(value)); } if (ctx->ZERO()) { return static_cast(builder_.CreateConstInt(0)); } // 处理变量 if (ctx->lVal()) { return ctx->lVal()->accept(this); } // 处理括号表达式 if (ctx->L_PAREN() && ctx->exp()) { return EvalExpr(*ctx->exp()); } throw std::runtime_error(FormatError("irgen", "不支持的基本表达式类型")); } std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) { std::cout << "[DEBUG IRGEN] visitUnaryExp: " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx) { throw std::runtime_error(FormatError("irgen", "缺少一元表达式")); } if (ctx->primaryExp()) { auto result = ctx->primaryExp()->accept(this); std::cout << "[DEBUG IRGEN] visitUnaryExp primary result: " << (ctx->primaryExp() ? ctx->primaryExp()->getText() : "") << std::endl; return result; } if (ctx->Ident() && ctx->L_PAREN()) { std::string funcName = ctx->Ident()->getText(); ir::Function* callee = nullptr; for (auto& f : module_.GetFunctions()) { if (f->GetName() == funcName) { callee = f.get(); break; } } if (!callee) { throw std::runtime_error(FormatError("irgen", "找不到函数: " + funcName)); } std::vector args; if (ctx->funcRParams()) { for (auto* exp : ctx->funcRParams()->exp()) { args.push_back(EvalExpr(*exp)); } } ir::Value* result = builder_.CreateCall(callee, args, module_.GetContext().NextTemp()); return result; } if (ctx->unaryOp() && ctx->unaryExp()) { auto operand_any = ctx->unaryExp()->accept(this); std::cout << "[DEBUG IRGEN] visitUnaryExp operand_any.type=" << operand_any.type().name() << " text=" << ctx->unaryExp()->getText() << std::endl; auto* operand = std::any_cast(operand_any); if (ctx->unaryOp()->AddOp()) { return operand; } if (ctx->unaryOp()->SubOp()) { auto* zero = builder_.CreateConstInt(0); return static_cast( builder_.CreateBinary(ir::Opcode::Sub, zero, operand, module_.GetContext().NextTemp())); } if (ctx->unaryOp()->NotOp()) { // 逻辑非暂不支持,先默认 0/1 取反 // 这里简化:如果 operand ==0 返回1,否则返回0。(不做真实比较) // 需要后续完善比较指令。 return operand; } } throw std::runtime_error(FormatError("irgen", "不支持的 unaryExp")); } // 左值(变量)处理 // 1. 先通过语义分析结果把变量使用绑定回声明; // 2. 再通过 storage_map_ 找到该声明对应的栈槽位; // 3. 最后生成 load,把内存中的值读出来。 std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) { std::cout << "[DEBUG IRGEN] visitLVal: " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx || !ctx->Ident()) { throw std::runtime_error(FormatError("irgen", "非法左值")); } std::string varName = ctx->Ident()->getText(); // 从语义分析获取变量定义 auto* decl = sema_.ResolveVarUse(ctx); ir::Value* ptr = nullptr; if (decl) { auto it = storage_map_.find(decl); if (it != storage_map_.end()) { ptr = it->second; } } if (!ptr) { auto it2 = param_map_.find(varName); if (it2 != param_map_.end()) { ptr = it2->second; } } if (!ptr) { auto it3 = global_map_.find(varName); if (it3 != global_map_.end()) { ptr = it3->second; } } if (!ptr) { throw std::runtime_error( FormatError("irgen", "变量声明缺少存储槽位: " + varName)); } return static_cast( builder_.CreateLoad(ptr, module_.GetContext().NextTemp())); } // 加法表达式 std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) { std::cout << "[DEBUG IRGEN] visitAddExp: " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx) { throw std::runtime_error(FormatError("irgen", "非法加法表达式")); } // 注意:mulExp() 返回的是 MulExpContext*,不是 vector // 需要递归处理 AddExp 的左结合性 // AddExp : MulExp | AddExp ('+' | '-') MulExp // 先处理左操作数 ir::Value* result = nullptr; // 如果有左子节点(AddExp),递归处理 if (ctx->addExp()) { auto left_any = ctx->addExp()->accept(this); std::cout << "[DEBUG IRGEN] visitAddExp left_any.type=" << left_any.type().name() << " text=" << ctx->addExp()->getText() << std::endl; result = std::any_cast(left_any); } else { // 否则是 MulExp auto right_any = ctx->mulExp()->accept(this); std::cout << "[DEBUG IRGEN] visitAddExp right_any.type=" << right_any.type().name() << " text=" << ctx->mulExp()->getText() << std::endl; result = std::any_cast(right_any); } // 如果有运算符和右操作数 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()); } } return static_cast(result); } // 在 IRGenExp.cpp 中添加 std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) { std::cout << "[DEBUG IRGEN] visitMulExp: " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx) { throw std::runtime_error(FormatError("irgen", "非法乘法表达式")); } // 检查 unaryExp(返回指针,可能为 nullptr) auto* unaryExp = ctx->unaryExp(); std::cout << "[DEBUG] unaryExp is " << (unaryExp ? "not null" : "null") << std::endl; if (unaryExp) { std::cout << "[DEBUG] calling unaryExp->accept(this)" << std::endl; auto result = unaryExp->accept(this); std::cout << "[DEBUG] returned from unaryExp" << std::endl; return result; } // 检查 mulExp auto* mulExp = ctx->mulExp(); std::cout << "[DEBUG] mulExp is " << (mulExp ? "not null" : "null") << std::endl; if (mulExp) { std::cout << "[DEBUG] calling mulExp->accept(this)" << std::endl; auto result = mulExp->accept(this); std::cout << "[DEBUG] returned from mulExp" << std::endl; return result; } std::cout << "[DEBUG] no unaryExp or mulExp found!" << std::endl; throw std::runtime_error(FormatError("irgen", "乘法表达式暂未实现")); } // 关系表达式(支持 <, >, <=, >=) std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) { if (!ctx) { throw std::runtime_error(FormatError("irgen", "非法关系表达式")); } if (ctx->relExp() && ctx->addExp()) { auto left_any = ctx->relExp()->accept(this); auto right_any = ctx->addExp()->accept(this); auto* lhs = std::any_cast(left_any); auto* rhs = std::any_cast(right_any); if (ctx->LOp()) { return static_cast( builder_.CreateICmpLT(lhs, rhs, module_.GetContext().NextTemp())); } if (ctx->GOp()) { return static_cast( builder_.CreateICmpGT(lhs, rhs, module_.GetContext().NextTemp())); } if (ctx->LeOp()) { return static_cast( builder_.CreateICmpLE(lhs, rhs, module_.GetContext().NextTemp())); } if (ctx->GeOp()) { return static_cast( builder_.CreateICmpGE(lhs, rhs, module_.GetContext().NextTemp())); } throw std::runtime_error(FormatError("irgen", "未知关系运算符")); } if (ctx->addExp()) { return ctx->addExp()->accept(this); } throw std::runtime_error(FormatError("irgen", "关系表达式暂未实现")); } // 相等表达式(支持 ==, !=) std::any IRGenImpl::visitEqExp(SysYParser::EqExpContext* ctx) { if (!ctx) { throw std::runtime_error(FormatError("irgen", "非法相等表达式")); } if (ctx->eqExp() && ctx->relExp()) { auto left_any = ctx->eqExp()->accept(this); auto right_any = ctx->relExp()->accept(this); auto* lhs = std::any_cast(left_any); auto* rhs = std::any_cast(right_any); if (ctx->EqOp()) { return static_cast( builder_.CreateICmpEQ(lhs, rhs, module_.GetContext().NextTemp())); } if (ctx->NeOp()) { return static_cast( builder_.CreateICmpNE(lhs, rhs, module_.GetContext().NextTemp())); } throw std::runtime_error(FormatError("irgen", "未知相等运算符")); } if (ctx->relExp()) { return ctx->relExp()->accept(this); } throw std::runtime_error(FormatError("irgen", "相等表达式暂未实现")); } // 条件表达式 std::any IRGenImpl::visitCond(SysYParser::CondContext* ctx) { std::cout << "[DEBUG IRGEN] visitCond: " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx) { throw std::runtime_error(FormatError("irgen", "非法条件表达式")); } // 简化:返回 lOrExp 的值 if (ctx->lOrExp()) { return ctx->lOrExp()->accept(this); } throw std::runtime_error(FormatError("irgen", "条件表达式暂未实现")); }