|
|
|
|
@ -111,6 +111,7 @@ std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// visitLVal
|
|
|
|
|
// 修改 visitLVal 以支持数组访问
|
|
|
|
|
std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
|
|
|
|
|
if (!ctx || !ctx->Ident()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法左值"));
|
|
|
|
|
@ -135,13 +136,43 @@ std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
|
|
|
|
|
"变量声明缺少存储槽位: " + varName));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ir::Value* load_result = builder_.CreateLoad(it->second, module_.GetContext().NextTemp());
|
|
|
|
|
std::cerr << "[DEBUG] visitLVal: created load, result = " << (void*)load_result << std::endl;
|
|
|
|
|
ir::Value* base_ptr = it->second;
|
|
|
|
|
|
|
|
|
|
return static_cast<ir::Value*>(load_result);
|
|
|
|
|
// 检查是否有数组下标(是否是数组访问)
|
|
|
|
|
auto exp_list = ctx->exp();
|
|
|
|
|
if (!exp_list.empty()) {
|
|
|
|
|
// 这是数组访问,需要生成GEP指令
|
|
|
|
|
std::vector<ir::Value*> indices;
|
|
|
|
|
|
|
|
|
|
// 第一个索引是0(假设一维数组)
|
|
|
|
|
indices.push_back(builder_.CreateConstInt(0));
|
|
|
|
|
|
|
|
|
|
// 添加用户提供的下标
|
|
|
|
|
for (auto* exp : exp_list) {
|
|
|
|
|
ir::Value* index = EvalExpr(*exp);
|
|
|
|
|
indices.push_back(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成GEP指令获取元素地址
|
|
|
|
|
ir::Value* elem_ptr = builder_.CreateGEP(
|
|
|
|
|
base_ptr, indices, module_.GetContext().NextTemp());
|
|
|
|
|
|
|
|
|
|
// 加载值
|
|
|
|
|
ir::Value* load_result = builder_.CreateLoad(
|
|
|
|
|
elem_ptr, module_.GetContext().NextTemp());
|
|
|
|
|
std::cerr << "[DEBUG] visitLVal: array access, result = " << (void*)load_result << std::endl;
|
|
|
|
|
|
|
|
|
|
return static_cast<ir::Value*>(load_result);
|
|
|
|
|
} else {
|
|
|
|
|
// 普通标量变量访问
|
|
|
|
|
ir::Value* load_result = builder_.CreateLoad(
|
|
|
|
|
base_ptr, module_.GetContext().NextTemp());
|
|
|
|
|
std::cerr << "[DEBUG] visitLVal: scalar load, result = " << (void*)load_result << std::endl;
|
|
|
|
|
|
|
|
|
|
return static_cast<ir::Value*>(load_result);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 加法表达式
|
|
|
|
|
std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
@ -386,16 +417,6 @@ std::any IRGenImpl::visitConstInitVal(SysYParser::ConstInitValContext* ctx) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitInitVal(SysYParser::InitValContext* ctx) {
|
|
|
|
|
// 返回初始化的值(可能是单个表达式或聚合列表)
|
|
|
|
|
if (ctx->exp()) {
|
|
|
|
|
return EvalExpr(*ctx->exp());
|
|
|
|
|
} else {
|
|
|
|
|
// 聚合初始化:需要返回一个列表,暂未实现
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "聚合初始化暂未实现"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitConstExp(SysYParser::ConstExpContext* ctx) {
|
|
|
|
|
// 消除未使用参数警告
|
|
|
|
|
(void)ctx; // 明确表示参数未使用
|
|
|
|
|
@ -415,7 +436,7 @@ std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法关系表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果是基本形式 AddExp
|
|
|
|
|
// 如果是基本形式 AddExp(没有关系操作符)
|
|
|
|
|
if (!ctx->relExp()) {
|
|
|
|
|
return ctx->addExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
@ -434,27 +455,52 @@ std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
|
|
|
|
|
}
|
|
|
|
|
ir::Value* right = std::any_cast<ir::Value*>(right_any);
|
|
|
|
|
|
|
|
|
|
// 根据操作符生成相应的比较指令
|
|
|
|
|
std::string op = ctx->relExp()->getText();
|
|
|
|
|
// 通过操作符文本来判断,这样更通用
|
|
|
|
|
// 获取操作符文本(这需要查看具体的语法定义)
|
|
|
|
|
// 由于不知道具体的方法名,我们采用更通用的方法
|
|
|
|
|
|
|
|
|
|
// 方法1:尝试通过relOp()获取操作符
|
|
|
|
|
if (auto relOp = ctx->relExp()) {
|
|
|
|
|
std::string op = relOp->getText();
|
|
|
|
|
|
|
|
|
|
if (op == "<" || op == "Lt") {
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateICmpSLT(left, right, module_.GetContext().NextTemp()));
|
|
|
|
|
} else if (op == ">" || op == "Gt") {
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateICmpSGT(left, right, module_.GetContext().NextTemp()));
|
|
|
|
|
} else if (op == "<=" || op == "Le") {
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateICmpSLE(left, right, module_.GetContext().NextTemp()));
|
|
|
|
|
} else if (op == ">=" || op == "Ge") {
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateICmpSGE(left, right, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (op == "<") {
|
|
|
|
|
// 方法2:检查是否有特定的操作符方法
|
|
|
|
|
// 根据错误信息,可能是LOp和GOp
|
|
|
|
|
if (ctx->LOp()) { // "<"
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateICmpSLT(left, right, module_.GetContext().NextTemp()));
|
|
|
|
|
} else if (op == ">") {
|
|
|
|
|
} else if (ctx->GOp()) { // ">"
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateICmpSGT(left, right, module_.GetContext().NextTemp()));
|
|
|
|
|
} else if (op == "<=") {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 方法3:检查Le和Ge
|
|
|
|
|
if (ctx->LeOp()) { // "<="
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateICmpSLE(left, right, module_.GetContext().NextTemp()));
|
|
|
|
|
} else if (op == ">=") {
|
|
|
|
|
} else if (ctx->GeOp()) { // ">="
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateICmpSGE(left, right, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "未知的关系操作符: " + op));
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "未知的关系操作符"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//赋值
|
|
|
|
|
// 修改 EvalAssign 以支持数组赋值
|
|
|
|
|
ir::Value* IRGenImpl::EvalAssign(SysYParser::StmtContext* ctx) {
|
|
|
|
|
if (!ctx || !ctx->lVal() || !ctx->exp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法赋值语句"));
|
|
|
|
|
@ -463,11 +509,11 @@ ir::Value* IRGenImpl::EvalAssign(SysYParser::StmtContext* ctx) {
|
|
|
|
|
// 计算右值
|
|
|
|
|
ir::Value* rhs = EvalExpr(*ctx->exp());
|
|
|
|
|
|
|
|
|
|
// 获取左值地址
|
|
|
|
|
std::string varName = ctx->lVal()->Ident()->getText();
|
|
|
|
|
auto* lval = ctx->lVal();
|
|
|
|
|
std::string varName = lval->Ident()->getText();
|
|
|
|
|
|
|
|
|
|
// 从语义分析获取变量定义
|
|
|
|
|
auto* decl = sema_.ResolveVarUse(ctx->lVal());
|
|
|
|
|
auto* decl = sema_.ResolveVarUse(lval);
|
|
|
|
|
if (!decl) {
|
|
|
|
|
throw std::runtime_error(
|
|
|
|
|
FormatError("irgen", "变量使用缺少语义绑定: " + varName));
|
|
|
|
|
@ -480,8 +526,33 @@ ir::Value* IRGenImpl::EvalAssign(SysYParser::StmtContext* ctx) {
|
|
|
|
|
FormatError("irgen", "变量声明缺少存储槽位: " + varName));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成store指令
|
|
|
|
|
builder_.CreateStore(rhs, it->second);
|
|
|
|
|
ir::Value* base_ptr = it->second;
|
|
|
|
|
|
|
|
|
|
// 检查是否有数组下标
|
|
|
|
|
auto exp_list = lval->exp();
|
|
|
|
|
if (!exp_list.empty()) {
|
|
|
|
|
// 这是数组元素赋值,需要生成GEP指令
|
|
|
|
|
std::vector<ir::Value*> indices;
|
|
|
|
|
|
|
|
|
|
// 第一个索引是0(假设一维数组)
|
|
|
|
|
indices.push_back(builder_.CreateConstInt(0));
|
|
|
|
|
|
|
|
|
|
// 添加用户提供的下标
|
|
|
|
|
for (auto* exp : exp_list) {
|
|
|
|
|
ir::Value* index = EvalExpr(*exp);
|
|
|
|
|
indices.push_back(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成GEP指令获取元素地址
|
|
|
|
|
ir::Value* elem_ptr = builder_.CreateGEP(
|
|
|
|
|
base_ptr, indices, module_.GetContext().NextTemp());
|
|
|
|
|
|
|
|
|
|
// 生成store指令
|
|
|
|
|
builder_.CreateStore(rhs, elem_ptr);
|
|
|
|
|
} else {
|
|
|
|
|
// 普通标量赋值
|
|
|
|
|
builder_.CreateStore(rhs, base_ptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rhs;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|