|
|
|
|
@ -21,84 +21,96 @@
|
|
|
|
|
// - 条件与比较表达式
|
|
|
|
|
// - ...
|
|
|
|
|
|
|
|
|
|
// 表达式生成
|
|
|
|
|
ir::Value* IRGenImpl::EvalExpr(SysYParser::ExpContext& expr) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] EvalExpr: 开始处理表达式 " << expr.getText());
|
|
|
|
|
std::cout << "[DEBUG IRGEN] EvalExpr: " << expr.getText() << std::endl;
|
|
|
|
|
try {
|
|
|
|
|
auto result_any = expr.accept(this);
|
|
|
|
|
|
|
|
|
|
if (!result_any.has_value()) {
|
|
|
|
|
DEBUG_MSG("[ERROR] EvalExpr: result_any has no value");
|
|
|
|
|
std::cerr << "[ERROR] EvalExpr: result_any has no value" << std::endl;
|
|
|
|
|
throw std::runtime_error("表达式求值结果为空");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
ir::Value* result = std::any_cast<ir::Value*>(result_any);
|
|
|
|
|
DEBUG_MSG("[DEBUG] EvalExpr: success, result = " << (void*)result);
|
|
|
|
|
std::cerr << "[DEBUG] EvalExpr: success, result = " << (void*)result << std::endl;
|
|
|
|
|
return result;
|
|
|
|
|
} catch (const std::bad_any_cast& e) {
|
|
|
|
|
DEBUG_MSG("[ERROR] EvalExpr: bad any_cast - " << e.what());
|
|
|
|
|
DEBUG_MSG(" Type info: " << result_any.type().name());
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "表达式求值返回了错误的类型"));
|
|
|
|
|
std::cerr << "[ERROR] EvalExpr: bad any_cast - " << e.what() << std::endl;
|
|
|
|
|
std::cerr << " Type info: " << result_any.type().name() << std::endl;
|
|
|
|
|
|
|
|
|
|
// 尝试其他可能的类型
|
|
|
|
|
try {
|
|
|
|
|
// 检查是否是无值的any(可能来自visit函数返回{})
|
|
|
|
|
std::cerr << "[DEBUG] EvalExpr: Trying to handle empty any" << std::endl;
|
|
|
|
|
return nullptr;
|
|
|
|
|
} catch (...) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "表达式求值返回了错误的类型"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
DEBUG_MSG("[ERROR] Exception in EvalExpr: " << e.what());
|
|
|
|
|
std::cerr << "[ERROR] Exception in EvalExpr: " << e.what() << std::endl;
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ir::Value* IRGenImpl::EvalCond(SysYParser::CondContext& cond) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] EvalCond: 开始处理条件表达式 " << cond.getText());
|
|
|
|
|
return std::any_cast<ir::Value*>(cond.accept(this));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 基本表达式:数字、变量、括号表达式
|
|
|
|
|
std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitPrimaryExp: 开始处理基本表达式 " << (ctx ? ctx->getText() : "<null>"));
|
|
|
|
|
std::cout << "[DEBUG IRGEN] visitPrimaryExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "缺少基本表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DEBUG_MSG("[DEBUG] visitPrimaryExp");
|
|
|
|
|
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);
|
|
|
|
|
DEBUG_MSG("[DEBUG] visitPrimaryExp: constant int " << value
|
|
|
|
|
<< " created as " << (void*)const_int);
|
|
|
|
|
std::cerr << "[DEBUG] visitPrimaryExp: constant int " << value
|
|
|
|
|
<< " created as " << (void*)const_int << std::endl;
|
|
|
|
|
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) {
|
|
|
|
|
DEBUG_MSG("[WARNING] 无法解析十六进制浮点数: " << hex_float_str
|
|
|
|
|
<< ",使用0.0代替");
|
|
|
|
|
std::cerr << "[WARNING] 无法解析十六进制浮点数: " << hex_float_str
|
|
|
|
|
<< ",使用0.0代替" << std::endl;
|
|
|
|
|
value = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
ir::Value* const_float = builder_.CreateConstFloat(value);
|
|
|
|
|
DEBUG_MSG("[DEBUG] visitPrimaryExp: constant hex float " << value
|
|
|
|
|
<< " created as " << (void*)const_float);
|
|
|
|
|
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) {
|
|
|
|
|
DEBUG_MSG("[WARNING] 无法解析十进制浮点数: " << dec_float_str
|
|
|
|
|
<< ",使用0.0代替");
|
|
|
|
|
std::cerr << "[WARNING] 无法解析十进制浮点数: " << dec_float_str
|
|
|
|
|
<< ",使用0.0代替" << std::endl;
|
|
|
|
|
value = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
ir::Value* const_float = builder_.CreateConstFloat(value);
|
|
|
|
|
DEBUG_MSG("[DEBUG] visitPrimaryExp: constant dec float " << value
|
|
|
|
|
<< " created as " << (void*)const_float);
|
|
|
|
|
std::cerr << "[DEBUG] visitPrimaryExp: constant dec float " << value
|
|
|
|
|
<< " created as " << (void*)const_float << std::endl;
|
|
|
|
|
return static_cast<ir::Value*>(const_float);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -106,8 +118,6 @@ std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
|
|
|
|
|
std::string hex = ctx->HEX_INT()->getText();
|
|
|
|
|
int value = std::stoi(hex, nullptr, 16);
|
|
|
|
|
ir::Value* const_int = builder_.CreateConstInt(value);
|
|
|
|
|
DEBUG_MSG("[DEBUG] visitPrimaryExp: constant hex int " << value
|
|
|
|
|
<< " created as " << (void*)const_int);
|
|
|
|
|
return static_cast<ir::Value*>(const_int);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -115,132 +125,79 @@ std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
|
|
|
|
|
std::string oct = ctx->OCTAL_INT()->getText();
|
|
|
|
|
int value = std::stoi(oct, nullptr, 8);
|
|
|
|
|
ir::Value* const_int = builder_.CreateConstInt(value);
|
|
|
|
|
DEBUG_MSG("[DEBUG] visitPrimaryExp: constant octal int " << value
|
|
|
|
|
<< " created as " << (void*)const_int);
|
|
|
|
|
return static_cast<ir::Value*>(const_int);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ctx->ZERO()) {
|
|
|
|
|
ir::Value* const_int = builder_.CreateConstInt(0);
|
|
|
|
|
DEBUG_MSG("[DEBUG] visitPrimaryExp: constant zero int created");
|
|
|
|
|
return static_cast<ir::Value*>(const_int);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理变量
|
|
|
|
|
if (ctx->lVal()) {
|
|
|
|
|
DEBUG_MSG("[DEBUG] visitPrimaryExp: visiting lVal");
|
|
|
|
|
std::cerr << "[DEBUG] visitPrimaryExp: visiting lVal" << std::endl;
|
|
|
|
|
return ctx->lVal()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理括号表达式
|
|
|
|
|
if (ctx->L_PAREN() && ctx->exp()) {
|
|
|
|
|
DEBUG_MSG("[DEBUG] visitPrimaryExp: visiting parenthesized expression");
|
|
|
|
|
std::cerr << "[DEBUG] visitPrimaryExp: visiting parenthesized expression" << std::endl;
|
|
|
|
|
return EvalExpr(*ctx->exp());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DEBUG_MSG("[ERROR] visitPrimaryExp: unsupported primary expression type");
|
|
|
|
|
std::cerr << "[ERROR] visitPrimaryExp: unsupported primary expression type" << std::endl;
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "不支持的基本表达式类型"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 左值(变量)处理
|
|
|
|
|
// 1. 先通过语义分析结果把变量使用绑定回声明;
|
|
|
|
|
// 2. 再通过 storage_map_ 找到该声明对应的栈槽位;
|
|
|
|
|
// 3. 最后生成 load,把内存中的值读出来。
|
|
|
|
|
std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitLVal: 开始处理左值 " << (ctx ? ctx->getText() : "<null>"));
|
|
|
|
|
if (!ctx || !ctx->Ident()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法左值"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string varName = ctx->Ident()->getText();
|
|
|
|
|
DEBUG_MSG("[DEBUG] visitLVal: " << varName);
|
|
|
|
|
|
|
|
|
|
// 先检查语义分析中常量绑定
|
|
|
|
|
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) {
|
|
|
|
|
DEBUG_MSG("[DEBUG] visitLVal: 找到常量 " << varName);
|
|
|
|
|
|
|
|
|
|
if (sym->IsScalarConstant()) {
|
|
|
|
|
if (sym->type->IsInt32()) {
|
|
|
|
|
ir::ConstantValue* const_val = builder_.CreateConstInt(sym->GetIntConstant());
|
|
|
|
|
return static_cast<ir::Value*>(const_val);
|
|
|
|
|
} else if (sym->type->IsFloat()) {
|
|
|
|
|
ir::ConstantValue* const_val = builder_.CreateConstFloat(sym->GetFloatConstant());
|
|
|
|
|
return static_cast<ir::Value*>(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<ir::ArrayType*>(sym->type.get());
|
|
|
|
|
if (!array_ty) {
|
|
|
|
|
// 无法获取数组类型,退回返回全局对象
|
|
|
|
|
return static_cast<ir::Value*>(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<int> 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<ir::ConstantInt*>(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<size_t>(flat));
|
|
|
|
|
return static_cast<ir::Value*>(elem);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 部分索引:返回指针(不做 Load),由上层按需处理
|
|
|
|
|
std::vector<ir::Value*> indices;
|
|
|
|
|
indices.push_back(builder_.CreateConstInt(0));
|
|
|
|
|
for (auto* exp : ctx->exp()) {
|
|
|
|
|
indices.push_back(EvalExpr(*exp));
|
|
|
|
|
}
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateGEP(global_array, indices, module_.GetContext().NextTemp()));
|
|
|
|
|
} else {
|
|
|
|
|
// 无下标,直接返回全局常量对象
|
|
|
|
|
return static_cast<ir::Value*>(global_array);
|
|
|
|
|
}
|
|
|
|
|
std::cerr << "[DEBUG] visitLVal: " << varName << std::endl;
|
|
|
|
|
|
|
|
|
|
// 优先检查是否是常量
|
|
|
|
|
auto const_it = const_value_map_.find(varName);
|
|
|
|
|
if (const_it != const_value_map_.end()) {
|
|
|
|
|
// 常量直接返回值,不需要load
|
|
|
|
|
std::cerr << "[DEBUG] visitLVal: constant " << varName << std::endl;
|
|
|
|
|
return static_cast<ir::Value*>(const_it->second);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查全局常量
|
|
|
|
|
auto const_global_it = const_global_map_.find(varName);
|
|
|
|
|
if (const_global_it != const_global_map_.end()) {
|
|
|
|
|
// 全局常量,需要load
|
|
|
|
|
ir::Value* ptr = const_global_it->second;
|
|
|
|
|
if (!ctx->exp().empty()) {
|
|
|
|
|
// 数组访问
|
|
|
|
|
std::vector<ir::Value*> indices;
|
|
|
|
|
indices.push_back(builder_.CreateConstInt(0));
|
|
|
|
|
for (auto* exp : ctx->exp()) {
|
|
|
|
|
ir::Value* index = EvalExpr(*exp);
|
|
|
|
|
indices.push_back(index);
|
|
|
|
|
}
|
|
|
|
|
ir::Value* elem_ptr = builder_.CreateGEP(
|
|
|
|
|
ptr, indices, module_.GetContext().NextTemp());
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateLoad(elem_ptr, module_.GetContext().NextTemp()));
|
|
|
|
|
} else {
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateLoad(ptr, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 不是常量,按正常变量处理
|
|
|
|
|
// ... 原有的变量查找代码 ...
|
|
|
|
|
|
|
|
|
|
auto* decl = sema_.ResolveVarUse(ctx);
|
|
|
|
|
ir::Value* ptr = nullptr;
|
|
|
|
|
|
|
|
|
|
if (decl) {
|
|
|
|
|
auto it = storage_map_.find(decl);
|
|
|
|
|
if (it != storage_map_.end()) {
|
|
|
|
|
@ -277,124 +234,27 @@ std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
|
|
|
|
|
// 检查是否有数组下标
|
|
|
|
|
bool is_array_access = !ctx->exp().empty();
|
|
|
|
|
if (is_array_access) {
|
|
|
|
|
// 收集下标表达式(不含前导0)
|
|
|
|
|
std::vector<ir::Value*> idx_vals;
|
|
|
|
|
std::vector<ir::Value*> indices;
|
|
|
|
|
indices.push_back(builder_.CreateConstInt(0));
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
indices.push_back(index);
|
|
|
|
|
}
|
|
|
|
|
if (!var_sym) {
|
|
|
|
|
var_sym = symbol_table_.lookupAll(varName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<int> 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<ir::ArrayType*>(var_sym->type.get());
|
|
|
|
|
if (at) dims = at->GetDimensions();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dims.empty() && ptr->GetType()->IsArray()) {
|
|
|
|
|
if (auto* at = dynamic_cast<ir::ArrayType*>(ptr->GetType().get())) {
|
|
|
|
|
dims = at->GetDimensions();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 兜底:从语法树声明提取维度,避免作用域关闭后符号查询不完整。
|
|
|
|
|
if (dims.empty() && const_decl) {
|
|
|
|
|
auto* mutable_const_decl = const_cast<SysYParser::ConstDefContext*>(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<ir::Value*> 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<ir::Value*>(builder_.CreateLoad(elem_ptr, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<ir::Value*> 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<ir::Value*>(builder_.CreateLoad(elem_ptr, module_.GetContext().NextTemp()));
|
|
|
|
|
|
|
|
|
|
ir::Value* elem_ptr = builder_.CreateGEP(
|
|
|
|
|
ptr, indices, module_.GetContext().NextTemp());
|
|
|
|
|
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
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<ir::Value*>(builder_.CreateLoad(ptr, module_.GetContext().NextTemp()));
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateLoad(ptr, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitAddExp: 开始处理加法表达式 " << (ctx ? ctx->getText() : "<null>"));
|
|
|
|
|
std::cout << "[DEBUG IRGEN] visitAddExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法加法表达式"));
|
|
|
|
|
}
|
|
|
|
|
@ -418,10 +278,10 @@ std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
|
|
|
|
|
}
|
|
|
|
|
ir::Value* right = std::any_cast<ir::Value*>(right_any);
|
|
|
|
|
|
|
|
|
|
DEBUG_MSG("[DEBUG] visitAddExp: left=" << (void*)left
|
|
|
|
|
std::cerr << "[DEBUG] visitAddExp: left=" << (void*)left
|
|
|
|
|
<< ", type=" << (left->GetType()->IsFloat() ? "float" : "int")
|
|
|
|
|
<< ", right=" << (void*)right
|
|
|
|
|
<< ", type=" << (right->GetType()->IsFloat() ? "float" : "int"));
|
|
|
|
|
<< ", type=" << (right->GetType()->IsFloat() ? "float" : "int") << std::endl;
|
|
|
|
|
|
|
|
|
|
// 处理类型转换:如果操作数类型不同,需要进行类型转换
|
|
|
|
|
if (left->GetType()->IsFloat() != right->GetType()->IsFloat()) {
|
|
|
|
|
@ -458,7 +318,7 @@ std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitMulExp: 开始处理乘法表达式 " << (ctx ? ctx->getText() : "<null>"));
|
|
|
|
|
std::cout << "[DEBUG IRGEN] visitMulExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法乘法表达式"));
|
|
|
|
|
}
|
|
|
|
|
@ -482,10 +342,10 @@ std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) {
|
|
|
|
|
}
|
|
|
|
|
ir::Value* right = std::any_cast<ir::Value*>(right_any);
|
|
|
|
|
|
|
|
|
|
DEBUG_MSG("[DEBUG] visitMulExp: left=" << (void*)left
|
|
|
|
|
std::cerr << "[DEBUG] visitMulExp: left=" << (void*)left
|
|
|
|
|
<< ", type=" << (left->GetType()->IsFloat() ? "float" : "int")
|
|
|
|
|
<< ", right=" << (void*)right
|
|
|
|
|
<< ", type=" << (right->GetType()->IsFloat() ? "float" : "int"));
|
|
|
|
|
<< ", type=" << (right->GetType()->IsFloat() ? "float" : "int") << std::endl;
|
|
|
|
|
|
|
|
|
|
// 处理类型转换:如果操作数类型不同,需要进行类型转换
|
|
|
|
|
if (left->GetType()->IsFloat() != right->GetType()->IsFloat()) {
|
|
|
|
|
@ -532,7 +392,6 @@ std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) {
|
|
|
|
|
|
|
|
|
|
// 逻辑与
|
|
|
|
|
std::any IRGenImpl::visitLAndExp(SysYParser::LAndExpContext* ctx) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitLAndExp: 开始处理逻辑与表达式 " << (ctx ? ctx->getText() : "<null>"));
|
|
|
|
|
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法逻辑与表达式"));
|
|
|
|
|
|
|
|
|
|
if (!ctx->lAndExp()) {
|
|
|
|
|
@ -541,28 +400,14 @@ std::any IRGenImpl::visitLAndExp(SysYParser::LAndExpContext* ctx) {
|
|
|
|
|
|
|
|
|
|
ir::Value* left = std::any_cast<ir::Value*>(ctx->lAndExp()->accept(this));
|
|
|
|
|
ir::Value* right = std::any_cast<ir::Value*>(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<ir::Value*>(
|
|
|
|
|
builder_.CreateAnd(left_bool, right_bool, module_.GetContext().NextTemp()));
|
|
|
|
|
auto zero = builder_.CreateConstInt(0);
|
|
|
|
|
auto left_bool = builder_.CreateICmpNE(left, zero, module_.GetContext().NextTemp());
|
|
|
|
|
auto right_bool = builder_.CreateICmpNE(right, zero, module_.GetContext().NextTemp());
|
|
|
|
|
return builder_.CreateAnd(left_bool, right_bool, module_.GetContext().NextTemp());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 逻辑或
|
|
|
|
|
std::any IRGenImpl::visitLOrExp(SysYParser::LOrExpContext* ctx) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitLOrExp: 开始处理逻辑或表达式 " << (ctx ? ctx->getText() : "<null>"));
|
|
|
|
|
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法逻辑或表达式"));
|
|
|
|
|
|
|
|
|
|
if (!ctx->lOrExp()) {
|
|
|
|
|
@ -571,52 +416,36 @@ std::any IRGenImpl::visitLOrExp(SysYParser::LOrExpContext* ctx) {
|
|
|
|
|
|
|
|
|
|
ir::Value* left = std::any_cast<ir::Value*>(ctx->lOrExp()->accept(this));
|
|
|
|
|
ir::Value* right = std::any_cast<ir::Value*>(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<ir::Value*>(
|
|
|
|
|
builder_.CreateOr(left_bool, right_bool, module_.GetContext().NextTemp()));
|
|
|
|
|
auto zero = builder_.CreateConstInt(0);
|
|
|
|
|
auto left_bool = builder_.CreateICmpNE(left, zero, module_.GetContext().NextTemp());
|
|
|
|
|
auto right_bool = builder_.CreateICmpNE(right, zero, module_.GetContext().NextTemp());
|
|
|
|
|
return builder_.CreateOr(left_bool, right_bool, module_.GetContext().NextTemp());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitExp(SysYParser::ExpContext* ctx) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitExp: 开始处理表达式 " << (ctx ? ctx->getText() : "<null>"));
|
|
|
|
|
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法表达式"));
|
|
|
|
|
return ctx->addExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitCond(SysYParser::CondContext* ctx) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitCond: 开始处理条件 " << (ctx ? ctx->getText() : "<null>"));
|
|
|
|
|
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法条件表达式"));
|
|
|
|
|
return ctx->lOrExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitCallExp(SysYParser::UnaryExpContext* ctx) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitCallExp: 开始处理函数调用 " << (ctx ? ctx->getText() : "<null>"));
|
|
|
|
|
if (!ctx || !ctx->Ident()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法函数调用"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string funcName = ctx->Ident()->getText();
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitCallExp: 调用函数 " << funcName);
|
|
|
|
|
std::cout << "[DEBUG IRGEN] visitCallExp: 调用函数 " << funcName << std::endl;
|
|
|
|
|
|
|
|
|
|
// 查找函数对象
|
|
|
|
|
ir::Function* callee = module_.FindFunction(funcName);
|
|
|
|
|
|
|
|
|
|
// 如果没找到,可能是运行时函数还没声明,尝试动态声明
|
|
|
|
|
if (!callee) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] 函数 " << funcName << " 未找到,尝试动态声明");
|
|
|
|
|
std::cout << "[DEBUG IRGEN] 函数 " << funcName << " 未找到,尝试动态声明" << std::endl;
|
|
|
|
|
|
|
|
|
|
// 根据函数名动态创建运行时函数声明
|
|
|
|
|
callee = CreateRuntimeFunctionDecl(funcName);
|
|
|
|
|
@ -631,36 +460,9 @@ std::any IRGenImpl::visitCallExp(SysYParser::UnaryExpContext* ctx) {
|
|
|
|
|
auto argList = ctx->funcRParams()->accept(this);
|
|
|
|
|
try {
|
|
|
|
|
args = std::any_cast<std::vector<ir::Value*>>(argList);
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitCallExp: 收集到 " << args.size() << " 个参数");
|
|
|
|
|
std::cout << "[DEBUG IRGEN] visitCallExp: 收集到 " << args.size() << " 个参数" << std::endl;
|
|
|
|
|
} catch (const std::bad_any_cast& e) {
|
|
|
|
|
DEBUG_MSG("[ERROR] visitCallExp: 函数调用参数类型错误: " << e.what());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 按形参类型修正实参(数组衰减为指针等)。
|
|
|
|
|
if (auto* fty = dynamic_cast<ir::FunctionType*>(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<ir::Value*> 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());
|
|
|
|
|
}
|
|
|
|
|
std::cerr << "[ERROR] visitCallExp: 函数调用参数类型错误: " << e.what() << std::endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -673,13 +475,13 @@ std::any IRGenImpl::visitCallExp(SysYParser::UnaryExpContext* ctx) {
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitCallExp: 函数调用完成,返回值 " << (void*)callResult);
|
|
|
|
|
std::cout << "[DEBUG IRGEN] visitCallExp: 函数调用完成,返回值 " << (void*)callResult << std::endl;
|
|
|
|
|
return static_cast<ir::Value*>(callResult);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 动态创建运行时函数声明的辅助函数
|
|
|
|
|
ir::Function* IRGenImpl::CreateRuntimeFunctionDecl(const std::string& funcName) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] CreateRuntimeFunctionDecl: 开始创建运行时函数声明 " << funcName);
|
|
|
|
|
std::cout << "[DEBUG IRGEN] CreateRuntimeFunctionDecl: " << funcName << std::endl;
|
|
|
|
|
|
|
|
|
|
// 根据常见运行时函数名创建对应的函数类型
|
|
|
|
|
if (funcName == "getint" || funcName == "getch") {
|
|
|
|
|
@ -696,7 +498,7 @@ ir::Function* IRGenImpl::CreateRuntimeFunctionDecl(const std::string& funcName)
|
|
|
|
|
return module_.CreateFunction(funcName,
|
|
|
|
|
ir::Type::GetFunctionType(
|
|
|
|
|
ir::Type::GetInt32Type(),
|
|
|
|
|
{ir::Type::GetPtrInt32Type()}));
|
|
|
|
|
{ir::Type::GetPtrInt32Type(), ir::Type::GetInt32Type()}));
|
|
|
|
|
}
|
|
|
|
|
else if (funcName == "putarray") {
|
|
|
|
|
return module_.CreateFunction(funcName,
|
|
|
|
|
@ -720,27 +522,15 @@ ir::Function* IRGenImpl::CreateRuntimeFunctionDecl(const std::string& funcName)
|
|
|
|
|
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 == "read_map") {
|
|
|
|
|
return module_.CreateFunction(funcName,
|
|
|
|
|
ir::Type::GetFunctionType(ir::Type::GetInt32Type(), {}));
|
|
|
|
|
}
|
|
|
|
|
else if (funcName == "getfarray") {
|
|
|
|
|
return module_.CreateFunction(funcName,
|
|
|
|
|
else if (funcName == "float_eq") {
|
|
|
|
|
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()}));
|
|
|
|
|
{ir::Type::GetFloatType(), ir::Type::GetFloatType()}));
|
|
|
|
|
}
|
|
|
|
|
else if (funcName == "memset") {
|
|
|
|
|
return module_.CreateFunction(funcName,
|
|
|
|
|
@ -750,49 +540,12 @@ ir::Function* IRGenImpl::CreateRuntimeFunctionDecl(const std::string& funcName)
|
|
|
|
|
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) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitUnaryExp: 开始处理一元表达式 " << (ctx ? ctx->getText() : "<null>"));
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法一元表达式"));
|
|
|
|
|
}
|
|
|
|
|
@ -834,15 +587,14 @@ std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
|
|
|
|
|
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());
|
|
|
|
|
// 浮点比较:不等于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 static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateNot(operand, module_.GetContext().NextTemp()));
|
|
|
|
|
return builder_.CreateNot(operand, module_.GetContext().NextTemp());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -852,7 +604,6 @@ std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
|
|
|
|
|
|
|
|
|
|
// 实现函数调用
|
|
|
|
|
std::any IRGenImpl::visitFuncRParams(SysYParser::FuncRParamsContext* ctx) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitFuncRParams: 开始处理函数参数 " << (ctx ? ctx->getText() : "<null>"));
|
|
|
|
|
if (!ctx) return std::vector<ir::Value*>{};
|
|
|
|
|
std::vector<ir::Value*> args;
|
|
|
|
|
for (auto* exp : ctx->exp()) {
|
|
|
|
|
@ -861,37 +612,67 @@ std::any IRGenImpl::visitFuncRParams(SysYParser::FuncRParamsContext* ctx) {
|
|
|
|
|
return args;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// visitConstExp - 处理常量表达式
|
|
|
|
|
// 修改 visitConstExp 以支持常量表达式求值
|
|
|
|
|
std::any IRGenImpl::visitConstExp(SysYParser::ConstExpContext* ctx) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitConstExp: 开始处理常量表达式 " << (ctx ? ctx->getText() : "<null>"));
|
|
|
|
|
if (!ctx || !ctx->addExp()) {
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
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<ir::Value*>(result);
|
|
|
|
|
} catch (const std::bad_any_cast& e) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen",
|
|
|
|
|
"常量表达式返回类型错误: " + std::string(e.what())));
|
|
|
|
|
if (ctx->addExp()) {
|
|
|
|
|
// 尝试获取数值
|
|
|
|
|
auto result = ctx->addExp()->accept(this);
|
|
|
|
|
if (result.has_value()) {
|
|
|
|
|
try {
|
|
|
|
|
ir::Value* value = std::any_cast<ir::Value*>(result);
|
|
|
|
|
// 尝试判断是否是 ConstantInt
|
|
|
|
|
// 暂时简化:返回 IR 值
|
|
|
|
|
return static_cast<ir::Value*>(value);
|
|
|
|
|
} catch (const std::bad_any_cast&) {
|
|
|
|
|
// 可能是其他类型
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
std::cerr << "[WARNING] visitConstExp: 常量表达式求值失败: " << e.what()
|
|
|
|
|
<< ",返回0" << std::endl;
|
|
|
|
|
// 如果普通表达式求值失败,返回0
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// visitConstInitVal - 处理常量初始化值
|
|
|
|
|
std::any IRGenImpl::visitConstInitVal(SysYParser::ConstInitValContext* ctx) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitConstInitVal: 开始处理常量初始化值 " << (ctx ? ctx->getText() : "<null>"));
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法常量初始化值"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果是单个常量表达式
|
|
|
|
|
if (ctx->constExp()) {
|
|
|
|
|
return ctx->constExp()->accept(this);
|
|
|
|
|
try {
|
|
|
|
|
auto result = ctx->constExp()->accept(this);
|
|
|
|
|
if (result.has_value()) {
|
|
|
|
|
try {
|
|
|
|
|
ir::Value* value = std::any_cast<ir::Value*>(result);
|
|
|
|
|
// 尝试提取常量值
|
|
|
|
|
if (auto* const_int = dynamic_cast<ir::ConstantInt*>(value)) {
|
|
|
|
|
return static_cast<ir::Value*>(const_int);
|
|
|
|
|
} else {
|
|
|
|
|
// 如果不是常量,尝试计算数值
|
|
|
|
|
int int_val = TryEvaluateConstInt(ctx->constExp());
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateConstInt(int_val));
|
|
|
|
|
}
|
|
|
|
|
} catch (const std::bad_any_cast&) {
|
|
|
|
|
int int_val = TryEvaluateConstInt(ctx->constExp());
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateConstInt(int_val));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
std::cerr << "[WARNING] visitConstInitVal: " << e.what() << std::endl;
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 如果是聚合初始化(花括号列表)
|
|
|
|
|
else if (!ctx->constInitVal().empty()) {
|
|
|
|
|
@ -899,24 +680,22 @@ std::any IRGenImpl::visitConstInitVal(SysYParser::ConstInitValContext* ctx) {
|
|
|
|
|
|
|
|
|
|
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<ir::Value*>(result);
|
|
|
|
|
all_values.push_back(value);
|
|
|
|
|
} catch (const std::bad_any_cast&) {
|
|
|
|
|
if (result.has_value()) {
|
|
|
|
|
try {
|
|
|
|
|
// 尝试获取值列表(嵌套情况)
|
|
|
|
|
std::vector<ir::Value*> nested_values =
|
|
|
|
|
std::any_cast<std::vector<ir::Value*>>(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())));
|
|
|
|
|
// 尝试获取单个常量值
|
|
|
|
|
ir::Value* value = std::any_cast<ir::Value*>(result);
|
|
|
|
|
all_values.push_back(value);
|
|
|
|
|
} catch (const std::bad_any_cast&) {
|
|
|
|
|
try {
|
|
|
|
|
// 尝试获取值列表(嵌套情况)
|
|
|
|
|
std::vector<ir::Value*> nested_values =
|
|
|
|
|
std::any_cast<std::vector<ir::Value*>>(result);
|
|
|
|
|
all_values.insert(all_values.end(),
|
|
|
|
|
nested_values.begin(), nested_values.end());
|
|
|
|
|
} catch (const std::bad_any_cast&) {
|
|
|
|
|
throw std::runtime_error(
|
|
|
|
|
FormatError("irgen", "不支持的常量初始化值类型"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -929,7 +708,6 @@ std::any IRGenImpl::visitConstInitVal(SysYParser::ConstInitValContext* ctx) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitRelExp: 开始处理关系表达式 " << (ctx ? ctx->getText() : "<null>"));
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法关系表达式"));
|
|
|
|
|
}
|
|
|
|
|
@ -940,10 +718,10 @@ std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
|
|
|
|
|
auto* lhs = std::any_cast<ir::Value*>(left_any);
|
|
|
|
|
auto* rhs = std::any_cast<ir::Value*>(right_any);
|
|
|
|
|
|
|
|
|
|
DEBUG_MSG("[DEBUG] visitRelExp: left=" << (void*)lhs
|
|
|
|
|
std::cerr << "[DEBUG] visitRelExp: left=" << (void*)lhs
|
|
|
|
|
<< ", type=" << (lhs->GetType()->IsFloat() ? "float" : "int")
|
|
|
|
|
<< ", right=" << (void*)rhs
|
|
|
|
|
<< ", type=" << (rhs->GetType()->IsFloat() ? "float" : "int"));
|
|
|
|
|
<< ", type=" << (rhs->GetType()->IsFloat() ? "float" : "int") << std::endl;
|
|
|
|
|
|
|
|
|
|
// 处理类型转换:如果操作数类型不同,需要进行类型转换
|
|
|
|
|
if (lhs->GetType()->IsFloat() != rhs->GetType()->IsFloat()) {
|
|
|
|
|
@ -1004,7 +782,6 @@ std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitEqExp(SysYParser::EqExpContext* ctx) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitEqExp: 开始处理相等表达式 " << (ctx ? ctx->getText() : "<null>"));
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法相等表达式"));
|
|
|
|
|
}
|
|
|
|
|
@ -1015,10 +792,10 @@ std::any IRGenImpl::visitEqExp(SysYParser::EqExpContext* ctx) {
|
|
|
|
|
auto* lhs = std::any_cast<ir::Value*>(left_any);
|
|
|
|
|
auto* rhs = std::any_cast<ir::Value*>(right_any);
|
|
|
|
|
|
|
|
|
|
DEBUG_MSG("[DEBUG] visitEqExp: left=" << (void*)lhs
|
|
|
|
|
std::cerr << "[DEBUG] visitEqExp: left=" << (void*)lhs
|
|
|
|
|
<< ", type=" << (lhs->GetType()->IsFloat() ? "float" : "int")
|
|
|
|
|
<< ", right=" << (void*)rhs
|
|
|
|
|
<< ", type=" << (rhs->GetType()->IsFloat() ? "float" : "int"));
|
|
|
|
|
<< ", type=" << (rhs->GetType()->IsFloat() ? "float" : "int") << std::endl;
|
|
|
|
|
|
|
|
|
|
// 处理类型转换:如果操作数类型不同,需要进行类型转换
|
|
|
|
|
if (lhs->GetType()->IsFloat() != rhs->GetType()->IsFloat()) {
|
|
|
|
|
@ -1062,8 +839,7 @@ std::any IRGenImpl::visitEqExp(SysYParser::EqExpContext* ctx) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ir::Value* IRGenImpl::EvalAssign(SysYParser::StmtContext* ctx) {
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] EvalAssign: 开始处理赋值语句 " << (ctx ? ctx->getText() : "<null>"));
|
|
|
|
|
DEBUG_MSG("[DEBUG IRGEN] visitCond: " << (ctx ? ctx->getText() : "<null>"));
|
|
|
|
|
std::cout << "[DEBUG IRGEN] visitCond: " << (ctx ? ctx->getText() : "<null>") << std::endl;
|
|
|
|
|
if (!ctx || !ctx->lVal() || !ctx->exp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法赋值语句"));
|
|
|
|
|
}
|
|
|
|
|
@ -1088,29 +864,15 @@ ir::Value* IRGenImpl::EvalAssign(SysYParser::StmtContext* ctx) {
|
|
|
|
|
|
|
|
|
|
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<ir::Value*> indices;
|
|
|
|
|
|
|
|
|
|
// 标量指针参数(T*)不应添加前导0;数组对象需要前导0。
|
|
|
|
|
if (!(base_ptr->GetType()->IsPtrInt32() || base_ptr->GetType()->IsPtrFloat())) {
|
|
|
|
|
indices.push_back(builder_.CreateConstInt(0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 第一个索引是0(假设一维数组)
|
|
|
|
|
indices.push_back(builder_.CreateConstInt(0));
|
|
|
|
|
|
|
|
|
|
// 添加用户提供的下标
|
|
|
|
|
for (auto* exp : exp_list) {
|
|
|
|
|
ir::Value* index = EvalExpr(*exp);
|
|
|
|
|
@ -1122,20 +884,18 @@ ir::Value* IRGenImpl::EvalAssign(SysYParser::StmtContext* ctx) {
|
|
|
|
|
base_ptr, indices, module_.GetContext().NextTemp());
|
|
|
|
|
|
|
|
|
|
// 生成store指令
|
|
|
|
|
rhs = convert_for_store(rhs, elem_ptr);
|
|
|
|
|
builder_.CreateStore(rhs, elem_ptr);
|
|
|
|
|
} else {
|
|
|
|
|
// 普通标量赋值
|
|
|
|
|
// 调试输出指针类型
|
|
|
|
|
DEBUG_MSG("[DEBUG] base_ptr type: " << base_ptr->GetType());
|
|
|
|
|
DEBUG_MSG("[DEBUG] rhs type: " << rhs->GetType());
|
|
|
|
|
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()) {
|
|
|
|
|
DEBUG_MSG("[ERROR] base_ptr is not a pointer type!");
|
|
|
|
|
// 如果 base_ptr 不是指针类型,可能需要特殊处理
|
|
|
|
|
if (!base_ptr->GetType()->IsPtrInt32()) {
|
|
|
|
|
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 {
|
|
|
|
|
|