#include "irgen/IRGen.h" #include #include "SysYParser.h" #include "ir/IR.h" #include "utils/Log.h" // 表达式生成当前也只实现了很小的一个子集。 // 目前支持: // - 整数字面量 // - 普通局部变量读取 // - 括号表达式 // - 二元加法 // // 还未支持: // - 减乘除与一元运算 // - 赋值表达式 // - 函数调用 // - 数组、指针、下标访问 // - 条件与比较表达式 // - ... // 表达式生成 ir::Value* IRGenImpl::EvalExpr(SysYParser::ExpContext& expr) { std::cerr << "[DEBUG IRGEN] EvalExpr: 开始处理表达式 " << expr.getText() << std::endl; try { auto result_any = expr.accept(this); if (!result_any.has_value()) { std::cerr << "[ERROR] EvalExpr: result_any has no value" << std::endl; throw std::runtime_error("表达式求值结果为空"); } try { ir::Value* result = std::any_cast(result_any); std::cerr << "[DEBUG] EvalExpr: success, result = " << (void*)result << std::endl; return result; } catch (const std::bad_any_cast& e) { std::cerr << "[ERROR] EvalExpr: bad any_cast - " << e.what() << std::endl; std::cerr << " Type info: " << result_any.type().name() << std::endl; throw std::runtime_error(FormatError("irgen", "表达式求值返回了错误的类型")); } } catch (const std::exception& e) { std::cerr << "[ERROR] Exception in EvalExpr: " << e.what() << std::endl; throw; } } ir::Value* IRGenImpl::EvalCond(SysYParser::CondContext& cond) { std::cerr << "[DEBUG IRGEN] EvalCond: 开始处理条件表达式 " << cond.getText() << std::endl; return std::any_cast(cond.accept(this)); } // 基本表达式:数字、变量、括号表达式 std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) { std::cerr << "[DEBUG IRGEN] visitPrimaryExp: 开始处理基本表达式 " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx) { throw std::runtime_error(FormatError("irgen", "缺少基本表达式")); } std::cerr << "[DEBUG] visitPrimaryExp" << std::endl; // 处理数字字面量 if (ctx->DECIMAL_INT()) { int value = std::stoi(ctx->DECIMAL_INT()->getText()); ir::Value* const_int = builder_.CreateConstInt(value); std::cerr << "[DEBUG] visitPrimaryExp: constant int " << value << " created as " << (void*)const_int << std::endl; return static_cast(const_int); } if (ctx->HEX_FLOAT()) { std::string hex_float_str = ctx->HEX_FLOAT()->getText(); float value = 0.0f; try { value = std::stof(hex_float_str); } catch (const std::exception& e) { std::cerr << "[WARNING] 无法解析十六进制浮点数: " << hex_float_str << ",使用0.0代替" << std::endl; value = 0.0f; } ir::Value* const_float = builder_.CreateConstFloat(value); std::cerr << "[DEBUG] visitPrimaryExp: constant hex float " << value << " created as " << (void*)const_float << std::endl; return static_cast(const_float); } if (ctx->DEC_FLOAT()) { std::string dec_float_str = ctx->DEC_FLOAT()->getText(); float value = 0.0f; try { value = std::stof(dec_float_str); } catch (const std::exception& e) { std::cerr << "[WARNING] 无法解析十进制浮点数: " << dec_float_str << ",使用0.0代替" << std::endl; value = 0.0f; } ir::Value* const_float = builder_.CreateConstFloat(value); std::cerr << "[DEBUG] visitPrimaryExp: constant dec float " << value << " created as " << (void*)const_float << std::endl; return static_cast(const_float); } if (ctx->HEX_INT()) { std::string hex = ctx->HEX_INT()->getText(); int value = std::stoi(hex, nullptr, 16); ir::Value* const_int = builder_.CreateConstInt(value); std::cerr << "[DEBUG] visitPrimaryExp: constant hex int " << value << " created as " << (void*)const_int << std::endl; return static_cast(const_int); } if (ctx->OCTAL_INT()) { std::string oct = ctx->OCTAL_INT()->getText(); int value = std::stoi(oct, nullptr, 8); ir::Value* const_int = builder_.CreateConstInt(value); std::cerr << "[DEBUG] visitPrimaryExp: constant octal int " << value << " created as " << (void*)const_int << std::endl; return static_cast(const_int); } if (ctx->ZERO()) { ir::Value* const_int = builder_.CreateConstInt(0); std::cerr << "[DEBUG] visitPrimaryExp: constant zero int created" << std::endl; return static_cast(const_int); } // 处理变量 if (ctx->lVal()) { std::cerr << "[DEBUG] visitPrimaryExp: visiting lVal" << std::endl; return ctx->lVal()->accept(this); } // 处理括号表达式 if (ctx->L_PAREN() && ctx->exp()) { std::cerr << "[DEBUG] visitPrimaryExp: visiting parenthesized expression" << std::endl; return EvalExpr(*ctx->exp()); } std::cerr << "[ERROR] visitPrimaryExp: unsupported primary expression type" << std::endl; throw std::runtime_error(FormatError("irgen", "不支持的基本表达式类型")); } // 左值(变量)处理 std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) { std::cerr << "[DEBUG IRGEN] visitLVal: 开始处理左值 " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx || !ctx->Ident()) { throw std::runtime_error(FormatError("irgen", "非法左值")); } std::string varName = ctx->Ident()->getText(); std::cerr << "[DEBUG] visitLVal: " << varName << std::endl; // 先检查语义分析中常量绑定 const SysYParser::ConstDefContext* const_decl = sema_.ResolveConstUse(ctx); const Symbol* sym = nullptr; if (const_decl) { sym = symbol_table_.lookupByConstDef(const_decl); if (!sym) { sym = symbol_table_.lookupAll(varName); } } else { sym = symbol_table_.lookup(varName); } // 如果是常量,直接返回常量值 if (sym && sym->kind == SymbolKind::Constant) { std::cerr << "[DEBUG] visitLVal: 找到常量 " << varName << std::endl; if (sym->IsScalarConstant()) { if (sym->type->IsInt32()) { ir::ConstantValue* const_val = builder_.CreateConstInt(sym->GetIntConstant()); return static_cast(const_val); } else if (sym->type->IsFloat()) { ir::ConstantValue* const_val = builder_.CreateConstFloat(sym->GetFloatConstant()); return static_cast(const_val); } } else if (sym->IsArrayConstant()) { auto it = const_global_map_.find(varName); if (it != const_global_map_.end()) { ir::GlobalValue* global_array = it->second; // 尝试获取类型信息,用于维度判断与下标线性化 auto* array_ty = dynamic_cast(sym->type.get()); if (!array_ty) { // 无法获取数组类型,退回返回全局对象 return static_cast(global_array); } size_t ndims = array_ty->GetDimensions().size(); // 有下标访问 if (!ctx->exp().empty()) { size_t provided = ctx->exp().size(); // 完全索引(所有维度都有下标)——直接返回常量元素,不生成 Load if (provided == ndims) { std::vector idxs; idxs.reserve(provided); for (auto* exp : ctx->exp()) { ir::Value* v = EvalExpr(*exp); if (!v || !v->IsConstant()) { throw std::runtime_error(FormatError("irgen", "常量数组索引必须为常量整数: " + varName)); } auto* ci = dynamic_cast(v); if (!ci) { throw std::runtime_error(FormatError("irgen", "常量数组索引非整型常量: " + varName)); } idxs.push_back(ci->GetValue()); } // 计算线性下标(行主序) const auto& dims = array_ty->GetDimensions(); int flat = idxs[0]; for (size_t i = 1; i < ndims; ++i) { flat = flat * dims[i] + idxs[i]; } ir::ConstantValue* elem = global_array->GetArrayElement(static_cast(flat)); return static_cast(elem); } // 部分索引:返回指针(不做 Load),由上层按需处理 std::vector indices; indices.push_back(builder_.CreateConstInt(0)); for (auto* exp : ctx->exp()) { indices.push_back(EvalExpr(*exp)); } return static_cast( builder_.CreateGEP(global_array, indices, module_.GetContext().NextTemp())); } else { // 无下标,直接返回全局常量对象 return static_cast(global_array); } } } } // 不是常量,按正常变量处理 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) { auto it4 = local_var_map_.find(varName); if (it4 != local_var_map_.end()) { ptr = it4->second; } } if (!ptr) { throw std::runtime_error( FormatError("irgen", "变量声明缺少存储槽位: " + varName)); } // 检查是否有数组下标 bool is_array_access = !ctx->exp().empty(); if (is_array_access) { // 收集下标表达式(不含前导0) std::vector idx_vals; for (auto* exp : ctx->exp()) { ir::Value* index = EvalExpr(*exp); idx_vals.push_back(index); } const Symbol* var_sym = sym; if (!var_sym) { var_sym = symbol_table_.lookup(varName); } if (!var_sym && decl) { var_sym = symbol_table_.lookupByVarDef(decl); } if (!var_sym) { var_sym = symbol_table_.lookupAll(varName); } std::vector dims; if (var_sym) { if (var_sym->is_array_param && !var_sym->array_dims.empty()) { dims = var_sym->array_dims; } else if (var_sym->type && var_sym->type->IsArray()) { auto* at = dynamic_cast(var_sym->type.get()); if (at) dims = at->GetDimensions(); } } if (dims.empty() && ptr->GetType()->IsArray()) { if (auto* at = dynamic_cast(ptr->GetType().get())) { dims = at->GetDimensions(); } } // 兜底:从语法树声明提取维度,避免作用域关闭后符号查询不完整。 if (dims.empty() && const_decl) { auto* mutable_const_decl = const_cast(const_decl); for (auto* cexp : mutable_const_decl->constExp()) { dims.push_back(symbol_table_.EvaluateConstExp(cexp)); } } if (dims.empty() && decl) { for (auto* cexp : decl->constExp()) { dims.push_back(symbol_table_.EvaluateConstExp(cexp)); } } const bool is_partial_array_access = !dims.empty() && idx_vals.size() < dims.size(); // 如果 base 是标量指针(例如局部扁平数组或数组参数), // 需要把多维下标折合为单一线性下标,然后用一个索引进行 GEP。 if (ptr->GetType()->IsPtrInt32() || ptr->GetType()->IsPtrFloat()) { // 如果没有维度信息,仍尝试用运行时算术合并下标(按后维乘积) // flat = idx0 * (prod dims[1..]) + idx1 * (prod dims[2..]) + ... ir::Value* flat = nullptr; for (size_t i = 0; i < idx_vals.size(); ++i) { ir::Value* term = idx_vals[i]; if (!term) continue; // 计算乘数(后续维度乘积) int mult = 1; if (!dims.empty() && i + 1 < dims.size()) { for (size_t j = i + 1; j < dims.size(); ++j) { // 数组参数首维可能是 0(表示省略),不参与乘数。 if (dims[j] > 0) mult *= dims[j]; } } if (mult != 1) { auto* mval = builder_.CreateConstInt(mult); term = builder_.CreateMul(term, mval, module_.GetContext().NextTemp()); } if (!flat) flat = term; else flat = builder_.CreateAdd(flat, term, module_.GetContext().NextTemp()); } if (!flat) flat = builder_.CreateConstInt(0); // 使用单一索引创建 GEP std::vector gep_indices = { flat }; ir::Value* elem_ptr = builder_.CreateGEP(ptr, gep_indices, module_.GetContext().NextTemp()); if (is_partial_array_access) { return elem_ptr; } return static_cast(builder_.CreateLoad(elem_ptr, module_.GetContext().NextTemp())); } std::vector indices; // 标量指针(T*)使用单索引;数组对象使用前导0进入首层。 if (ptr->GetType()->IsPtrInt32() || ptr->GetType()->IsPtrFloat()) { for (auto* v : idx_vals) indices.push_back(v); } else { indices.push_back(builder_.CreateConstInt(0)); for (auto* v : idx_vals) indices.push_back(v); } ir::Value* elem_ptr = builder_.CreateGEP(ptr, indices, module_.GetContext().NextTemp()); if (is_partial_array_access) { return elem_ptr; } return static_cast(builder_.CreateLoad(elem_ptr, module_.GetContext().NextTemp())); } else { if ((sym && sym->is_array_param) || pointer_param_names_.find(varName) != pointer_param_names_.end() || heap_local_array_names_.find(varName) != heap_local_array_names_.end()) { return ptr; } if (ptr->GetType()->IsArray()) { return ptr; } return static_cast(builder_.CreateLoad(ptr, module_.GetContext().NextTemp())); } } std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) { std::cerr << "[DEBUG IRGEN] visitAddExp: 开始处理加法表达式 " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx) { throw std::runtime_error(FormatError("irgen", "非法加法表达式")); } // 如果没有 addExp(),说明是单个 mulExp() if (!ctx->addExp()) { return ctx->mulExp()->accept(this); } // 正确提取左操作数 auto left_any = ctx->addExp()->accept(this); if (!left_any.has_value()) { throw std::runtime_error(FormatError("irgen", "左操作数求值失败")); } ir::Value* left = std::any_cast(left_any); // 正确提取右操作数 auto right_any = ctx->mulExp()->accept(this); if (!right_any.has_value()) { throw std::runtime_error(FormatError("irgen", "右操作数求值失败")); } ir::Value* right = std::any_cast(right_any); std::cerr << "[DEBUG] visitAddExp: left=" << (void*)left << ", type=" << (left->GetType()->IsFloat() ? "float" : "int") << ", right=" << (void*)right << ", type=" << (right->GetType()->IsFloat() ? "float" : "int") << std::endl; // 处理类型转换:如果操作数类型不同,需要进行类型转换 if (left->GetType()->IsFloat() != right->GetType()->IsFloat()) { if (left->GetType()->IsFloat()) { // left是float,right是int,需要将right转换为float right = builder_.CreateSIToFP(right, ir::Type::GetFloatType()); } else { // right是float,left是int,需要将left转换为float left = builder_.CreateSIToFP(left, ir::Type::GetFloatType()); } } // 根据操作符生成相应的指令 if (ctx->AddOp()) { if (left->GetType()->IsFloat()) { return static_cast( builder_.CreateFAdd(left, right, module_.GetContext().NextTemp())); } else { return static_cast( builder_.CreateAdd(left, right, module_.GetContext().NextTemp())); } } else if (ctx->SubOp()) { if (left->GetType()->IsFloat()) { return static_cast( builder_.CreateFSub(left, right, module_.GetContext().NextTemp())); } else { return static_cast( builder_.CreateSub(left, right, module_.GetContext().NextTemp())); } } throw std::runtime_error(FormatError("irgen", "未知的加法操作符")); } std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) { std::cerr << "[DEBUG IRGEN] visitMulExp: 开始处理乘法表达式 " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx) { throw std::runtime_error(FormatError("irgen", "非法乘法表达式")); } // 如果是基本形式 UnaryExp if (!ctx->mulExp()) { return ctx->unaryExp()->accept(this); } // 提取左操作数 auto left_any = ctx->mulExp()->accept(this); if (!left_any.has_value()) { throw std::runtime_error(FormatError("irgen", "左操作数求值失败")); } ir::Value* left = std::any_cast(left_any); // 提取右操作数 auto right_any = ctx->unaryExp()->accept(this); if (!right_any.has_value()) { throw std::runtime_error(FormatError("irgen", "右操作数求值失败")); } ir::Value* right = std::any_cast(right_any); std::cerr << "[DEBUG] visitMulExp: left=" << (void*)left << ", type=" << (left->GetType()->IsFloat() ? "float" : "int") << ", right=" << (void*)right << ", type=" << (right->GetType()->IsFloat() ? "float" : "int") << std::endl; // 处理类型转换:如果操作数类型不同,需要进行类型转换 if (left->GetType()->IsFloat() != right->GetType()->IsFloat()) { if (left->GetType()->IsFloat()) { // left是float,right是int,需要将right转换为float right = builder_.CreateSIToFP(right, ir::Type::GetFloatType()); } else { // right是float,left是int,需要将left转换为float left = builder_.CreateSIToFP(left, ir::Type::GetFloatType()); } } // 根据操作符生成指令 if (ctx->MulOp()) { if (left->GetType()->IsFloat()) { return static_cast( builder_.CreateFMul(left, right, module_.GetContext().NextTemp())); } else { return static_cast( builder_.CreateMul(left, right, module_.GetContext().NextTemp())); } } else if (ctx->DivOp()) { if (left->GetType()->IsFloat()) { return static_cast( builder_.CreateFDiv(left, right, module_.GetContext().NextTemp())); } else { return static_cast( builder_.CreateDiv(left, right, module_.GetContext().NextTemp())); } } else if (ctx->QuoOp()) { // 取模运算:浮点数不支持取模,只支持整数 if (left->GetType()->IsFloat() || right->GetType()->IsFloat()) { throw std::runtime_error( FormatError("irgen", "浮点数不支持取模运算")); } return static_cast( builder_.CreateMod(left, right, module_.GetContext().NextTemp())); } throw std::runtime_error(FormatError("irgen", "未知的乘法操作符")); } // 逻辑与 std::any IRGenImpl::visitLAndExp(SysYParser::LAndExpContext* ctx) { std::cerr << "[DEBUG IRGEN] visitLAndExp: 开始处理逻辑与表达式 " << (ctx ? ctx->getText() : "") << std::endl; 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 to_bool = [&](ir::Value* v) -> ir::Value* { if (v->GetType()->IsInt1()) { return v; } if (v->GetType()->IsFloat()) { return builder_.CreateFCmpONE(v, builder_.CreateConstFloat(0.0f), module_.GetContext().NextTemp()); } return builder_.CreateICmpNE(v, builder_.CreateConstInt(0), module_.GetContext().NextTemp()); }; auto* left_bool = to_bool(left); auto* right_bool = to_bool(right); return static_cast( builder_.CreateAnd(left_bool, right_bool, module_.GetContext().NextTemp())); } // 逻辑或 std::any IRGenImpl::visitLOrExp(SysYParser::LOrExpContext* ctx) { std::cerr << "[DEBUG IRGEN] visitLOrExp: 开始处理逻辑或表达式 " << (ctx ? ctx->getText() : "") << std::endl; 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 to_bool = [&](ir::Value* v) -> ir::Value* { if (v->GetType()->IsInt1()) { return v; } if (v->GetType()->IsFloat()) { return builder_.CreateFCmpONE(v, builder_.CreateConstFloat(0.0f), module_.GetContext().NextTemp()); } return builder_.CreateICmpNE(v, builder_.CreateConstInt(0), module_.GetContext().NextTemp()); }; auto* left_bool = to_bool(left); auto* right_bool = to_bool(right); return static_cast( builder_.CreateOr(left_bool, right_bool, module_.GetContext().NextTemp())); } std::any IRGenImpl::visitExp(SysYParser::ExpContext* ctx) { std::cerr << "[DEBUG IRGEN] visitExp: 开始处理表达式 " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx) throw std::runtime_error(FormatError("irgen", "非法表达式")); return ctx->addExp()->accept(this); } std::any IRGenImpl::visitCond(SysYParser::CondContext* ctx) { std::cerr << "[DEBUG IRGEN] visitCond: 开始处理条件 " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx) throw std::runtime_error(FormatError("irgen", "非法条件表达式")); return ctx->lOrExp()->accept(this); } std::any IRGenImpl::visitCallExp(SysYParser::UnaryExpContext* ctx) { std::cerr << "[DEBUG IRGEN] visitCallExp: 开始处理函数调用 " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx || !ctx->Ident()) { throw std::runtime_error(FormatError("irgen", "非法函数调用")); } std::string funcName = ctx->Ident()->getText(); std::cout << "[DEBUG IRGEN] visitCallExp: 调用函数 " << funcName << std::endl; // 查找函数对象 ir::Function* callee = module_.FindFunction(funcName); // 如果没找到,可能是运行时函数还没声明,尝试动态声明 if (!callee) { std::cout << "[DEBUG IRGEN] 函数 " << funcName << " 未找到,尝试动态声明" << std::endl; // 根据函数名动态创建运行时函数声明 callee = CreateRuntimeFunctionDecl(funcName); if (!callee) { throw std::runtime_error(FormatError("irgen", "未找到函数: " + funcName)); } } // 收集实参 std::vector args; if (ctx->funcRParams()) { auto argList = ctx->funcRParams()->accept(this); try { args = std::any_cast>(argList); std::cout << "[DEBUG IRGEN] visitCallExp: 收集到 " << args.size() << " 个参数" << std::endl; } catch (const std::bad_any_cast& e) { std::cerr << "[ERROR] visitCallExp: 函数调用参数类型错误: " << e.what() << std::endl; } } // 按形参类型修正实参(数组衰减为指针等)。 if (auto* fty = dynamic_cast(callee->GetType().get())) { const auto& param_tys = fty->GetParamTypes(); size_t n = std::min(param_tys.size(), args.size()); for (size_t i = 0; i < n; ++i) { if (!args[i] || !param_tys[i]) continue; // 数组实参传给指针形参时,执行数组到指针衰减。 if (args[i]->GetType()->IsArray() && (param_tys[i]->IsPtrInt32() || param_tys[i]->IsPtrFloat())) { std::vector idx; idx.push_back(builder_.CreateConstInt(0)); idx.push_back(builder_.CreateConstInt(0)); args[i] = builder_.CreateGEP(args[i], idx, module_.GetContext().NextTemp()); } // 标量实参的隐式类型转换(int <-> float)。 if (param_tys[i]->IsFloat() && args[i]->GetType()->IsInt32()) { args[i] = builder_.CreateSIToFP(args[i], ir::Type::GetFloatType(), module_.GetContext().NextTemp()); } else if (param_tys[i]->IsInt32() && args[i]->GetType()->IsFloat()) { args[i] = builder_.CreateFPToSI(args[i], ir::Type::GetInt32Type(), module_.GetContext().NextTemp()); } } } // 生成调用指令 ir::Value* callResult = builder_.CreateCall(callee, args, module_.GetContext().NextTemp()); // 如果函数返回 void,返回一个默认值(用于表达式上下文) if (callResult->GetType()->IsVoid()) { // void 函数调用不产生值,但我们返回一个 0 常量以保持类型一致性 return static_cast(builder_.CreateConstInt(0)); } std::cout << "[DEBUG IRGEN] visitCallExp: 函数调用完成,返回值 " << (void*)callResult << std::endl; return static_cast(callResult); } // 动态创建运行时函数声明的辅助函数 ir::Function* IRGenImpl::CreateRuntimeFunctionDecl(const std::string& funcName) { std::cerr << "[DEBUG IRGEN] CreateRuntimeFunctionDecl: 开始创建运行时函数声明 " << funcName << std::endl; // 根据常见运行时函数名创建对应的函数类型 if (funcName == "getint" || funcName == "getch") { return module_.CreateFunction(funcName, ir::Type::GetFunctionType(ir::Type::GetInt32Type(), {})); } else if (funcName == "putint" || funcName == "putch") { return module_.CreateFunction(funcName, ir::Type::GetFunctionType( ir::Type::GetVoidType(), {ir::Type::GetInt32Type()})); } else if (funcName == "getarray") { return module_.CreateFunction(funcName, ir::Type::GetFunctionType( ir::Type::GetInt32Type(), {ir::Type::GetPtrInt32Type()})); } else if (funcName == "putarray") { return module_.CreateFunction(funcName, ir::Type::GetFunctionType( ir::Type::GetVoidType(), {ir::Type::GetInt32Type(), ir::Type::GetPtrInt32Type()})); } else if (funcName == "puts") { return module_.CreateFunction(funcName, ir::Type::GetFunctionType( ir::Type::GetVoidType(), {ir::Type::GetPtrInt32Type()})); } else if (funcName == "starttime" || funcName == "stoptime") { return module_.CreateFunction(funcName, ir::Type::GetFunctionType(ir::Type::GetVoidType(), {})); } else if (funcName == "_sysy_starttime" || funcName == "_sysy_stoptime") { return module_.CreateFunction(funcName, ir::Type::GetFunctionType( ir::Type::GetVoidType(), {ir::Type::GetInt32Type()})); } else if (funcName == "getfloat") { return module_.CreateFunction(funcName, ir::Type::GetFunctionType(ir::Type::GetFloatType(), {})); } else if (funcName == "putfloat") { return module_.CreateFunction(funcName, ir::Type::GetFunctionType( ir::Type::GetVoidType(), {ir::Type::GetFloatType()})); } else if (funcName == "getfarray") { return module_.CreateFunction(funcName, ir::Type::GetFunctionType( ir::Type::GetInt32Type(), {ir::Type::GetPtrFloatType()})); } else if (funcName == "putfarray") { return module_.CreateFunction(funcName, ir::Type::GetFunctionType( ir::Type::GetVoidType(), {ir::Type::GetInt32Type(), ir::Type::GetPtrFloatType()})); } else if (funcName == "memset") { return module_.CreateFunction(funcName, ir::Type::GetFunctionType( ir::Type::GetPtrInt32Type(), {ir::Type::GetPtrInt32Type(), ir::Type::GetInt32Type(), ir::Type::GetInt32Type()})); } else if (funcName == "sysy_alloc_i32") { return module_.CreateFunction(funcName, ir::Type::GetFunctionType( ir::Type::GetPtrInt32Type(), {ir::Type::GetInt32Type()})); } else if (funcName == "sysy_alloc_f32") { return module_.CreateFunction(funcName, ir::Type::GetFunctionType( ir::Type::GetPtrFloatType(), {ir::Type::GetInt32Type()})); } else if (funcName == "sysy_free_i32") { return module_.CreateFunction(funcName, ir::Type::GetFunctionType( ir::Type::GetVoidType(), {ir::Type::GetPtrInt32Type()})); } else if (funcName == "sysy_free_f32") { return module_.CreateFunction(funcName, ir::Type::GetFunctionType( ir::Type::GetVoidType(), {ir::Type::GetPtrFloatType()})); } else if (funcName == "sysy_zero_i32") { return module_.CreateFunction(funcName, ir::Type::GetFunctionType( ir::Type::GetVoidType(), {ir::Type::GetPtrInt32Type(), ir::Type::GetInt32Type()})); } else if (funcName == "sysy_zero_f32") { return module_.CreateFunction(funcName, ir::Type::GetFunctionType( ir::Type::GetVoidType(), {ir::Type::GetPtrFloatType(), ir::Type::GetInt32Type()})); } // 其他函数不支持动态创建 return nullptr; } std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) { std::cerr << "[DEBUG IRGEN] visitUnaryExp: 开始处理一元表达式 " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx) { throw std::runtime_error(FormatError("irgen", "非法一元表达式")); } // 基本表达式 if (ctx->primaryExp()) { return ctx->primaryExp()->accept(this); } // 函数调用 if (ctx->Ident()) { return visitCallExp(ctx); } // 一元运算 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 根据操作数类型选择整数或浮点减法 if (operand->GetType()->IsFloat()) { // 浮点取负:0.0 - x ir::Value* zero_float = builder_.CreateConstFloat(0.0f); return static_cast( builder_.CreateFSub(zero_float, operand, module_.GetContext().NextTemp())); } else { // 整数取负:0 - x ir::Value* zero = builder_.CreateConstInt(0); return static_cast( builder_.CreateSub(zero, operand, module_.GetContext().NextTemp())); } } else if (op == "!") { // 逻辑非运算 // 先将值转换为bool(与0比较) ir::Value* zero; if (operand->GetType()->IsFloat()) { zero = builder_.CreateConstFloat(0.0f); // 浮点逻辑非:x == 0.0 ir::Value* cmp = builder_.CreateFCmpOEQ(operand, zero, module_.GetContext().NextTemp()); // 将bool转换为int return static_cast( builder_.CreateZExt(cmp, ir::Type::GetInt32Type())); } else { zero = builder_.CreateConstInt(0); return static_cast( builder_.CreateNot(operand, module_.GetContext().NextTemp())); } } } throw std::runtime_error(FormatError("irgen", "暂不支持的一元表达式形式")); } // 实现函数调用 std::any IRGenImpl::visitFuncRParams(SysYParser::FuncRParamsContext* ctx) { std::cerr << "[DEBUG IRGEN] visitFuncRParams: 开始处理函数参数 " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx) return std::vector{}; std::vector args; for (auto* exp : ctx->exp()) { args.push_back(EvalExpr(*exp)); } return args; } // visitConstExp - 处理常量表达式 std::any IRGenImpl::visitConstExp(SysYParser::ConstExpContext* ctx) { std::cerr << "[DEBUG IRGEN] visitConstExp: 开始处理常量表达式 " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx || !ctx->addExp()) { throw std::runtime_error(FormatError("irgen", "非法常量表达式")); } auto result = ctx->addExp()->accept(this); if (!result.has_value()) { throw std::runtime_error(FormatError("irgen", "常量表达式求值失败")); } try { return std::any_cast(result); } catch (const std::bad_any_cast& e) { throw std::runtime_error(FormatError("irgen", "常量表达式返回类型错误: " + std::string(e.what()))); } } // visitConstInitVal - 处理常量初始化值 std::any IRGenImpl::visitConstInitVal(SysYParser::ConstInitValContext* ctx) { std::cerr << "[DEBUG IRGEN] visitConstInitVal: 开始处理常量初始化值 " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx) { throw std::runtime_error(FormatError("irgen", "非法常量初始化值")); } // 如果是单个常量表达式 if (ctx->constExp()) { return ctx->constExp()->accept(this); } // 如果是聚合初始化(花括号列表) else if (!ctx->constInitVal().empty()) { std::vector all_values; for (auto* init_val : ctx->constInitVal()) { auto result = init_val->accept(this); if (!result.has_value()) { throw std::runtime_error(FormatError("irgen", "常量初始化值求值失败")); } try { // 尝试获取单个常量值 ir::Value* value = std::any_cast(result); all_values.push_back(value); } catch (const std::bad_any_cast&) { try { // 尝试获取值列表(嵌套情况) std::vector nested_values = std::any_cast>(result); all_values.insert(all_values.end(), nested_values.begin(), nested_values.end()); } catch (const std::bad_any_cast& e) { throw std::runtime_error(FormatError("irgen", "不支持的常量初始化值类型: " + std::string(e.what()))); } } } return all_values; } // 空初始化列表 return std::vector{}; } std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) { std::cerr << "[DEBUG IRGEN] visitRelExp: 开始处理关系表达式 " << (ctx ? ctx->getText() : "") << std::endl; 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); std::cerr << "[DEBUG] visitRelExp: left=" << (void*)lhs << ", type=" << (lhs->GetType()->IsFloat() ? "float" : "int") << ", right=" << (void*)rhs << ", type=" << (rhs->GetType()->IsFloat() ? "float" : "int") << std::endl; // 处理类型转换:如果操作数类型不同,需要进行类型转换 if (lhs->GetType()->IsFloat() != rhs->GetType()->IsFloat()) { if (lhs->GetType()->IsFloat()) { // lhs是float,rhs是int,需要将rhs转换为float rhs = builder_.CreateSIToFP(rhs, ir::Type::GetFloatType()); } else { // rhs是float,lhs是int,需要将lhs转换为float lhs = builder_.CreateSIToFP(lhs, ir::Type::GetFloatType()); } } // 根据操作数和类型选择指令 if (ctx->LOp()) { if (lhs->GetType()->IsFloat()) { return static_cast( builder_.CreateFCmpOLT(lhs, rhs, module_.GetContext().NextTemp())); } else { return static_cast( builder_.CreateICmpLT(lhs, rhs, module_.GetContext().NextTemp())); } } if (ctx->GOp()) { if (lhs->GetType()->IsFloat()) { return static_cast( builder_.CreateFCmpOGT(lhs, rhs, module_.GetContext().NextTemp())); } else { return static_cast( builder_.CreateICmpGT(lhs, rhs, module_.GetContext().NextTemp())); } } if (ctx->LeOp()) { if (lhs->GetType()->IsFloat()) { return static_cast( builder_.CreateFCmpOLE(lhs, rhs, module_.GetContext().NextTemp())); } else { return static_cast( builder_.CreateICmpLE(lhs, rhs, module_.GetContext().NextTemp())); } } if (ctx->GeOp()) { if (lhs->GetType()->IsFloat()) { return static_cast( builder_.CreateFCmpOGE(lhs, rhs, module_.GetContext().NextTemp())); } else { 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) { std::cerr << "[DEBUG IRGEN] visitEqExp: 开始处理相等表达式 " << (ctx ? ctx->getText() : "") << std::endl; 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); std::cerr << "[DEBUG] visitEqExp: left=" << (void*)lhs << ", type=" << (lhs->GetType()->IsFloat() ? "float" : "int") << ", right=" << (void*)rhs << ", type=" << (rhs->GetType()->IsFloat() ? "float" : "int") << std::endl; // 处理类型转换:如果操作数类型不同,需要进行类型转换 if (lhs->GetType()->IsFloat() != rhs->GetType()->IsFloat()) { if (lhs->GetType()->IsFloat()) { // lhs是float,rhs是int,需要将rhs转换为float rhs = builder_.CreateSIToFP(rhs, ir::Type::GetFloatType()); } else { // rhs是float,lhs是int,需要将lhs转换为float lhs = builder_.CreateSIToFP(lhs, ir::Type::GetFloatType()); } } // 根据操作符和类型选择指令 if (ctx->EqOp()) { if (lhs->GetType()->IsFloat()) { return static_cast( builder_.CreateFCmpOEQ(lhs, rhs, module_.GetContext().NextTemp())); } else { return static_cast( builder_.CreateICmpEQ(lhs, rhs, module_.GetContext().NextTemp())); } } if (ctx->NeOp()) { if (lhs->GetType()->IsFloat()) { return static_cast( builder_.CreateFCmpONE(lhs, rhs, module_.GetContext().NextTemp())); } else { 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", "相等表达式暂未实现")); } ir::Value* IRGenImpl::EvalAssign(SysYParser::StmtContext* ctx) { std::cerr << "[DEBUG IRGEN] EvalAssign: 开始处理赋值语句 " << (ctx ? ctx->getText() : "") << std::endl; std::cout << "[DEBUG IRGEN] visitCond: " << (ctx ? ctx->getText() : "") << std::endl; if (!ctx || !ctx->lVal() || !ctx->exp()) { throw std::runtime_error(FormatError("irgen", "非法赋值语句")); } // 计算右值 ir::Value* rhs = EvalExpr(*ctx->exp()); auto* lval = ctx->lVal(); std::string varName = lval->Ident()->getText(); // 首先尝试从语义分析获取变量定义 auto* var_decl = sema_.ResolveVarUse(lval); if (var_decl) { // 是变量赋值 // 从storage_map_获取存储位置 auto it = storage_map_.find(var_decl); if (it == storage_map_.end()) { throw std::runtime_error( FormatError("irgen", "变量声明缺少存储槽位: " + varName)); } ir::Value* base_ptr = it->second; auto convert_for_store = [&](ir::Value* value, ir::Value* ptr) -> ir::Value* { if (ptr->GetType()->IsPtrFloat() && value->GetType()->IsInt32()) { return builder_.CreateSIToFP(value, ir::Type::GetFloatType(), module_.GetContext().NextTemp()); } if (ptr->GetType()->IsPtrInt32() && value->GetType()->IsFloat()) { return builder_.CreateFPToSI(value, ir::Type::GetInt32Type(), module_.GetContext().NextTemp()); } return value; }; // 检查是否有数组下标 auto exp_list = lval->exp(); if (!exp_list.empty()) { // 这是数组元素赋值,需要生成GEP指令 std::vector indices; // 标量指针参数(T*)不应添加前导0;数组对象需要前导0。 if (!(base_ptr->GetType()->IsPtrInt32() || base_ptr->GetType()->IsPtrFloat())) { indices.push_back(builder_.CreateConstInt(0)); } // 添加用户提供的下标 for (auto* exp : exp_list) { ir::Value* index = EvalExpr(*exp); indices.push_back(index); } // 生成GEP指令获取元素地址 ir::Value* elem_ptr = builder_.CreateGEP( base_ptr, indices, module_.GetContext().NextTemp()); // 生成store指令 rhs = convert_for_store(rhs, elem_ptr); builder_.CreateStore(rhs, elem_ptr); } else { // 普通标量赋值 // 调试输出指针类型 std::cerr << "[DEBUG] base_ptr type: " << base_ptr->GetType() << std::endl; std::cerr << "[DEBUG] rhs type: " << rhs->GetType()<< std::endl; // 如果 base_ptr 不是标量指针类型,可能需要特殊处理 if (!base_ptr->GetType()->IsPtrInt32() && !base_ptr->GetType()->IsPtrFloat()) { std::cerr << "[ERROR] base_ptr is not a pointer type!" << std::endl; throw std::runtime_error("尝试存储到非指针类型"); } rhs = convert_for_store(rhs, base_ptr); builder_.CreateStore(rhs, base_ptr); } } else { // 尝试获取常量定义 auto* const_decl = sema_.ResolveConstUse(lval); if (const_decl) { // 尝试给常量赋值,这是错误的 throw std::runtime_error( FormatError("irgen", "不能给常量赋值: " + varName)); } else { throw std::runtime_error( FormatError("irgen", "变量/常量使用缺少语义绑定: " + varName)); } } return rhs; }