|
|
|
|
@ -30,12 +30,14 @@ int TryGetConstInt(SysYParser::ConstExpContext* ctx) {
|
|
|
|
|
// 注意:visitBlock 已经在 IRGenFunc.cpp 中实现,这里不要重复定义
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitDecl(SysYParser::DeclContext* ctx) {
|
|
|
|
|
std::cerr << "[DEBUG] visitDecl: 开始处理声明" << std::endl;
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "缺少变量声明"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理 varDecl
|
|
|
|
|
if (auto* varDecl = ctx->varDecl()) {
|
|
|
|
|
std::cerr << "[DEBUG] visitDecl: 处理变量声明" << std::endl;
|
|
|
|
|
// 检查类型
|
|
|
|
|
if (varDecl->bType() && varDecl->bType()->Int()) {
|
|
|
|
|
for (auto* varDef : varDecl->varDef()) {
|
|
|
|
|
@ -48,6 +50,7 @@ std::any IRGenImpl::visitDecl(SysYParser::DeclContext* ctx) {
|
|
|
|
|
|
|
|
|
|
// 处理 constDecl
|
|
|
|
|
if (ctx->constDecl()) {
|
|
|
|
|
std::cerr << "[DEBUG] visitDecl: 处理常量声明" << std::endl;
|
|
|
|
|
auto* constDecl = ctx->constDecl();
|
|
|
|
|
|
|
|
|
|
if (constDecl->bType() && constDecl->bType()->Int()) {
|
|
|
|
|
@ -60,11 +63,13 @@ std::any IRGenImpl::visitDecl(SysYParser::DeclContext* ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "未知的常量类型"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
std::cerr << "[DEBUG] visitDecl: 声明处理完成" << std::endl;
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 在 IRGenDecl.cpp 中确保有这个函数
|
|
|
|
|
std::any IRGenImpl::visitConstDecl(SysYParser::ConstDeclContext* ctx) {
|
|
|
|
|
std::cerr << "[DEBUG] visitConstDecl: 开始处理常量声明" << std::endl;
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法常量声明"));
|
|
|
|
|
}
|
|
|
|
|
@ -90,10 +95,10 @@ std::any IRGenImpl::visitConstDecl(SysYParser::ConstDeclContext* ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "常量声明缺少类型"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::cerr << "[DEBUG] visitConstDecl: 常量声明处理完成" << std::endl;
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 修改 visitConstDef 函数,正确处理数组大小
|
|
|
|
|
std::any IRGenImpl::visitConstDef(SysYParser::ConstDefContext* ctx) {
|
|
|
|
|
if (!ctx || !ctx->Ident()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法常量定义"));
|
|
|
|
|
@ -106,147 +111,103 @@ std::any IRGenImpl::visitConstDef(SysYParser::ConstDefContext* ctx) {
|
|
|
|
|
bool is_array = !ctx->constExp().empty();
|
|
|
|
|
|
|
|
|
|
if (is_array) {
|
|
|
|
|
// 数组常量处理
|
|
|
|
|
// 数组常量处理 - 创建全局常量数组
|
|
|
|
|
std::cerr << "[DEBUG] visitConstDef: array constant " << const_name << std::endl;
|
|
|
|
|
|
|
|
|
|
// 获取数组维度
|
|
|
|
|
int array_size = 0;
|
|
|
|
|
|
|
|
|
|
if (!ctx->constExp().empty()) {
|
|
|
|
|
// 尝试获取数组大小
|
|
|
|
|
try {
|
|
|
|
|
// 使用辅助函数获取整数值
|
|
|
|
|
array_size = TryEvaluateConstInt(ctx->constExp()[0]);
|
|
|
|
|
if (array_size <= 0) {
|
|
|
|
|
// 如果获取失败,使用默认值10
|
|
|
|
|
array_size = 10;
|
|
|
|
|
}
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
// 注意:这里错误信息应该是 visitConstDef,不是 visitVarDef
|
|
|
|
|
std::cerr << "[WARNING] visitConstDef: 无法获取数组大小: " << e.what()
|
|
|
|
|
<< ",使用默认值10" << std::endl;
|
|
|
|
|
array_size = 10;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (array_size <= 0) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "常量数组大小必须为正数"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (array_size > 1000) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "常量数组大小太大"));
|
|
|
|
|
std::vector<int> dimensions;
|
|
|
|
|
for (auto* const_exp : ctx->constExp()) {
|
|
|
|
|
int dim_size = TryEvaluateConstInt(const_exp);
|
|
|
|
|
if (dim_size <= 0) dim_size = 1;
|
|
|
|
|
dimensions.push_back(dim_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 分配数组存储
|
|
|
|
|
std::vector<ir::Value*> element_slots;
|
|
|
|
|
for (int i = 0; i < array_size; i++) {
|
|
|
|
|
auto* slot = builder_.CreateAllocaI32(
|
|
|
|
|
module_.GetContext().NextTemp() + "_" + const_name + "_" + std::to_string(i));
|
|
|
|
|
element_slots.push_back(slot);
|
|
|
|
|
}
|
|
|
|
|
// 创建数组类型
|
|
|
|
|
auto array_type = ir::Type::GetArrayType(ir::Type::GetInt32Type(), dimensions);
|
|
|
|
|
ir::GlobalValue* global_array = module_.CreateGlobal(const_name, array_type);
|
|
|
|
|
|
|
|
|
|
// 处理初始化
|
|
|
|
|
// 处理初始化值
|
|
|
|
|
std::vector<ir::ConstantValue*> init_consts;
|
|
|
|
|
if (auto* const_init_val = ctx->constInitVal()) {
|
|
|
|
|
// 获取初始化值
|
|
|
|
|
auto result = const_init_val->accept(this);
|
|
|
|
|
|
|
|
|
|
if (result.has_value()) {
|
|
|
|
|
try {
|
|
|
|
|
std::vector<ir::Value*> init_values =
|
|
|
|
|
std::any_cast<std::vector<ir::Value*>>(result);
|
|
|
|
|
|
|
|
|
|
// 检查初始化值数量
|
|
|
|
|
if (init_values.size() > static_cast<size_t>(array_size)) {
|
|
|
|
|
throw std::runtime_error(
|
|
|
|
|
FormatError("irgen", "常量数组初始化值太多,数组大小为" + std::to_string(array_size) +
|
|
|
|
|
",但提供了" + std::to_string(init_values.size()) + "个值"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 使用初始化值初始化数组元素
|
|
|
|
|
for (size_t i = 0; i < init_values.size(); i++) {
|
|
|
|
|
builder_.CreateStore(init_values[i], element_slots[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 剩余元素初始化为0
|
|
|
|
|
for (size_t i = init_values.size(); i < static_cast<size_t>(array_size); i++) {
|
|
|
|
|
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
|
|
|
|
|
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);
|
|
|
|
|
} else {
|
|
|
|
|
init_consts.push_back(builder_.CreateConstInt(0));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (const std::bad_any_cast&) {
|
|
|
|
|
// 可能返回的是单个值
|
|
|
|
|
try {
|
|
|
|
|
ir::Value* single_value = std::any_cast<ir::Value*>(result);
|
|
|
|
|
// 只初始化第一个元素
|
|
|
|
|
builder_.CreateStore(single_value, element_slots[0]);
|
|
|
|
|
|
|
|
|
|
// 其他元素初始化为0
|
|
|
|
|
for (int i = 1; i < array_size; i++) {
|
|
|
|
|
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
|
|
|
|
|
}
|
|
|
|
|
} catch (const std::bad_any_cast&) {
|
|
|
|
|
std::cerr << "[ERROR] visitConstDef: 无法解析常量数组初始化值类型" << std::endl;
|
|
|
|
|
// 全部初始化为0
|
|
|
|
|
for (int i = 0; i < array_size; i++) {
|
|
|
|
|
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 没有初始化值,全部初始化为0
|
|
|
|
|
for (int i = 0; i < array_size; i++) {
|
|
|
|
|
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
|
|
|
|
|
} catch (...) {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 常量数组缺少初始值
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "常量数组缺少初始值"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 存储第一个元素的地址到 const_storage_map_
|
|
|
|
|
const_storage_map_[ctx] = element_slots[0];
|
|
|
|
|
// 补0
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
global_array->SetInitializer(init_consts);
|
|
|
|
|
global_array->SetConstant(true);
|
|
|
|
|
|
|
|
|
|
// 存储到常量映射(而不是storage_map_)
|
|
|
|
|
const_storage_map_[ctx] = global_array;
|
|
|
|
|
const_global_map_[const_name] = global_array;
|
|
|
|
|
|
|
|
|
|
std::cerr << "[DEBUG] visitConstDef: 创建常量数组 " << const_name
|
|
|
|
|
<< ",大小 " << array_size << std::endl;
|
|
|
|
|
} 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();
|
|
|
|
|
auto result = const_init_val->accept(this);
|
|
|
|
|
|
|
|
|
|
if (result.has_value()) {
|
|
|
|
|
try {
|
|
|
|
|
ir::Value* const_value = std::any_cast<ir::Value*>(result);
|
|
|
|
|
std::cerr << "[DEBUG] visitConstDef: scalar constant " << const_name
|
|
|
|
|
<< " with value " << (void*)const_value << std::endl;
|
|
|
|
|
|
|
|
|
|
// 标量常量也需要存储槽位,以便后续引用
|
|
|
|
|
auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp() + "_" + const_name);
|
|
|
|
|
const_storage_map_[ctx] = slot;
|
|
|
|
|
builder_.CreateStore(const_value, slot);
|
|
|
|
|
|
|
|
|
|
return {};
|
|
|
|
|
} catch (const std::bad_any_cast& e) {
|
|
|
|
|
std::cerr << "[ERROR] visitConstDef: bad any_cast for scalar constant " << const_name << ": " << e.what() << std::endl;
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "标量常量初始化值类型错误"));
|
|
|
|
|
}
|
|
|
|
|
// 关键修改:直接求值常量表达式,不使用 builder_
|
|
|
|
|
ir::ConstantValue* const_value = nullptr;
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
} else {
|
|
|
|
|
const_value = module_.GetContext().GetConstInt(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果求值失败,使用默认值0
|
|
|
|
|
ir::Value* default_value = builder_.CreateConstInt(0);
|
|
|
|
|
auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp() + "_" + const_name);
|
|
|
|
|
const_storage_map_[ctx] = slot;
|
|
|
|
|
builder_.CreateStore(default_value, slot);
|
|
|
|
|
// 存储常量值到映射
|
|
|
|
|
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 {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TO DO:visitVarDef来区分全局和局部变量,并且正确处理数组变量的定义和初始化
|
|
|
|
|
std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) {
|
|
|
|
|
std::cerr << "[DEBUG] visitVarDef: 开始处理变量定义" << std::endl;
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "缺少变量定义"));
|
|
|
|
|
}
|
|
|
|
|
@ -256,91 +217,258 @@ std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string varName = ctx->Ident()->getText();
|
|
|
|
|
std::cerr << "[DEBUG] visitVarDef: 变量名称: " << varName << std::endl;
|
|
|
|
|
// 防止同一个变量被多次分配存储空间。
|
|
|
|
|
if (storage_map_.find(ctx) != storage_map_.end()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "声明重复生成存储槽位: " + varName));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool is_array = !ctx->constExp().empty();
|
|
|
|
|
std::cerr << "[DEBUG] visitVarDef: 是否为数组: " << (is_array ? "是" : "否") << std::endl;
|
|
|
|
|
|
|
|
|
|
// 使用 func_ 来判断:func_ == nullptr 表示在全局作用域
|
|
|
|
|
if (func_ == nullptr) {
|
|
|
|
|
std::cerr << "[DEBUG] visitVarDef: 处理全局变量" << std::endl;
|
|
|
|
|
// 全局变量处理
|
|
|
|
|
return HandleGlobalVariable(ctx, varName, is_array);
|
|
|
|
|
} else {
|
|
|
|
|
std::cerr << "[DEBUG] visitVarDef: 处理局部变量" << std::endl;
|
|
|
|
|
// 局部变量处理
|
|
|
|
|
return HandleLocalVariable(ctx, varName, is_array);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::HandleGlobalVariable(SysYParser::VarDefContext* ctx,
|
|
|
|
|
const std::string& varName,
|
|
|
|
|
bool is_array) {
|
|
|
|
|
std::cerr << "[DEBUG] HandleGlobalVariable: 开始处理全局变量 " << varName << std::endl;
|
|
|
|
|
if (is_array) {
|
|
|
|
|
// 数组变量
|
|
|
|
|
// 获取数组维度
|
|
|
|
|
std::cerr << "[DEBUG] HandleGlobalVariable: 处理全局数组变量" << std::endl;
|
|
|
|
|
// 全局数组变量
|
|
|
|
|
int total_size = 1;
|
|
|
|
|
std::vector<int> dimensions;
|
|
|
|
|
|
|
|
|
|
// 计算总大小
|
|
|
|
|
for (auto* const_exp : ctx->constExp()) {
|
|
|
|
|
int dim_size = TryEvaluateConstInt(const_exp);
|
|
|
|
|
if (dim_size <= 0) {
|
|
|
|
|
dim_size = 1;
|
|
|
|
|
std::cerr << "[WARNING] HandleGlobalVariable: 无法确定数组维度大小,使用1" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
dimensions.push_back(dim_size);
|
|
|
|
|
total_size *= dim_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::cerr << "[DEBUG] HandleGlobalVariable: 数组总大小: " << total_size << std::endl;
|
|
|
|
|
|
|
|
|
|
if (total_size <= 0 || total_size > 10000) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "全局数组大小无效"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建数组类型的全局变量
|
|
|
|
|
auto array_type = ir::Type::GetArrayType(ir::Type::GetInt32Type(), dimensions);
|
|
|
|
|
ir::GlobalValue* global_array = module_.CreateGlobal(varName, array_type);
|
|
|
|
|
std::cerr << "[DEBUG] HandleGlobalVariable: 创建全局数组: " << varName << std::endl;
|
|
|
|
|
|
|
|
|
|
// 处理初始化值
|
|
|
|
|
std::vector<ir::ConstantValue*> init_consts;
|
|
|
|
|
if (auto* initVal = ctx->initVal()) {
|
|
|
|
|
std::cerr << "[DEBUG] HandleGlobalVariable: 处理初始化值" << std::endl;
|
|
|
|
|
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 {
|
|
|
|
|
// 非常量表达式,使用0
|
|
|
|
|
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 {
|
|
|
|
|
init_consts.push_back(builder_.CreateConstInt(0));
|
|
|
|
|
}
|
|
|
|
|
} catch (const std::bad_any_cast&) {
|
|
|
|
|
std::cerr << "[WARNING] HandleGlobalVariable: 无法解析数组初始化值" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果初始化值不足,补0
|
|
|
|
|
while (init_consts.size() < static_cast<size_t>(total_size)) {
|
|
|
|
|
init_consts.push_back(builder_.CreateConstInt(0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置全局数组的初始化器
|
|
|
|
|
if (!init_consts.empty()) {
|
|
|
|
|
global_array->SetInitializer(init_consts);
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
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::cerr << "[DEBUG] HandleGlobalVariable: 创建全局标量变量: " << varName << std::endl;
|
|
|
|
|
|
|
|
|
|
// 处理初始化值
|
|
|
|
|
ir::ConstantValue* init_value = nullptr;
|
|
|
|
|
if (auto* initVal = ctx->initVal()) {
|
|
|
|
|
std::cerr << "[DEBUG] HandleGlobalVariable: 处理标量初始化值" << std::endl;
|
|
|
|
|
auto result = initVal->accept(this);
|
|
|
|
|
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;
|
|
|
|
|
} else {
|
|
|
|
|
// 默认初始化为0
|
|
|
|
|
init_value = builder_.CreateConstInt(0);
|
|
|
|
|
std::cerr << "[DEBUG] HandleGlobalVariable: 使用默认初始化值0" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
} catch (const std::bad_any_cast&) {
|
|
|
|
|
init_value = builder_.CreateConstInt(0);
|
|
|
|
|
std::cerr << "[DEBUG] HandleGlobalVariable: 类型转换失败,使用默认初始化值0" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
} 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置全局变量的初始化器
|
|
|
|
|
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 {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 计算所有维度
|
|
|
|
|
std::any IRGenImpl::HandleLocalVariable(SysYParser::VarDefContext* ctx,
|
|
|
|
|
const std::string& varName,
|
|
|
|
|
bool is_array) {
|
|
|
|
|
std::cerr << "[DEBUG] HandleLocalVariable: 开始处理局部变量 " << varName << 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] visitVarDef: 无法确定数组维度大小,使用1" << std::endl;
|
|
|
|
|
std::cerr << "[WARNING] HandleLocalVariable: 无法确定数组维度大小,使用1" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
dimensions.push_back(dim_size);
|
|
|
|
|
total_size *= dim_size;
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
std::cerr << "[WARNING] visitVarDef: 无法获取数组维度: " << e.what()
|
|
|
|
|
std::cerr << "[WARNING] HandleLocalVariable: 无法获取数组维度: " << e.what()
|
|
|
|
|
<< ",使用维度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 > 1000) {
|
|
|
|
|
|
|
|
|
|
if (total_size > 10000) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "数组大小太大"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 分配数组存储
|
|
|
|
|
|
|
|
|
|
// 分配数组存储 - 为每个元素创建独立的 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));
|
|
|
|
|
element_slots.push_back(slot);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 处理初始化
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
// 检查初始化值数量
|
|
|
|
|
if (init_values.size() > static_cast<size_t>(total_size)) {
|
|
|
|
|
// 对于多维数组,这可能是正常的
|
|
|
|
|
// 我们打印警告但继续执行
|
|
|
|
|
std::cerr << "[WARNING] visitVarDef: 初始化值(" << init_values.size()
|
|
|
|
|
<< ")超过数组总大小(" << total_size
|
|
|
|
|
<< "),只初始化前" << total_size << "个元素" << std::endl;
|
|
|
|
|
|
|
|
|
|
// 只初始化能容纳的部分
|
|
|
|
|
for (size_t i = 0; i < static_cast<size_t>(total_size); i++) {
|
|
|
|
|
builder_.CreateStore(init_values[i], element_slots[i]);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 正常初始化
|
|
|
|
|
for (size_t i = 0; i < init_values.size(); i++) {
|
|
|
|
|
builder_.CreateStore(init_values[i], element_slots[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 剩余元素初始化为0
|
|
|
|
|
for (size_t i = init_values.size(); i < static_cast<size_t>(total_size); i++) {
|
|
|
|
|
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
|
|
|
|
|
}
|
|
|
|
|
// 初始化数组元素
|
|
|
|
|
for (size_t i = 0; i < init_values.size() && i < static_cast<size_t>(total_size); i++) {
|
|
|
|
|
builder_.CreateStore(init_values[i], element_slots[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 剩余元素初始化为0
|
|
|
|
|
for (size_t i = init_values.size(); i < static_cast<size_t>(total_size); i++) {
|
|
|
|
|
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]);
|
|
|
|
|
|
|
|
|
|
@ -349,7 +477,7 @@ std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) {
|
|
|
|
|
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
|
|
|
|
|
}
|
|
|
|
|
} catch (const std::bad_any_cast&) {
|
|
|
|
|
std::cerr << "[ERROR] visitVarDef: 无法解析数组初始化值类型" << std::endl;
|
|
|
|
|
std::cerr << "[ERROR] HandleLocalVariable: 无法解析数组初始化值类型" << std::endl;
|
|
|
|
|
// 全部初始化为0
|
|
|
|
|
for (int i = 0; i < total_size; i++) {
|
|
|
|
|
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
|
|
|
|
|
@ -357,45 +485,56 @@ std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
std::cerr << "[DEBUG] HandleLocalVariable: 无初始化值结果" << std::endl;
|
|
|
|
|
// 没有初始化值,全部初始化为0
|
|
|
|
|
for (int i = 0; i < total_size; i++) {
|
|
|
|
|
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]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 存储第一个元素的地址
|
|
|
|
|
|
|
|
|
|
// 存储第一个元素的地址作为数组的基地址
|
|
|
|
|
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] visitVarDef: 创建数组 " << varName
|
|
|
|
|
|
|
|
|
|
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 {
|
|
|
|
|
// 标量变量
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
std::cerr << "[DEBUG] HandleLocalVariable: 处理局部标量变量" << std::endl;
|
|
|
|
|
// 局部标量变量
|
|
|
|
|
auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp() + "_" + varName);
|
|
|
|
|
storage_map_[ctx] = slot;
|
|
|
|
|
local_var_map_[varName] = slot; // 添加到局部变量映射
|
|
|
|
|
std::cerr << "[DEBUG] HandleLocalVariable: 创建局部标量变量存储槽" << std::endl;
|
|
|
|
|
|
|
|
|
|
// 处理初始化
|
|
|
|
|
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 {
|
|
|
|
|
@ -403,49 +542,60 @@ std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) {
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
} catch (const std::bad_any_cast&) {
|
|
|
|
|
init = builder_.CreateConstInt(0);
|
|
|
|
|
std::cerr << "[DEBUG] HandleLocalVariable: 无法解析初始化值类型,使用0" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
init = builder_.CreateConstInt(0);
|
|
|
|
|
std::cerr << "[DEBUG] HandleLocalVariable: 无初始化值结果,使用0" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
init = builder_.CreateConstInt(0);
|
|
|
|
|
std::cerr << "[DEBUG] HandleLocalVariable: 无初始化值,使用0" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
builder_.CreateStore(init, slot);
|
|
|
|
|
std::cerr << "[DEBUG] visitVarDef: 创建标量变量 " << varName
|
|
|
|
|
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) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法初始化值"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果是单个表达式
|
|
|
|
|
if (ctx->exp()) {
|
|
|
|
|
std::cerr << "[DEBUG] visitInitVal: 处理表达式初始化" << std::endl;
|
|
|
|
|
return EvalExpr(*ctx->exp());
|
|
|
|
|
}
|
|
|
|
|
// 如果是聚合初始化(花括号列表)
|
|
|
|
|
else if (!ctx->initVal().empty()) {
|
|
|
|
|
std::cerr << "[DEBUG] visitInitVal: 处理聚合初始化" << std::endl;
|
|
|
|
|
// 处理嵌套聚合初始化
|
|
|
|
|
return ProcessNestedInitVals(ctx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::cerr << "[DEBUG] visitInitVal: 空初始化列表" << std::endl;
|
|
|
|
|
// 空初始化列表
|
|
|
|
|
return std::vector<ir::Value*>{};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 新增:处理嵌套聚合初始化的辅助函数
|
|
|
|
|
std::vector<ir::Value*> IRGenImpl::ProcessNestedInitVals(SysYParser::InitValContext* ctx) {
|
|
|
|
|
std::cerr << "[DEBUG] ProcessNestedInitVals: 开始处理嵌套初始化值" << std::endl;
|
|
|
|
|
std::vector<ir::Value*> all_values;
|
|
|
|
|
|
|
|
|
|
for (auto* init_val : ctx->initVal()) {
|
|
|
|
|
@ -455,54 +605,163 @@ std::vector<ir::Value*> IRGenImpl::ProcessNestedInitVals(SysYParser::InitValCont
|
|
|
|
|
// 尝试获取单个值
|
|
|
|
|
ir::Value* value = std::any_cast<ir::Value*>(result);
|
|
|
|
|
all_values.push_back(value);
|
|
|
|
|
std::cerr << "[DEBUG] ProcessNestedInitVals: 获取到单个值" << std::endl;
|
|
|
|
|
} catch (const std::bad_any_cast&) {
|
|
|
|
|
try {
|
|
|
|
|
// 尝试获取值列表(嵌套情况)
|
|
|
|
|
std::vector<ir::Value*> nested_values =
|
|
|
|
|
std::any_cast<std::vector<ir::Value*>>(result);
|
|
|
|
|
std::cerr << "[DEBUG] ProcessNestedInitVals: 获取到嵌套值列表, 大小: " << nested_values.size() << std::endl;
|
|
|
|
|
// 展平嵌套的值
|
|
|
|
|
all_values.insert(all_values.end(),
|
|
|
|
|
nested_values.begin(), nested_values.end());
|
|
|
|
|
} catch (const std::bad_any_cast&) {
|
|
|
|
|
// 未知类型
|
|
|
|
|
std::cerr << "[ERROR] ProcessNestedInitVals: 不支持的初始化值类型" << std::endl;
|
|
|
|
|
throw std::runtime_error(
|
|
|
|
|
FormatError("irgen", "不支持的初始化值类型"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
std::cerr << "[DEBUG] ProcessNestedInitVals: 无初始化值结果" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::cerr << "[DEBUG] ProcessNestedInitVals: 共获取 " << all_values.size() << " 个初始化值" << std::endl;
|
|
|
|
|
return all_values;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int IRGenImpl::TryEvaluateConstInt(SysYParser::ConstExpContext* ctx) {
|
|
|
|
|
std::cerr << "[DEBUG] TryEvaluateConstInt: 开始求值常量表达式" << std::endl;
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
std::cerr << "[DEBUG] TryEvaluateConstInt: ctx is null" << std::endl;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
auto result = ctx->accept(this);
|
|
|
|
|
if (result.has_value()) {
|
|
|
|
|
try {
|
|
|
|
|
ir::Value* value = std::any_cast<ir::Value*>(result);
|
|
|
|
|
std::cerr << "[DEBUG] TryEvaluateConstInt: got IR value " << (void*)value << std::endl;
|
|
|
|
|
|
|
|
|
|
// 尝试获取整数常量
|
|
|
|
|
// 简化:检查是否是 ConstantInt
|
|
|
|
|
// 这里需要 IR 库的支持,暂时返回一个测试值
|
|
|
|
|
return 16; // 暂时返回测试值
|
|
|
|
|
} catch (const std::bad_any_cast& e) {
|
|
|
|
|
std::cerr << "[DEBUG] TryEvaluateConstInt: bad any_cast: " << e.what() << std::endl;
|
|
|
|
|
return 0;
|
|
|
|
|
// 直接访问常量表达式树,计算数值
|
|
|
|
|
// 这里需要实现真正的常量求值逻辑
|
|
|
|
|
// 简化版本:假设常量表达式是整数常量
|
|
|
|
|
|
|
|
|
|
if (ctx->addExp()) {
|
|
|
|
|
// 尝试从 addExp 求值
|
|
|
|
|
return EvaluateConstAddExp(ctx->addExp());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 添加辅助函数来求值常量表达式
|
|
|
|
|
int IRGenImpl::EvaluateConstAddExp(SysYParser::AddExpContext* ctx) {
|
|
|
|
|
if (!ctx) return 0;
|
|
|
|
|
|
|
|
|
|
// 如果没有左操作数,直接求值右操作数
|
|
|
|
|
if (!ctx->addExp()) {
|
|
|
|
|
return EvaluateConstMulExp(ctx->mulExp());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int left = EvaluateConstAddExp(ctx->addExp());
|
|
|
|
|
int right = EvaluateConstMulExp(ctx->mulExp());
|
|
|
|
|
|
|
|
|
|
if (ctx->AddOp()) {
|
|
|
|
|
return left + right;
|
|
|
|
|
} else if (ctx->SubOp()) {
|
|
|
|
|
return left - right;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int IRGenImpl::EvaluateConstMulExp(SysYParser::MulExpContext* ctx) {
|
|
|
|
|
if (!ctx) return 0;
|
|
|
|
|
|
|
|
|
|
// 如果没有左操作数,直接求值右操作数
|
|
|
|
|
if (!ctx->mulExp()) {
|
|
|
|
|
return EvaluateConstUnaryExp(ctx->unaryExp());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int left = EvaluateConstMulExp(ctx->mulExp());
|
|
|
|
|
int right = EvaluateConstUnaryExp(ctx->unaryExp());
|
|
|
|
|
|
|
|
|
|
if (ctx->MulOp()) {
|
|
|
|
|
return left * right;
|
|
|
|
|
} else if (ctx->DivOp()) {
|
|
|
|
|
return left / right;
|
|
|
|
|
} else if (ctx->QuoOp()) {
|
|
|
|
|
return left % right;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int IRGenImpl::EvaluateConstUnaryExp(SysYParser::UnaryExpContext* ctx) {
|
|
|
|
|
if (!ctx) return 0;
|
|
|
|
|
|
|
|
|
|
// 基本表达式(数字字面量)
|
|
|
|
|
if (ctx->primaryExp()) {
|
|
|
|
|
return EvaluateConstPrimaryExp(ctx->primaryExp());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 一元运算
|
|
|
|
|
if (ctx->unaryOp() && ctx->unaryExp()) {
|
|
|
|
|
int operand = EvaluateConstUnaryExp(ctx->unaryExp());
|
|
|
|
|
std::string op = ctx->unaryOp()->getText();
|
|
|
|
|
|
|
|
|
|
if (op == "+") {
|
|
|
|
|
return operand;
|
|
|
|
|
} else if (op == "-") {
|
|
|
|
|
return -operand;
|
|
|
|
|
} else if (op == "!") {
|
|
|
|
|
return !operand;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int IRGenImpl::EvaluateConstPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
|
|
|
|
|
if (!ctx) return 0;
|
|
|
|
|
|
|
|
|
|
// 处理数字字面量
|
|
|
|
|
if (ctx->DECIMAL_INT()) {
|
|
|
|
|
return std::stoi(ctx->DECIMAL_INT()->getText());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ctx->HEX_INT()) {
|
|
|
|
|
std::string hex = ctx->HEX_INT()->getText();
|
|
|
|
|
return std::stoi(hex, nullptr, 16);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ctx->OCTAL_INT()) {
|
|
|
|
|
std::string oct = ctx->OCTAL_INT()->getText();
|
|
|
|
|
return std::stoi(oct, nullptr, 8);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ctx->ZERO()) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理括号表达式
|
|
|
|
|
if (ctx->L_PAREN() && ctx->exp()) {
|
|
|
|
|
return EvaluateConstExp(ctx->exp());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 常量标识符(引用其他常量)
|
|
|
|
|
if (ctx->lVal()) {
|
|
|
|
|
std::string const_name = ctx->lVal()->Ident()->getText();
|
|
|
|
|
auto it = const_value_map_.find(const_name);
|
|
|
|
|
if (it != const_value_map_.end()) {
|
|
|
|
|
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(it->second)) {
|
|
|
|
|
return const_int->GetValue();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
std::cerr << "[DEBUG] TryEvaluateConstInt: result has no value" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
std::cerr << "[DEBUG] TryEvaluateConstInt: exception: " << e.what() << std::endl;
|
|
|
|
|
// 也可以从语义分析获取常量值
|
|
|
|
|
// ...
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::cerr << "[DEBUG] TryEvaluateConstInt: returning default value 10" << std::endl;
|
|
|
|
|
return 10; // 默认值
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int IRGenImpl::EvaluateConstExp(SysYParser::ExpContext* ctx) {
|
|
|
|
|
if (!ctx || !ctx->addExp()) return 0;
|
|
|
|
|
return EvaluateConstAddExp(ctx->addExp());
|
|
|
|
|
}
|