浮点实现,常量存在问题以及存储

feature/sem
potapo 2 weeks ago
parent d9201de428
commit c8f40ea09a

@ -320,6 +320,12 @@ enum class Opcode {
Div, Mod,
And, Or, Not,
GEP,
FAdd, FSub, FMul, FDiv,
FCmp,
SIToFP, // 整数转浮点
FPToSI, // 浮点转整数
FPExt, // 浮点扩展
FPTrunc, // 浮点截断
};
// ZExt 和 Trunc 是零扩展和截断指令,SysY 的 int (i32) vs LLVM IR 的比较结果 (i1)。
@ -569,6 +575,42 @@ class BranchInst : public Instruction {
Predicate pred_;
};
class FcmpInst : public Instruction {
public:
enum class Predicate {
FALSE, // Always false
OEQ, // Ordered and equal
OGT, // Ordered and greater than
OGE, // Ordered and greater than or equal
OLT, // Ordered and less than
OLE, // Ordered and less than or equal
ONE, // Ordered and not equal
ORD, // Ordered (no nans)
UNO, // Unordered (isnan(x) || isnan(y))
UEQ, // Unordered or equal
UGT, // Unordered or greater than
UGE, // Unordered or greater than or equal
ULT, // Unordered or less than
ULE, // Unordered or less than or equal
UNE, // Unordered or not equal
TRUE // Always true
};
FcmpInst(Predicate pred, Value* lhs, Value* rhs,
std::shared_ptr<Type> i1_ty, std::string name)
: Instruction(Opcode::FCmp, i1_ty, name), pred_(pred) {
AddOperand(lhs);
AddOperand(rhs);
}
Predicate GetPredicate() const { return pred_; }
Value* GetLhs() const { return GetOperand(0); }
Value* GetRhs() const { return GetOperand(1); }
private:
Predicate pred_;
};
// ZExtInst - 零扩展指令
class ZExtInst : public Instruction {
public:
@ -728,6 +770,32 @@ class Module {
std::vector<std::unique_ptr<GlobalValue>> globals_;
};
// SIToFP - 整数转浮点
class SIToFPInst : public Instruction {
public:
SIToFPInst(Value* value, std::shared_ptr<Type> target_ty, std::string name = "")
: Instruction(Opcode::SIToFP, target_ty, name) {
AddOperand(value);
}
Value* GetValue() const {
return GetOperand(0);
}
};
// FPToSI - 浮点转整数
class FPToSIInst : public Instruction {
public:
FPToSIInst(Value* value, std::shared_ptr<Type> target_ty, std::string name = "")
: Instruction(Opcode::FPToSI, target_ty, name) {
AddOperand(value);
}
Value* GetValue() const {
return GetOperand(0);
}
};
class IRBuilder {
public:
IRBuilder(Context& ctx, BasicBlock* bb);
@ -791,6 +859,25 @@ class IRBuilder {
GEPInst* CreateGEP(Value* base, const std::vector<Value*>& indices, const std::string& name);
// 浮点运算
BinaryInst* CreateFAdd(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateFSub(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateFMul(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateFDiv(Value* lhs, Value* rhs, const std::string& name);
// 浮点比较
FcmpInst* CreateFCmpOEQ(Value* lhs, Value* rhs, const std::string& name);
FcmpInst* CreateFCmpONE(Value* lhs, Value* rhs, const std::string& name);
FcmpInst* CreateFCmpOLT(Value* lhs, Value* rhs, const std::string& name);
FcmpInst* CreateFCmpOLE(Value* lhs, Value* rhs, const std::string& name);
FcmpInst* CreateFCmpOGT(Value* lhs, Value* rhs, const std::string& name);
FcmpInst* CreateFCmpOGE(Value* lhs, Value* rhs, const std::string& name);
// 类型转换
SIToFPInst* CreateSIToFP(Value* value, std::shared_ptr<Type> target_ty,
const std::string& name = "");
FPToSIInst* CreateFPToSI(Value* value, std::shared_ptr<Type> target_ty,
const std::string& name = "");
private:
Context& ctx_;
BasicBlock* insert_block_;

File diff suppressed because it is too large Load Diff

@ -5,7 +5,7 @@
#include "ir/IR.h"
#include <stdexcept>
#include <cstring>
#include "utils/Log.h"
namespace ir {
@ -59,6 +59,11 @@ BinaryInst* IRBuilder::CreateBinary(Opcode op, Value* lhs, Value* rhs,
case Opcode::Mod:
case Opcode::And:
case Opcode::Or:
// 添加浮点操作码
case Opcode::FAdd:
case Opcode::FSub:
case Opcode::FMul:
case Opcode::FDiv:
// 有效的二元操作符
break;
case Opcode::Not:
@ -77,21 +82,33 @@ BinaryInst* IRBuilder::CreateBinary(Opcode op, Value* lhs, Value* rhs,
FormatError("ir", "CreateBinary 操作数类型不匹配"));
}
// 检查是否为浮点操作
bool is_float_op = (op == Opcode::FAdd || op == Opcode::FSub ||
op == Opcode::FMul || op == Opcode::FDiv);
bool is_logical = (op == Opcode::And || op == Opcode::Or);
if (is_logical) {
// 逻辑运算的结果是 int32布尔值
result_type = Type::GetInt32Type();
} else {
// 算术运算的结果类型与操作数相同
if (is_float_op) {
// 浮点操作要求操作数是浮点类型
if (!lhs->GetType()->IsFloat()) {
throw std::runtime_error(
FormatError("ir", "浮点运算要求操作数为浮点类型"));
}
result_type = lhs->GetType();
}
// 检查操作数类型是否支持
if (!lhs->GetType()->IsInt32() && !lhs->GetType()->IsFloat()) {
throw std::runtime_error(
FormatError("ir", "CreateBinary 只支持 int32 和 float 类型"));
} else {
bool is_logical = (op == Opcode::And || op == Opcode::Or);
if (is_logical) {
// 逻辑运算的结果是 int32布尔值
result_type = Type::GetInt32Type();
} else {
// 算术运算的结果类型与操作数相同
result_type = lhs->GetType();
}
// 检查操作数类型是否支持
if (!lhs->GetType()->IsInt32() && !lhs->GetType()->IsFloat()) {
throw std::runtime_error(
FormatError("ir", "CreateBinary 只支持 int32 和 float 类型"));
}
}
return insert_block_->Append<BinaryInst>(op, result_type, lhs, rhs, name);
@ -126,16 +143,30 @@ LoadInst* IRBuilder::CreateLoad(Value* ptr, const std::string& name) {
}
auto ptr_ty = ptr->GetType();
std::shared_ptr<Type> elem_ty;
if (ptr_ty->IsPtrInt32()) {
elem_ty = Type::GetInt32Type();
} else if (ptr_ty->IsPtrFloat()) {
elem_ty = Type::GetFloatType();
} else if (ptr_ty->IsPtrInt1()) {
elem_ty = Type::GetInt1Type();
} else if (ptr_ty->IsArray()) {
// 数组类型的指针,元素类型是数组元素类型
auto* array_ty = dynamic_cast<ArrayType*>(ptr_ty.get());
if (array_ty) {
elem_ty = array_ty->GetElementType();
} else {
throw std::runtime_error(FormatError("ir", "不支持的指针类型"));
}
} else {
// 尝试其他指针类型
throw std::runtime_error(FormatError("ir", "不支持的指针类型"));
}
return insert_block_->Append<LoadInst>(elem_ty, ptr, name);
}
StoreInst* IRBuilder::CreateStore(Value* val, Value* ptr) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
@ -148,6 +179,32 @@ StoreInst* IRBuilder::CreateStore(Value* val, Value* ptr) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateStore 缺少 ptr"));
}
// 检查类型兼容性
auto ptr_ty = ptr->GetType();
auto val_ty = val->GetType();
if (ptr_ty->IsPtrInt32()) {
if (!val_ty->IsInt32()) {
throw std::runtime_error(FormatError("ir", "存储类型不匹配:期望 int32"));
}
} else if (ptr_ty->IsPtrFloat()) {
if (!val_ty->IsFloat()) {
throw std::runtime_error(FormatError("ir", "存储类型不匹配:期望 float"));
}
} else if (ptr_ty->IsArray()) {
// 数组存储:检查元素类型
auto* array_ty = dynamic_cast<ArrayType*>(ptr_ty.get());
if (array_ty) {
auto elem_ty = array_ty->GetElementType();
if (elem_ty->IsInt32() && !val_ty->IsInt32()) {
throw std::runtime_error(FormatError("ir", "数组元素类型不匹配:期望 int32"));
} else if (elem_ty->IsFloat() && !val_ty->IsFloat()) {
throw std::runtime_error(FormatError("ir", "数组元素类型不匹配:期望 float"));
}
}
}
return insert_block_->Append<StoreInst>(Type::GetVoidType(), val, ptr);
}
@ -500,4 +557,64 @@ CallInst* IRBuilder::CreateCall(Function* callee,
auto ret_ty = func_ty->GetReturnType();
return insert_block_->Append<CallInst>(ret_ty, callee, args, name);
}
BinaryInst* IRBuilder::CreateFAdd(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<BinaryInst>(Opcode::FAdd, lhs->GetType(), lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateFSub(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<BinaryInst>(Opcode::FSub, lhs->GetType(), lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateFMul(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<BinaryInst>(Opcode::FMul, lhs->GetType(), lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateFDiv(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<BinaryInst>(Opcode::FDiv, lhs->GetType(), lhs, rhs, name);
}
// 浮点比较
FcmpInst* IRBuilder::CreateFCmpOEQ(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<FcmpInst>(
FcmpInst::Predicate::OEQ, lhs, rhs, Type::GetInt1Type(), name);
}
FcmpInst* IRBuilder::CreateFCmpONE(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<FcmpInst>(
FcmpInst::Predicate::ONE, lhs, rhs, Type::GetInt1Type(), name);
}
FcmpInst* IRBuilder::CreateFCmpOLT(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<FcmpInst>(
FcmpInst::Predicate::OLT, lhs, rhs, Type::GetInt1Type(), name);
}
FcmpInst* IRBuilder::CreateFCmpOLE(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<FcmpInst>(
FcmpInst::Predicate::OLE, lhs, rhs, Type::GetInt1Type(), name);
}
FcmpInst* IRBuilder::CreateFCmpOGT(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<FcmpInst>(
FcmpInst::Predicate::OGT, lhs, rhs, Type::GetInt1Type(), name);
}
FcmpInst* IRBuilder::CreateFCmpOGE(Value* lhs, Value* rhs, const std::string& name) {
return insert_block_->Append<FcmpInst>(
FcmpInst::Predicate::OGE, lhs, rhs, Type::GetInt1Type(), name);
}
// 类型转换
SIToFPInst* IRBuilder::CreateSIToFP(Value* value, std::shared_ptr<Type> target_ty,
const std::string& name) {
return insert_block_->Append<SIToFPInst>(value, target_ty, name);
}
FPToSIInst* IRBuilder::CreateFPToSI(Value* value, std::shared_ptr<Type> target_ty,
const std::string& name) {
return insert_block_->Append<FPToSIInst>(value, target_ty, name);
}
} // namespace ir

@ -69,6 +69,15 @@ static const char* OpcodeToString(Opcode op) {
return "not";
case Opcode::GEP:
return "getelementptr";
case Opcode::FAdd: return "fadd";
case Opcode::FSub: return "fsub";
case Opcode::FMul: return "fmul";
case Opcode::FDiv: return "fdiv";
case Opcode::FCmp: return "fcmp";
case Opcode::SIToFP: return "sitofp";
case Opcode::FPToSI: return "fptosi";
case Opcode::FPExt: return "fpext";
case Opcode::FPTrunc: return "fptrunc";
}
return "?";
}

@ -105,16 +105,22 @@ std::any IRGenImpl::visitConstDef(SysYParser::ConstDefContext* ctx) {
}
std::string const_name = ctx->Ident()->getText();
std::cerr << "[DEBUG] visitConstDef: processing constant " << const_name << std::endl;
// 检查是否为数组
bool is_array = !ctx->constExp().empty();
// 获取常量类型int 或 float
bool is_float = false;
auto* constDecl = dynamic_cast<SysYParser::ConstDeclContext*>(ctx->parent);
if (constDecl && constDecl->bType()) {
if (constDecl->bType()->Float()) {
is_float = true;
std::cerr << "[DEBUG] visitConstDef: 常量 " << const_name << " 是 float 类型" << std::endl;
}
}
if (is_array) {
// 数组常量处理 - 创建全局常量数组
std::cerr << "[DEBUG] visitConstDef: array constant " << const_name << std::endl;
// 获取数组维度
// 数组常量处理
std::vector<int> dimensions;
for (auto* const_exp : ctx->constExp()) {
int dim_size = TryEvaluateConstInt(const_exp);
@ -123,7 +129,14 @@ std::any IRGenImpl::visitConstDef(SysYParser::ConstDefContext* ctx) {
}
// 创建数组类型
auto array_type = ir::Type::GetArrayType(ir::Type::GetInt32Type(), dimensions);
std::shared_ptr<ir::Type> element_type;
if (is_float) {
element_type = ir::Type::GetFloatType();
} else {
element_type = ir::Type::GetInt32Type();
}
auto array_type = ir::Type::GetArrayType(element_type, dimensions);
ir::GlobalValue* global_array = module_.CreateGlobal(const_name, array_type);
// 处理初始化值
@ -134,17 +147,43 @@ std::any IRGenImpl::visitConstDef(SysYParser::ConstDefContext* ctx) {
try {
auto init_vec = std::any_cast<std::vector<ir::Value*>>(result);
for (auto* val : init_vec) {
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(val)) {
init_consts.push_back(const_int);
if (is_float) {
if (auto* const_float = dynamic_cast<ir::ConstantFloat*>(val)) {
init_consts.push_back(const_float);
} else if (auto* const_int = dynamic_cast<ir::ConstantInt*>(val)) {
// 整数转浮点
float float_val = static_cast<float>(const_int->GetValue());
init_consts.push_back(builder_.CreateConstFloat(float_val));
} else {
init_consts.push_back(builder_.CreateConstFloat(0.0f));
}
} else {
init_consts.push_back(builder_.CreateConstInt(0));
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(val)) {
init_consts.push_back(const_int);
} else if (auto* const_float = dynamic_cast<ir::ConstantFloat*>(val)) {
// 浮点转整数
int int_val = static_cast<int>(const_float->GetValue());
init_consts.push_back(builder_.CreateConstInt(int_val));
} else {
init_consts.push_back(builder_.CreateConstInt(0));
}
}
}
} catch (const std::bad_any_cast&) {
try {
ir::Value* single_val = std::any_cast<ir::Value*>(result);
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(single_val)) {
init_consts.push_back(const_int);
if (is_float) {
if (auto* const_float = dynamic_cast<ir::ConstantFloat*>(single_val)) {
init_consts.push_back(const_float);
} else {
init_consts.push_back(builder_.CreateConstFloat(0.0f));
}
} else {
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(single_val)) {
init_consts.push_back(const_int);
} else {
init_consts.push_back(builder_.CreateConstInt(0));
}
}
} catch (...) {}
}
@ -155,50 +194,47 @@ std::any IRGenImpl::visitConstDef(SysYParser::ConstDefContext* ctx) {
int total_size = 1;
for (int dim : dimensions) total_size *= dim;
while (init_consts.size() < static_cast<size_t>(total_size)) {
init_consts.push_back(builder_.CreateConstInt(0));
if (is_float) {
init_consts.push_back(builder_.CreateConstFloat(0.0f));
} else {
init_consts.push_back(builder_.CreateConstInt(0));
}
}
global_array->SetInitializer(init_consts);
global_array->SetConstant(true);
// 存储到常量映射而不是storage_map_
const_storage_map_[ctx] = global_array;
const_global_map_[const_name] = global_array;
} else {
// 标量常量处理 - 直接求值并存储常量值
std::cerr << "[DEBUG] visitConstDef: scalar constant " << const_name << std::endl;
// 标量常量处理
if (!ctx->constInitVal()) {
throw std::runtime_error(FormatError("irgen", "常量缺少初始值"));
}
// 求值常量表达式
// 求值常量表达式
auto* const_init_val = ctx->constInitVal();
// 关键修改:直接求值常量表达式,不使用 builder_
ir::ConstantValue* const_value = nullptr;
auto* const_init_val = ctx->constInitVal();
if (const_init_val->constExp()) {
// 直接访问常量表达式的值,不通过 IR 生成
int value = TryEvaluateConstInt(const_init_val->constExp());
// 使用 Context 直接创建常量,不依赖 builder_
const_value = module_.GetContext().GetConstInt(value);
std::cerr << "[DEBUG] visitConstDef: constant " << const_name
<< " = " << value << std::endl;
// 对于常量表达式,我们可以尝试直接求值
if (is_float) {
// TODO: 实现浮点常量表达式的求值
const_value = module_.GetContext().GetConstFloat(0.0f);
} else {
int value = TryEvaluateConstInt(const_init_val->constExp());
const_value = module_.GetContext().GetConstInt(value);
}
} else {
const_value = module_.GetContext().GetConstInt(0);
if (is_float) {
const_value = module_.GetContext().GetConstFloat(0.0f);
} else {
const_value = module_.GetContext().GetConstInt(0);
}
}
// 存储常量值到映射
const_value_map_[const_name] = const_value;
// 同时也保存一个虚拟指针用于统一接口(可选)
// auto* dummy_slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp() + "_" + const_name);
// builder_.CreateStore(const_value, dummy_slot);
// const_storage_map_[ctx] = dummy_slot;
std::cerr << "[DEBUG] visitConstDef: scalar constant stored, no alloca created" << std::endl;
}
return {};
@ -242,8 +278,20 @@ std::any IRGenImpl::HandleGlobalVariable(SysYParser::VarDefContext* ctx,
const std::string& varName,
bool is_array) {
std::cerr << "[DEBUG] HandleGlobalVariable: 开始处理全局变量 " << varName << std::endl;
// 获取变量类型int 或 float
bool is_float = false;
auto* varDecl = dynamic_cast<SysYParser::VarDeclContext*>(ctx->parent);
if (varDecl && varDecl->bType()) {
if (varDecl->bType()->Float()) {
is_float = true;
std::cerr << "[DEBUG] HandleGlobalVariable: 变量 " << varName << " 是 float 类型" << std::endl;
} else if (varDecl->bType()->Int()) {
std::cerr << "[DEBUG] HandleGlobalVariable: 变量 " << varName << " 是 int 类型" << std::endl;
}
}
if (is_array) {
std::cerr << "[DEBUG] HandleGlobalVariable: 处理全局数组变量" << std::endl;
// 全局数组变量
int total_size = 1;
std::vector<int> dimensions;
@ -261,12 +309,15 @@ std::any IRGenImpl::HandleGlobalVariable(SysYParser::VarDefContext* ctx,
std::cerr << "[DEBUG] HandleGlobalVariable: 数组总大小: " << total_size << std::endl;
if (total_size <= 0 || total_size > 10000) {
throw std::runtime_error(FormatError("irgen", "全局数组大小无效"));
// 创建数组类型
std::shared_ptr<ir::Type> element_type;
if (is_float) {
element_type = ir::Type::GetFloatType();
} else {
element_type = ir::Type::GetInt32Type();
}
// 创建数组类型的全局变量
auto array_type = ir::Type::GetArrayType(ir::Type::GetInt32Type(), dimensions);
auto array_type = ir::Type::GetArrayType(element_type, dimensions);
ir::GlobalValue* global_array = module_.CreateGlobal(varName, array_type);
std::cerr << "[DEBUG] HandleGlobalVariable: 创建全局数组: " << varName << std::endl;
@ -277,26 +328,36 @@ std::any IRGenImpl::HandleGlobalVariable(SysYParser::VarDefContext* ctx,
auto result = initVal->accept(this);
if (result.has_value()) {
try {
// 尝试获取初始化值列表
auto init_vec = std::any_cast<std::vector<ir::Value*>>(result);
std::cerr << "[DEBUG] HandleGlobalVariable: 获取到初始化值列表, 大小: " << init_vec.size() << std::endl;
for (auto* val : init_vec) {
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(val)) {
init_consts.push_back(const_int);
} else if (auto* const_float = dynamic_cast<ir::ConstantFloat*>(val)) {
init_consts.push_back(const_float);
} else {
// 非常量表达式使用0
init_consts.push_back(builder_.CreateConstInt(0));
if (is_float) {
init_consts.push_back(builder_.CreateConstFloat(0.0f));
} else {
init_consts.push_back(builder_.CreateConstInt(0));
}
}
}
} catch (const std::bad_any_cast&) {
try {
// 可能是单个值
ir::Value* single_val = std::any_cast<ir::Value*>(result);
std::cerr << "[DEBUG] HandleGlobalVariable: 获取到单个初始化值" << std::endl;
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(single_val)) {
init_consts.push_back(const_int);
} else if (auto* const_float = dynamic_cast<ir::ConstantFloat*>(single_val)) {
init_consts.push_back(const_float);
} else {
init_consts.push_back(builder_.CreateConstInt(0));
if (is_float) {
init_consts.push_back(builder_.CreateConstFloat(0.0f));
} else {
init_consts.push_back(builder_.CreateConstInt(0));
}
}
} catch (const std::bad_any_cast&) {
std::cerr << "[WARNING] HandleGlobalVariable: 无法解析数组初始化值" << std::endl;
@ -307,7 +368,11 @@ std::any IRGenImpl::HandleGlobalVariable(SysYParser::VarDefContext* ctx,
// 如果初始化值不足补0
while (init_consts.size() < static_cast<size_t>(total_size)) {
init_consts.push_back(builder_.CreateConstInt(0));
if (is_float) {
init_consts.push_back(builder_.CreateConstFloat(0.0f));
} else {
init_consts.push_back(builder_.CreateConstInt(0));
}
}
// 设置全局数组的初始化器
@ -316,29 +381,20 @@ std::any IRGenImpl::HandleGlobalVariable(SysYParser::VarDefContext* ctx,
std::cerr << "[DEBUG] HandleGlobalVariable: 设置全局数组初始化器" << std::endl;
}
// 判断是否为常量(检查父节点是否为 ConstDef
if (ctx->parent && dynamic_cast<SysYParser::ConstDefContext*>(ctx->parent)) {
global_array->SetConstant(true);
std::cerr << "[DEBUG] HandleGlobalVariable: 设置为常量数组" << std::endl;
}
// 存储全局变量引用
storage_map_[ctx] = global_array;
global_map_[varName] = global_array;//按名称映射
std::cerr << "[DEBUG] HandleGlobalVariable: 存储全局数组引用" << std::endl;
// 保存数组信息
ArrayInfo info;
info.elements.clear(); // 全局数组不预先分配元素槽位
info.dimensions = dimensions;
array_info_map_[ctx] = info;
global_map_[varName] = global_array;
std::cerr << "[DEBUG] HandleGlobalVariable: 创建全局数组 " << varName
<< ",总大小 " << total_size << std::endl;
} else {
std::cerr << "[DEBUG] HandleGlobalVariable: 处理全局标量变量" << std::endl;
// 全局标量变量
ir::GlobalValue* global_var = module_.CreateGlobal(varName, ir::Type::GetInt32Type());
std::shared_ptr<ir::Type> var_type;
if (is_float) {
var_type = ir::Type::GetFloatType();
} else {
var_type = ir::Type::GetInt32Type();
}
ir::GlobalValue* global_var = module_.CreateGlobal(varName, var_type);
std::cerr << "[DEBUG] HandleGlobalVariable: 创建全局标量变量: " << varName << std::endl;
// 处理初始化值
@ -349,111 +405,129 @@ std::any IRGenImpl::HandleGlobalVariable(SysYParser::VarDefContext* ctx,
if (result.has_value()) {
try {
ir::Value* val = std::any_cast<ir::Value*>(result);
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(val)) {
init_value = const_int;
std::cerr << "[DEBUG] HandleGlobalVariable: 获取到常量初始化值" << std::endl;
if (is_float) {
if (auto* const_float = dynamic_cast<ir::ConstantFloat*>(val)) {
init_value = const_float;
} else if (auto* const_int = dynamic_cast<ir::ConstantInt*>(val)) {
// 整数转浮点
float float_val = static_cast<float>(const_int->GetValue());
init_value = builder_.CreateConstFloat(float_val);
} else {
init_value = builder_.CreateConstFloat(0.0f);
}
} else {
// 默认初始化为0
init_value = builder_.CreateConstInt(0);
std::cerr << "[DEBUG] HandleGlobalVariable: 使用默认初始化值0" << std::endl;
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(val)) {
init_value = const_int;
} else if (auto* const_float = dynamic_cast<ir::ConstantFloat*>(val)) {
// 浮点转整数
int int_val = static_cast<int>(const_float->GetValue());
init_value = builder_.CreateConstInt(int_val);
} else {
init_value = builder_.CreateConstInt(0);
}
}
} catch (const std::bad_any_cast&) {
init_value = builder_.CreateConstInt(0);
std::cerr << "[DEBUG] HandleGlobalVariable: 类型转换失败使用默认初始化值0" << std::endl;
if (is_float) {
init_value = builder_.CreateConstFloat(0.0f);
} else {
init_value = builder_.CreateConstInt(0);
}
}
} else {
std::cerr << "[DEBUG] HandleGlobalVariable: 无初始化值结果" << std::endl;
}
} else {
std::cerr << "[DEBUG] HandleGlobalVariable: 无初始化值" << std::endl;
}
// 如果没有初始化值,默认初始化为0
// 如果没有初始化值,默认初始化
if (!init_value) {
init_value = builder_.CreateConstInt(0);
std::cerr << "[DEBUG] HandleGlobalVariable: 使用默认初始化值0" << std::endl;
if (is_float) {
init_value = builder_.CreateConstFloat(0.0f);
} else {
init_value = builder_.CreateConstInt(0);
}
}
// 设置全局变量的初始化器
global_var->SetInitializer(init_value);
std::cerr << "[DEBUG] HandleGlobalVariable: 设置全局变量初始化器" << std::endl;
// 判断是否为常量
if (ctx->parent && dynamic_cast<SysYParser::ConstDefContext*>(ctx->parent)) {
global_var->SetConstant(true);
std::cerr << "[DEBUG] HandleGlobalVariable: 设置为常量" << std::endl;
}
// 存储全局变量引用
storage_map_[ctx] = global_var;
global_map_[varName] = global_var;
std::cerr << "[DEBUG] HandleGlobalVariable: 存储全局变量引用" << std::endl;
std::cerr << "[DEBUG] HandleGlobalVariable: 创建全局变量 " << varName << std::endl;
}
std::cerr << "[DEBUG] HandleGlobalVariable: 全局变量处理完成" << std::endl;
return {};
}
// 修改 HandleLocalVariable 函数中的数组处理部分
std::any IRGenImpl::HandleLocalVariable(SysYParser::VarDefContext* ctx,
const std::string& varName,
bool is_array) {
std::cerr << "[DEBUG] HandleLocalVariable: 开始处理局部变量 " << varName << std::endl;
// 获取变量类型
bool is_float = false;
auto* varDecl = dynamic_cast<SysYParser::VarDeclContext*>(ctx->parent);
if (varDecl && varDecl->bType()) {
if (varDecl->bType()->Float()) {
is_float = true;
std::cerr << "[DEBUG] HandleLocalVariable: 变量 " << varName << " 是 float 类型" << std::endl;
}
}
if (is_array) {
std::cerr << "[DEBUG] HandleLocalVariable: 处理局部数组变量" << std::endl;
// 局部数组变量
int total_size = 1;
std::vector<int> dimensions;
// 获取数组维度
for (auto* const_exp : ctx->constExp()) {
try {
int dim_size = TryEvaluateConstInt(const_exp);
if (dim_size <= 0) {
dim_size = 1;
std::cerr << "[WARNING] HandleLocalVariable: 无法确定数组维度大小使用1" << std::endl;
}
if (dim_size <= 0) dim_size = 1;
dimensions.push_back(dim_size);
total_size *= dim_size;
} catch (const std::exception& e) {
std::cerr << "[WARNING] HandleLocalVariable: 无法获取数组维度: " << e.what()
<< "使用维度1" << std::endl;
std::cerr << "[WARNING] HandleLocalVariable: 无法获取数组维度使用维度1" << std::endl;
dimensions.push_back(1);
total_size *= 1;
}
}
std::cerr << "[DEBUG] HandleLocalVariable: 数组总大小: " << total_size << std::endl;
if (total_size <= 0) {
throw std::runtime_error(FormatError("irgen", "数组大小必须为正数"));
}
if (total_size > 10000) {
throw std::runtime_error(FormatError("irgen", "数组大小太大"));
// 创建数组类型
std::shared_ptr<ir::Type> elem_type;
if (is_float) {
elem_type = ir::Type::GetFloatType();
} else {
elem_type = ir::Type::GetInt32Type();
}
// 分配数组存储 - 为每个元素创建独立的 alloca
// 修正:使用完整的维度列表创建数组类型
auto array_type = ir::Type::GetArrayType(elem_type, dimensions);
// 分配数组内存 - 为每个元素创建独立的 alloca
std::vector<ir::Value*> element_slots;
std::cerr << "[DEBUG] HandleLocalVariable: 为数组元素分配存储空间" << std::endl;
for (int i = 0; i < total_size; i++) {
auto* slot = builder_.CreateAllocaI32(
module_.GetContext().NextTemp() + "_" + varName + "_" + std::to_string(i));
ir::AllocaInst* slot;
if (is_float) {
slot = builder_.CreateAllocaFloat(
module_.GetContext().NextTemp() + "_" + varName + "_" + std::to_string(i));
} else {
slot = builder_.CreateAllocaI32(
module_.GetContext().NextTemp() + "_" + varName + "_" + std::to_string(i));
}
element_slots.push_back(slot);
}
// 存储第一个元素的地址作为数组的基地址
storage_map_[ctx] = element_slots[0];
local_var_map_[varName] = element_slots[0];
// 处理初始化
if (auto* initVal = ctx->initVal()) {
std::cerr << "[DEBUG] HandleLocalVariable: 处理数组初始化值" << std::endl;
auto result = initVal->accept(this);
if (result.has_value()) {
try {
// 尝试获取初始化值列表
std::vector<ir::Value*> init_values =
std::any_cast<std::vector<ir::Value*>>(result);
std::cerr << "[DEBUG] HandleLocalVariable: 获取到初始化值列表, 大小: " << init_values.size() << std::endl;
// 初始化数组元素
for (size_t i = 0; i < init_values.size() && i < static_cast<size_t>(total_size); i++) {
@ -462,114 +536,119 @@ std::any IRGenImpl::HandleLocalVariable(SysYParser::VarDefContext* ctx,
// 剩余元素初始化为0
for (size_t i = init_values.size(); i < static_cast<size_t>(total_size); i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
if (is_float) {
builder_.CreateStore(builder_.CreateConstFloat(0.0f), element_slots[i]);
} else {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
} catch (const std::bad_any_cast&) {
// 可能返回的是单个值
try {
ir::Value* single_value = std::any_cast<ir::Value*>(result);
std::cerr << "[DEBUG] HandleLocalVariable: 获取到单个初始化值" << std::endl;
// 只初始化第一个元素
builder_.CreateStore(single_value, element_slots[0]);
// 其他元素初始化为0
for (int i = 1; i < total_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
if (is_float) {
builder_.CreateStore(builder_.CreateConstFloat(0.0f), element_slots[i]);
} else {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
} catch (const std::bad_any_cast&) {
std::cerr << "[ERROR] HandleLocalVariable: 无法解析数组初始化值类型" << std::endl;
// 全部初始化为0
for (int i = 0; i < total_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
if (is_float) {
builder_.CreateStore(builder_.CreateConstFloat(0.0f), element_slots[i]);
} else {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
}
}
} else {
std::cerr << "[DEBUG] HandleLocalVariable: 无初始化值结果" << std::endl;
// 没有初始化值全部初始化为0
for (int i = 0; i < total_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
if (is_float) {
builder_.CreateStore(builder_.CreateConstFloat(0.0f), element_slots[i]);
} else {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
}
} else {
std::cerr << "[DEBUG] HandleLocalVariable: 无初始化全部初始化为0" << std::endl;
// 无初始化所有元素初始化为0
for (int i = 0; i < total_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
if (is_float) {
builder_.CreateStore(builder_.CreateConstFloat(0.0f), element_slots[i]);
} else {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
}
// 存储第一个元素的地址作为数组的基地址
storage_map_[ctx] = element_slots[0];
local_var_map_[varName] = element_slots[0]; // 添加到局部变量映射,按名称映射
std::cerr << "[DEBUG] HandleLocalVariable: 存储数组引用" << std::endl;
// 保存数组信息
ArrayInfo info;
info.elements = element_slots;
info.dimensions = dimensions;
array_info_map_[ctx] = info;
std::cerr << "[DEBUG] HandleLocalVariable: 创建局部数组 " << varName
<< ",维度 ";
for (size_t i = 0; i < dimensions.size(); i++) {
std::cerr << dimensions[i];
if (i < dimensions.size() - 1) std::cerr << "×";
}
std::cerr << ",总大小 " << total_size << std::endl;
} else {
std::cerr << "[DEBUG] HandleLocalVariable: 处理局部标量变量" << std::endl;
// 局部标量变量
auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp() + "_" + varName);
ir::AllocaInst* slot;
if (is_float) {
slot = builder_.CreateAllocaFloat(module_.GetContext().NextTemp() + "_" + varName);
} else {
slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp() + "_" + varName);
}
storage_map_[ctx] = slot;
local_var_map_[varName] = slot; // 添加到局部变量映射
std::cerr << "[DEBUG] HandleLocalVariable: 创建局部标量变量存储槽" << std::endl;
local_var_map_[varName] = slot;
// 处理初始化
ir::Value* init = nullptr;
if (auto* initVal = ctx->initVal()) {
std::cerr << "[DEBUG] HandleLocalVariable: 处理标量初始化值" << std::endl;
auto result = initVal->accept(this);
if (result.has_value()) {
try {
init = std::any_cast<ir::Value*>(result);
std::cerr << "[DEBUG] HandleLocalVariable: 获取到初始化值" << std::endl;
} catch (const std::bad_any_cast&) {
// 可能是聚合初始化返回的 vector但标量只取第一个值
try {
std::vector<ir::Value*> init_values =
std::any_cast<std::vector<ir::Value*>>(result);
if (!init_values.empty()) {
init = init_values[0];
std::cerr << "[DEBUG] HandleLocalVariable: 从列表获取第一个初始化值" << std::endl;
} else {
init = builder_.CreateConstInt(0);
std::cerr << "[DEBUG] HandleLocalVariable: 初始化列表为空使用0" << std::endl;
if (is_float) {
init = builder_.CreateConstFloat(0.0f);
} else {
init = builder_.CreateConstInt(0);
}
}
} catch (const std::bad_any_cast&) {
init = builder_.CreateConstInt(0);
std::cerr << "[DEBUG] HandleLocalVariable: 无法解析初始化值类型使用0" << std::endl;
if (is_float) {
init = builder_.CreateConstFloat(0.0f);
} else {
init = builder_.CreateConstInt(0);
}
}
}
} else {
init = builder_.CreateConstInt(0);
std::cerr << "[DEBUG] HandleLocalVariable: 无初始化值结果使用0" << std::endl;
if (is_float) {
init = builder_.CreateConstFloat(0.0f);
} else {
init = builder_.CreateConstInt(0);
}
}
} else {
init = builder_.CreateConstInt(0);
std::cerr << "[DEBUG] HandleLocalVariable: 无初始化值使用0" << std::endl;
if (is_float) {
init = builder_.CreateConstFloat(0.0f);
} else {
init = builder_.CreateConstInt(0);
}
}
builder_.CreateStore(init, slot);
std::cerr << "[DEBUG] HandleLocalVariable: 创建局部变量 " << varName
<< ",初始值 " << (void*)init << std::endl;
}
std::cerr << "[DEBUG] HandleLocalVariable: 局部变量处理完成" << std::endl;
return {};
}
std::any IRGenImpl::visitInitVal(SysYParser::InitValContext* ctx) {
std::cerr << "[DEBUG] visitInitVal: 开始处理初始化值" << std::endl;
if (!ctx) {

@ -79,6 +79,41 @@ std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
return static_cast<ir::Value*>(const_int);
}
if (ctx->HEX_FLOAT()) {
std::string hex_float_str = ctx->HEX_FLOAT()->getText();
float value = 0.0f;
// 解析十六进制浮点数
try {
// C++11 的 std::stof 支持十六进制浮点数表示
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<ir::Value*>(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<ir::Value*>(const_float);
}
if (ctx->HEX_INT()) {
std::string hex = ctx->HEX_INT()->getText();
int value = std::stoi(hex, nullptr, 16);
@ -217,7 +252,7 @@ std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
builder_.CreateLoad(ptr, module_.GetContext().NextTemp()));
}
}
// 加法表达式
std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
std::cout << "[DEBUG IRGEN] visitAddExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
@ -243,23 +278,45 @@ std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
}
ir::Value* right = std::any_cast<ir::Value*>(right_any);
std::cerr << "[DEBUG] visitAddExp: left=" << (void*)left << ", right=" << (void*)right << std::endl;
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是floatright是int需要将right转换为float
right = builder_.CreateSIToFP(right, ir::Type::GetFloatType());
} else {
// right是floatleft是int需要将left转换为float
left = builder_.CreateSIToFP(left, ir::Type::GetFloatType());
}
}
// 根据操作符生成相应的指令
if (ctx->AddOp()) {
return static_cast<ir::Value*>(
builder_.CreateAdd(left, right, module_.GetContext().NextTemp()));
if (left->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFAdd(left, right, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateAdd(left, right, module_.GetContext().NextTemp()));
}
} else if (ctx->SubOp()) {
return static_cast<ir::Value*>(
builder_.CreateSub(left, right, module_.GetContext().NextTemp()));
if (left->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFSub(left, right, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateSub(left, right, module_.GetContext().NextTemp()));
}
}
throw std::runtime_error(FormatError("irgen", "未知的加法操作符"));
}
// 在 IRGenExp.cpp 中添加
// visitMulExp
std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) {
std::cout << "[DEBUG IRGEN] visitMulExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
@ -285,14 +342,45 @@ std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) {
}
ir::Value* right = std::any_cast<ir::Value*>(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是floatright是int需要将right转换为float
right = builder_.CreateSIToFP(right, ir::Type::GetFloatType());
} else {
// right是floatleft是int需要将left转换为float
left = builder_.CreateSIToFP(left, ir::Type::GetFloatType());
}
}
// 根据操作符生成指令
if (ctx->MulOp()) {
return static_cast<ir::Value*>(
builder_.CreateMul(left, right, module_.GetContext().NextTemp()));
if (left->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFMul(left, right, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateMul(left, right, module_.GetContext().NextTemp()));
}
} else if (ctx->DivOp()) {
return static_cast<ir::Value*>(
builder_.CreateDiv(left, right, module_.GetContext().NextTemp()));
if (left->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFDiv(left, right, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
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<ir::Value*>(
builder_.CreateMod(left, right, module_.GetContext().NextTemp()));
}
@ -301,6 +389,7 @@ std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) {
}
// 逻辑与
std::any IRGenImpl::visitLAndExp(SysYParser::LAndExpContext* ctx) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法逻辑与表达式"));
@ -456,8 +545,6 @@ ir::Function* IRGenImpl::CreateRuntimeFunctionDecl(const std::string& funcName)
return nullptr;
}
// 实现一元表达式
std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法一元表达式"));
@ -482,13 +569,33 @@ std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
// +x 等价于 x
return operand;
} else if (op == "-") {
// -x 等价于 0 - x
ir::Value* zero = builder_.CreateConstInt(0);
return static_cast<ir::Value*>(
builder_.CreateBinary(ir::Opcode::Sub, zero, operand,
module_.GetContext().NextTemp()));
// -x 根据操作数类型选择整数或浮点减法
if (operand->GetType()->IsFloat()) {
// 浮点取负0.0 - x
ir::Value* zero_float = builder_.CreateConstFloat(0.0f);
return static_cast<ir::Value*>(
builder_.CreateFSub(zero_float, operand, module_.GetContext().NextTemp()));
} else {
// 整数取负0 - x
ir::Value* zero = builder_.CreateConstInt(0);
return static_cast<ir::Value*>(
builder_.CreateSub(zero, operand, module_.GetContext().NextTemp()));
}
} else if (op == "!") {
return builder_.CreateNot(operand, module_.GetContext().NextTemp());
// 逻辑非运算
// 先将值转换为bool与0比较
ir::Value* zero;
if (operand->GetType()->IsFloat()) {
zero = builder_.CreateConstFloat(0.0f);
// 浮点比较不等于0
ir::Value* cmp = builder_.CreateFCmpONE(operand, zero, module_.GetContext().NextTemp());
// 将bool转换为int
return static_cast<ir::Value*>(
builder_.CreateZExt(cmp, ir::Type::GetInt32Type()));
} else {
zero = builder_.CreateConstInt(0);
return builder_.CreateNot(operand, module_.GetContext().NextTemp());
}
}
}
@ -610,22 +717,59 @@ std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
auto right_any = ctx->addExp()->accept(this);
auto* lhs = std::any_cast<ir::Value*>(left_any);
auto* rhs = std::any_cast<ir::Value*>(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是floatrhs是int需要将rhs转换为float
rhs = builder_.CreateSIToFP(rhs, ir::Type::GetFloatType());
} else {
// rhs是floatlhs是int需要将lhs转换为float
lhs = builder_.CreateSIToFP(lhs, ir::Type::GetFloatType());
}
}
// 根据操作数和类型选择指令
if (ctx->LOp()) {
return static_cast<ir::Value*>(
builder_.CreateICmpLT(lhs, rhs, module_.GetContext().NextTemp()));
if (lhs->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFCmpOLT(lhs, rhs, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateICmpLT(lhs, rhs, module_.GetContext().NextTemp()));
}
}
if (ctx->GOp()) {
return static_cast<ir::Value*>(
builder_.CreateICmpGT(lhs, rhs, module_.GetContext().NextTemp()));
if (lhs->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFCmpOGT(lhs, rhs, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateICmpGT(lhs, rhs, module_.GetContext().NextTemp()));
}
}
if (ctx->LeOp()) {
return static_cast<ir::Value*>(
builder_.CreateICmpLE(lhs, rhs, module_.GetContext().NextTemp()));
if (lhs->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFCmpOLE(lhs, rhs, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateICmpLE(lhs, rhs, module_.GetContext().NextTemp()));
}
}
if (ctx->GeOp()) {
return static_cast<ir::Value*>(
builder_.CreateICmpGE(lhs, rhs, module_.GetContext().NextTemp()));
if (lhs->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFCmpOGE(lhs, rhs, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateICmpGE(lhs, rhs, module_.GetContext().NextTemp()));
}
}
throw std::runtime_error(FormatError("irgen", "未知关系运算符"));
}
@ -637,7 +781,6 @@ std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
throw std::runtime_error(FormatError("irgen", "关系表达式暂未实现"));
}
// 相等表达式(支持 ==, !=
std::any IRGenImpl::visitEqExp(SysYParser::EqExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法相等表达式"));
@ -648,14 +791,41 @@ std::any IRGenImpl::visitEqExp(SysYParser::EqExpContext* ctx) {
auto right_any = ctx->relExp()->accept(this);
auto* lhs = std::any_cast<ir::Value*>(left_any);
auto* rhs = std::any_cast<ir::Value*>(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是floatrhs是int需要将rhs转换为float
rhs = builder_.CreateSIToFP(rhs, ir::Type::GetFloatType());
} else {
// rhs是floatlhs是int需要将lhs转换为float
lhs = builder_.CreateSIToFP(lhs, ir::Type::GetFloatType());
}
}
// 根据操作符和类型选择指令
if (ctx->EqOp()) {
return static_cast<ir::Value*>(
builder_.CreateICmpEQ(lhs, rhs, module_.GetContext().NextTemp()));
if (lhs->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFCmpOEQ(lhs, rhs, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateICmpEQ(lhs, rhs, module_.GetContext().NextTemp()));
}
}
if (ctx->NeOp()) {
return static_cast<ir::Value*>(
builder_.CreateICmpNE(lhs, rhs, module_.GetContext().NextTemp()));
if (lhs->GetType()->IsFloat()) {
return static_cast<ir::Value*>(
builder_.CreateFCmpONE(lhs, rhs, module_.GetContext().NextTemp()));
} else {
return static_cast<ir::Value*>(
builder_.CreateICmpNE(lhs, rhs, module_.GetContext().NextTemp()));
}
}
throw std::runtime_error(FormatError("irgen", "未知相等运算符"));
}
@ -667,6 +837,7 @@ std::any IRGenImpl::visitEqExp(SysYParser::EqExpContext* ctx) {
throw std::runtime_error(FormatError("irgen", "相等表达式暂未实现"));
}
ir::Value* IRGenImpl::EvalAssign(SysYParser::StmtContext* ctx) {
std::cout << "[DEBUG IRGEN] visitCond: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx || !ctx->lVal() || !ctx->exp()) {

@ -158,15 +158,23 @@ std::any IRGenImpl::visitFuncDef(SysYParser::FuncDefContext* ctx) {
std::vector<std::shared_ptr<ir::Type>> param_types;
if (ctx->funcFParams()) {
for (auto* param : ctx->funcFParams()->funcFParam()) {
if (!param || !param->bType()) continue;
if (!param || !param->Ident()) continue;
std::string name = param->Ident()->getText();
std::shared_ptr<ir::Type> param_ty;
// 检查 bType 是否存在
if (!param->bType()) {
throw std::runtime_error(FormatError("irgen", "函数参数缺少类型: " + name));
}
if (param->bType()->Int()) {
param_ty = ir::Type::GetInt32Type();
} else if (param->bType()->Float()) {
param_ty = ir::Type::GetFloatType();
} else {
param_ty = ir::Type::GetInt32Type();
param_ty = ir::Type::GetInt32Type(); // 默认值
}
if (!param->L_BRACK().empty()) {
if (param_ty->IsInt32()) {
param_ty = ir::Type::GetPtrInt32Type();
@ -174,22 +182,53 @@ std::any IRGenImpl::visitFuncDef(SysYParser::FuncDefContext* ctx) {
param_ty = ir::Type::GetPtrFloatType();
}
}
param_types.push_back(param_ty);
}
}
// 创建函数类型
auto func_type = ir::Type::GetFunctionType(ret_type, param_types);
// 调试输出
std::cerr << "[DEBUG] visitFuncDef: 创建函数 " << funcName
<< ",返回类型: " << (ret_type->IsVoid() ? "void" : ret_type->IsFloat() ? "float" : "int")
<< ",参数数量: " << param_types.size() << std::endl;
// 创建函数对象
func_ = module_.CreateFunction(funcName, func_type);
builder_.SetInsertPoint(func_->GetEntry());
// 检查函数是否成功创建
if (!func_) {
std::cerr << "[ERROR] visitFuncDef: 创建函数失败func_ 为 nullptr!" << std::endl;
throw std::runtime_error(FormatError("irgen", "创建函数失败: " + funcName));
}
std::cerr << "[DEBUG] visitFuncDef: 函数对象地址: " << (void*)func_ << std::endl;
// 设置插入点
auto* entry_block = func_->GetEntry();
if (!entry_block) {
std::cerr << "[ERROR] visitFuncDef: 函数入口基本块为空!" << std::endl;
throw std::runtime_error(FormatError("irgen", "函数入口基本块为空: " + funcName));
}
builder_.SetInsertPoint(entry_block);
storage_map_.clear();
param_map_.clear();
// 函数参数 (按照语义分析、symbol table 定义顺序)
// 函数参数处理
if (ctx->funcFParams()) {
for (auto* param : ctx->funcFParams()->funcFParam()) {
if (!param || !param->Ident()) continue;
std::string name = param->Ident()->getText();
std::shared_ptr<ir::Type> param_ty;
// 再次检查 bType
if (!param->bType()) {
throw std::runtime_error(FormatError("irgen", "函数参数缺少类型: " + name));
}
if (param->bType()->Int()) {
param_ty = ir::Type::GetInt32Type();
} else if (param->bType()->Float()) {
@ -197,6 +236,7 @@ std::any IRGenImpl::visitFuncDef(SysYParser::FuncDefContext* ctx) {
} else {
param_ty = ir::Type::GetInt32Type();
}
if (!param->L_BRACK().empty()) {
if (param_ty->IsInt32()) {
param_ty = ir::Type::GetPtrInt32Type();
@ -204,8 +244,35 @@ std::any IRGenImpl::visitFuncDef(SysYParser::FuncDefContext* ctx) {
param_ty = ir::Type::GetPtrFloatType();
}
}
auto* arg = func_->AddArgument(std::make_unique<ir::Argument>(param_ty, name));
ir::AllocaInst* slot;
// 检查函数对象是否有效
if (!func_) {
std::cerr << "[ERROR] visitFuncDef: func_ 在添加参数时变为 nullptr!" << std::endl;
throw std::runtime_error(FormatError("irgen", "函数对象无效"));
}
std::cerr << "[DEBUG] visitFuncDef: 为函数 " << funcName
<< " 添加参数 " << name << ",类型: "
<< (param_ty->IsInt32() ? "int32" : param_ty->IsFloat() ? "float" :
param_ty->IsPtrInt32() ? "ptr_int32" : param_ty->IsPtrFloat() ? "ptr_float" : "other")
<< std::endl;
// 创建参数并添加到函数
auto arg = std::make_unique<ir::Argument>(param_ty, name);
if (!arg) {
throw std::runtime_error(FormatError("irgen", "创建参数失败: " + name));
}
auto* arg_ptr = arg.get();
auto* added_arg = func_->AddArgument(std::move(arg));
if (!added_arg) {
std::cerr << "[ERROR] visitFuncDef: AddArgument 返回 nullptr!" << std::endl;
throw std::runtime_error(FormatError("irgen", "添加参数失败: " + name));
}
// 为参数创建存储槽位
ir::AllocaInst* slot = nullptr;
if (param_ty->IsInt32() || param_ty->IsPtrInt32()) {
slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp());
} else if (param_ty->IsFloat() || param_ty->IsPtrFloat()) {
@ -213,24 +280,43 @@ std::any IRGenImpl::visitFuncDef(SysYParser::FuncDefContext* ctx) {
} else {
throw std::runtime_error(FormatError("irgen", "不支持的参数类型"));
}
builder_.CreateStore(arg, slot);
if (!slot) {
throw std::runtime_error(FormatError("irgen", "创建参数存储槽位失败: " + name));
}
builder_.CreateStore(added_arg, slot);
param_map_[name] = slot;
std::cerr << "[DEBUG] visitFuncDef: 参数 " << name << " 处理完成" << std::endl;
}
}
// 生成函数体
std::cerr << "[DEBUG] visitFuncDef: 开始生成函数体" << std::endl;
ctx->block()->accept(this);
// 如果函数没有终止指令,添加默认返回
if (!func_->GetEntry()->HasTerminator()) {
std::cerr << "[DEBUG] visitFuncDef: 函数体没有终止指令,添加默认返回" << std::endl;
auto retVal = builder_.CreateConstInt(0);
builder_.CreateRet(retVal);
}
VerifyFunctionStructure(*func_);
// 验证函数结构
try {
VerifyFunctionStructure(*func_);
} catch (const std::exception& e) {
std::cerr << "[ERROR] visitFuncDef: 验证函数结构失败: " << e.what() << std::endl;
throw;
}
std::cerr << "[DEBUG] visitFuncDef: 函数 " << funcName << " 生成完成" << std::endl;
func_ = nullptr;
return {};
}
std::any IRGenImpl::visitBlock(SysYParser::BlockContext* ctx) {
std::cout << "[DEBUG IRGEN] visitBlock: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {

@ -62,26 +62,65 @@ std::any IRGenImpl::visitStmt(SysYParser::StmtContext* ctx) {
throw std::runtime_error(FormatError("irgen", "暂不支持的语句类型"));
}
// 修改 HandleReturnStmt 函数
IRGenImpl::BlockFlow IRGenImpl::HandleReturnStmt(SysYParser::StmtContext* ctx) {
std::cout << "[DEBUG IRGEN] HandleReturnStmt: " << (ctx ? ctx->getText() : "<null>") << std::endl;
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少 return 语句"));
}
ir::Value* retValue = nullptr;
if (ctx->exp()) {
std::cout << "[DEBUG IRGEN] HandleReturnStmt eval exp: " << ctx->exp()->getText() << std::endl;
retValue = EvalExpr(*ctx->exp());
// 检查函数是否存在
if (!func_) {
throw std::runtime_error(FormatError("irgen", "Return语句不在函数中"));
}
// 如果没有表达式返回0对于int main
if (!retValue) {
retValue = builder_.CreateConstInt(0);
// 获取函数类型中的返回类型
auto func_type = std::dynamic_pointer_cast<ir::FunctionType>(func_->GetType());
if (!func_type) {
throw std::runtime_error(FormatError("irgen", "函数类型无效"));
}
builder_.CreateRet(retValue);
auto ret_type = func_type->GetReturnType();
if (ret_type->IsVoid()) {
if (ctx->exp()) {
// 表达式被忽略(可计算但不使用)
EvalExpr(*ctx->exp());
}
// 对于void函数创建返回指令不传参数
builder_.CreateRet(nullptr);
} else {
ir::Value* retValue = nullptr;
if (ctx->exp()) {
retValue = EvalExpr(*ctx->exp());
if (!retValue) {
throw std::runtime_error(FormatError("irgen", "返回值表达式求值失败"));
}
// 类型转换
if (retValue->GetType() != ret_type) {
if (ret_type->IsInt32() && retValue->GetType()->IsFloat()) {
retValue = builder_.CreateFPToSI(retValue, ir::Type::GetInt32Type());
} else if (ret_type->IsFloat() && retValue->GetType()->IsInt32()) {
retValue = builder_.CreateSIToFP(retValue, ir::Type::GetFloatType());
}
}
} else {
// 无表达式,返回默认值
if (ret_type->IsInt32()) {
retValue = builder_.CreateConstInt(0);
} else if (ret_type->IsFloat()) {
retValue = builder_.CreateConstFloat(0.0f);
} else {
retValue = builder_.CreateConstInt(0); // fallback
}
}
builder_.CreateRet(retValue);
}
return BlockFlow::Terminated;
}
// if语句待实现
IRGenImpl::BlockFlow IRGenImpl::HandleIfStmt(SysYParser::StmtContext* ctx) {
std::cout << "[DEBUG IRGEN] HandleIfStmt: " << (ctx ? ctx->getText() : "<null>") << std::endl;

Loading…
Cancel
Save