|
|
|
|
@ -23,20 +23,43 @@
|
|
|
|
|
|
|
|
|
|
ir::Value* IRGenImpl::EvalExpr(SysYParser::ExpContext& expr) {
|
|
|
|
|
std::cout << "[DEBUG IRGEN] EvalExpr: " << expr.getText() << std::endl;
|
|
|
|
|
return std::any_cast<ir::Value*>(expr.accept(this));
|
|
|
|
|
try {
|
|
|
|
|
auto result_any = expr.accept(this);
|
|
|
|
|
|
|
|
|
|
if (!result_any.has_value()) {
|
|
|
|
|
std::cerr << "[ERROR] EvalExpr: result_any has no value" << std::endl;
|
|
|
|
|
throw std::runtime_error("表达式求值结果为空");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
ir::Value* result = std::any_cast<ir::Value*>(result_any);
|
|
|
|
|
std::cerr << "[DEBUG] EvalExpr: success, result = " << (void*)result << std::endl;
|
|
|
|
|
return result;
|
|
|
|
|
} catch (const std::bad_any_cast& e) {
|
|
|
|
|
std::cerr << "[ERROR] EvalExpr: bad any_cast - " << e.what() << std::endl;
|
|
|
|
|
std::cerr << " Type info: " << result_any.type().name() << std::endl;
|
|
|
|
|
|
|
|
|
|
// 尝试其他可能的类型
|
|
|
|
|
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) {
|
|
|
|
|
std::cerr << "[ERROR] Exception in EvalExpr: " << e.what() << std::endl;
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ir::Value* IRGenImpl::EvalCond(SysYParser::CondContext& cond) {
|
|
|
|
|
return std::any_cast<ir::Value*>(cond.accept(this));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitExp(SysYParser::ExpContext* ctx) {
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "缺少表达式"));
|
|
|
|
|
}
|
|
|
|
|
std::cout << "[DEBUG IRGEN] visitExp: " << ctx->getText() << std::endl;
|
|
|
|
|
return ctx->addExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 基本表达式:数字、变量、括号表达式
|
|
|
|
|
std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
|
|
|
|
|
@ -45,100 +68,52 @@ std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "缺少基本表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::cerr << "[DEBUG] visitPrimaryExp" << std::endl;
|
|
|
|
|
|
|
|
|
|
// 处理数字字面量
|
|
|
|
|
if (ctx->DECIMAL_INT()) {
|
|
|
|
|
int value = std::stoi(ctx->DECIMAL_INT()->getText());
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateConstInt(value));
|
|
|
|
|
ir::Value* const_int = builder_.CreateConstInt(value);
|
|
|
|
|
std::cerr << "[DEBUG] visitPrimaryExp: constant int " << value
|
|
|
|
|
<< " created as " << (void*)const_int << std::endl;
|
|
|
|
|
return static_cast<ir::Value*>(const_int);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ctx->HEX_INT()) {
|
|
|
|
|
std::string hex = ctx->HEX_INT()->getText();
|
|
|
|
|
int value = std::stoi(hex, nullptr, 16);
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateConstInt(value));
|
|
|
|
|
ir::Value* const_int = builder_.CreateConstInt(value);
|
|
|
|
|
return static_cast<ir::Value*>(const_int);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ctx->OCTAL_INT()) {
|
|
|
|
|
std::string oct = ctx->OCTAL_INT()->getText();
|
|
|
|
|
int value = std::stoi(oct, nullptr, 8);
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateConstInt(value));
|
|
|
|
|
ir::Value* const_int = builder_.CreateConstInt(value);
|
|
|
|
|
return static_cast<ir::Value*>(const_int);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ctx->ZERO()) {
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
|
|
|
|
|
ir::Value* const_int = builder_.CreateConstInt(0);
|
|
|
|
|
return static_cast<ir::Value*>(const_int);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理变量
|
|
|
|
|
if (ctx->lVal()) {
|
|
|
|
|
std::cerr << "[DEBUG] visitPrimaryExp: visiting lVal" << std::endl;
|
|
|
|
|
return ctx->lVal()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理括号表达式
|
|
|
|
|
if (ctx->L_PAREN() && ctx->exp()) {
|
|
|
|
|
std::cerr << "[DEBUG] visitPrimaryExp: visiting parenthesized expression" << std::endl;
|
|
|
|
|
return EvalExpr(*ctx->exp());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::cerr << "[ERROR] visitPrimaryExp: unsupported primary expression type" << std::endl;
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "不支持的基本表达式类型"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
|
|
|
|
|
std::cout << "[DEBUG IRGEN] visitUnaryExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "缺少一元表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ctx->primaryExp()) {
|
|
|
|
|
auto result = ctx->primaryExp()->accept(this);
|
|
|
|
|
std::cout << "[DEBUG IRGEN] visitUnaryExp primary result: " << (ctx->primaryExp() ? ctx->primaryExp()->getText() : "<null>") << std::endl;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ctx->Ident() && ctx->L_PAREN()) {
|
|
|
|
|
std::string funcName = ctx->Ident()->getText();
|
|
|
|
|
ir::Function* callee = nullptr;
|
|
|
|
|
for (auto& f : module_.GetFunctions()) {
|
|
|
|
|
if (f->GetName() == funcName) {
|
|
|
|
|
callee = f.get();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!callee) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "找不到函数: " + funcName));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<ir::Value*> args;
|
|
|
|
|
if (ctx->funcRParams()) {
|
|
|
|
|
for (auto* exp : ctx->funcRParams()->exp()) {
|
|
|
|
|
args.push_back(EvalExpr(*exp));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ir::Value* result = builder_.CreateCall(callee, args, module_.GetContext().NextTemp());
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ctx->unaryOp() && ctx->unaryExp()) {
|
|
|
|
|
auto operand_any = ctx->unaryExp()->accept(this);
|
|
|
|
|
std::cout << "[DEBUG IRGEN] visitUnaryExp operand_any.type=" << operand_any.type().name() << " text=" << ctx->unaryExp()->getText() << std::endl;
|
|
|
|
|
auto* operand = std::any_cast<ir::Value*>(operand_any);
|
|
|
|
|
if (ctx->unaryOp()->AddOp()) {
|
|
|
|
|
return operand;
|
|
|
|
|
}
|
|
|
|
|
if (ctx->unaryOp()->SubOp()) {
|
|
|
|
|
auto* zero = builder_.CreateConstInt(0);
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateBinary(ir::Opcode::Sub, zero, operand,
|
|
|
|
|
module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->unaryOp()->NotOp()) {
|
|
|
|
|
// 逻辑非暂不支持,先默认 0/1 取反
|
|
|
|
|
// 这里简化:如果 operand ==0 返回1,否则返回0。(不做真实比较)
|
|
|
|
|
// 需要后续完善比较指令。
|
|
|
|
|
return operand;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "不支持的 unaryExp"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 左值(变量)处理
|
|
|
|
|
// 1. 先通过语义分析结果把变量使用绑定回声明;
|
|
|
|
|
@ -151,6 +126,7 @@ std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string varName = ctx->Ident()->getText();
|
|
|
|
|
std::cerr << "[DEBUG] visitLVal: " << varName << std::endl;
|
|
|
|
|
|
|
|
|
|
// 从语义分析获取变量定义
|
|
|
|
|
auto* decl = sema_.ResolveVarUse(ctx);
|
|
|
|
|
@ -194,75 +170,283 @@ std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法加法表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 注意:mulExp() 返回的是 MulExpContext*,不是 vector
|
|
|
|
|
// 需要递归处理 AddExp 的左结合性
|
|
|
|
|
// AddExp : MulExp | AddExp ('+' | '-') MulExp
|
|
|
|
|
|
|
|
|
|
// 先处理左操作数
|
|
|
|
|
ir::Value* result = nullptr;
|
|
|
|
|
// 如果没有 addExp(),说明是单个 mulExp()
|
|
|
|
|
if (!ctx->addExp()) {
|
|
|
|
|
return ctx->mulExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 正确提取左操作数
|
|
|
|
|
auto left_any = ctx->addExp()->accept(this);
|
|
|
|
|
if (!left_any.has_value()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "左操作数求值失败"));
|
|
|
|
|
}
|
|
|
|
|
ir::Value* left = std::any_cast<ir::Value*>(left_any);
|
|
|
|
|
|
|
|
|
|
// 如果有左子节点(AddExp),递归处理
|
|
|
|
|
if (ctx->addExp()) {
|
|
|
|
|
auto left_any = ctx->addExp()->accept(this);
|
|
|
|
|
std::cout << "[DEBUG IRGEN] visitAddExp left_any.type=" << left_any.type().name() << " text=" << ctx->addExp()->getText() << std::endl;
|
|
|
|
|
result = std::any_cast<ir::Value*>(left_any);
|
|
|
|
|
} else {
|
|
|
|
|
// 否则是 MulExp
|
|
|
|
|
auto right_any = ctx->mulExp()->accept(this);
|
|
|
|
|
std::cout << "[DEBUG IRGEN] visitAddExp right_any.type=" << right_any.type().name() << " text=" << ctx->mulExp()->getText() << std::endl;
|
|
|
|
|
result = std::any_cast<ir::Value*>(right_any);
|
|
|
|
|
// 正确提取右操作数
|
|
|
|
|
auto right_any = ctx->mulExp()->accept(this);
|
|
|
|
|
if (!right_any.has_value()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "右操作数求值失败"));
|
|
|
|
|
}
|
|
|
|
|
ir::Value* right = std::any_cast<ir::Value*>(right_any);
|
|
|
|
|
|
|
|
|
|
// 如果有运算符和右操作数
|
|
|
|
|
if (ctx->AddOp() || ctx->SubOp()) {
|
|
|
|
|
ir::Value* rhs = std::any_cast<ir::Value*>(ctx->mulExp()->accept(this));
|
|
|
|
|
|
|
|
|
|
if (ctx->AddOp()) {
|
|
|
|
|
result = builder_.CreateAdd(result, rhs, module_.GetContext().NextTemp());
|
|
|
|
|
} else if (ctx->SubOp()) {
|
|
|
|
|
// 减法:a - b = a + (-b)
|
|
|
|
|
// 暂时用加法,后续需要实现真正的减法
|
|
|
|
|
result = builder_.CreateAdd(result, rhs, module_.GetContext().NextTemp());
|
|
|
|
|
}
|
|
|
|
|
std::cerr << "[DEBUG] visitAddExp: left=" << (void*)left << ", right=" << (void*)right << std::endl;
|
|
|
|
|
|
|
|
|
|
// 根据操作符生成相应的指令
|
|
|
|
|
if (ctx->AddOp()) {
|
|
|
|
|
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()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return static_cast<ir::Value*>(result);
|
|
|
|
|
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) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法乘法表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查 unaryExp(返回指针,可能为 nullptr)
|
|
|
|
|
auto* unaryExp = ctx->unaryExp();
|
|
|
|
|
std::cout << "[DEBUG] unaryExp is " << (unaryExp ? "not null" : "null") << std::endl;
|
|
|
|
|
// 如果是基本形式 UnaryExp
|
|
|
|
|
if (!ctx->mulExp()) {
|
|
|
|
|
return ctx->unaryExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 提取左操作数
|
|
|
|
|
auto left_any = ctx->mulExp()->accept(this);
|
|
|
|
|
if (!left_any.has_value()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "左操作数求值失败"));
|
|
|
|
|
}
|
|
|
|
|
ir::Value* left = std::any_cast<ir::Value*>(left_any);
|
|
|
|
|
|
|
|
|
|
if (unaryExp) {
|
|
|
|
|
std::cout << "[DEBUG] calling unaryExp->accept(this)" << std::endl;
|
|
|
|
|
auto result = unaryExp->accept(this);
|
|
|
|
|
std::cout << "[DEBUG] returned from unaryExp" << std::endl;
|
|
|
|
|
return result;
|
|
|
|
|
// 提取右操作数
|
|
|
|
|
auto right_any = ctx->unaryExp()->accept(this);
|
|
|
|
|
if (!right_any.has_value()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "右操作数求值失败"));
|
|
|
|
|
}
|
|
|
|
|
ir::Value* right = std::any_cast<ir::Value*>(right_any);
|
|
|
|
|
|
|
|
|
|
// 检查 mulExp
|
|
|
|
|
auto* mulExp = ctx->mulExp();
|
|
|
|
|
std::cout << "[DEBUG] mulExp is " << (mulExp ? "not null" : "null") << std::endl;
|
|
|
|
|
if (mulExp) {
|
|
|
|
|
std::cout << "[DEBUG] calling mulExp->accept(this)" << std::endl;
|
|
|
|
|
auto result = mulExp->accept(this);
|
|
|
|
|
std::cout << "[DEBUG] returned from mulExp" << std::endl;
|
|
|
|
|
return result;
|
|
|
|
|
// 根据操作符生成指令
|
|
|
|
|
if (ctx->MulOp()) {
|
|
|
|
|
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()));
|
|
|
|
|
} else if (ctx->QuoOp()) {
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateMod(left, right, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::cout << "[DEBUG] no unaryExp or mulExp found!" << std::endl;
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "乘法表达式暂未实现"));
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "未知的乘法操作符"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 逻辑与
|
|
|
|
|
std::any IRGenImpl::visitLAndExp(SysYParser::LAndExpContext* ctx) {
|
|
|
|
|
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法逻辑与表达式"));
|
|
|
|
|
|
|
|
|
|
if (!ctx->lAndExp()) {
|
|
|
|
|
return ctx->eqExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 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) {
|
|
|
|
|
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法逻辑或表达式"));
|
|
|
|
|
|
|
|
|
|
if (!ctx->lOrExp()) {
|
|
|
|
|
return ctx->lAndExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 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) {
|
|
|
|
|
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法表达式"));
|
|
|
|
|
return ctx->addExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitCond(SysYParser::CondContext* ctx) {
|
|
|
|
|
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法条件表达式"));
|
|
|
|
|
return ctx->lOrExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ir::Value* IRGenImpl::visitCallExp(SysYParser::UnaryExpContext* ctx) {
|
|
|
|
|
if (!ctx || !ctx->Ident()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法函数调用"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string funcName = ctx->Ident()->getText();
|
|
|
|
|
|
|
|
|
|
// 语义检查(如果需要)
|
|
|
|
|
// auto* funcDecl = sema_.ResolveFuncCall(ctx);
|
|
|
|
|
// if (!funcDecl) throw ...
|
|
|
|
|
|
|
|
|
|
// 收集实参
|
|
|
|
|
std::vector<ir::Value*> args;
|
|
|
|
|
if (ctx->funcRParams()) {
|
|
|
|
|
auto argList = ctx->funcRParams()->accept(this);
|
|
|
|
|
args = std::any_cast<std::vector<ir::Value*>>(argList);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 查找函数对象
|
|
|
|
|
ir::Function* callee = module_.FindFunction(funcName);
|
|
|
|
|
if (!callee) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "未找到函数: " + funcName));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成调用指令
|
|
|
|
|
return builder_.CreateCall(callee, args, module_.GetContext().NextTemp());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 实现一元表达式
|
|
|
|
|
std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法一元表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 基本表达式
|
|
|
|
|
if (ctx->primaryExp()) {
|
|
|
|
|
return ctx->primaryExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 函数调用
|
|
|
|
|
if (ctx->Ident()) {
|
|
|
|
|
return visitCallExp(ctx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 一元运算
|
|
|
|
|
if (ctx->unaryOp() && ctx->unaryExp()) {
|
|
|
|
|
auto* operand = std::any_cast<ir::Value*>(ctx->unaryExp()->accept(this));
|
|
|
|
|
std::string op = ctx->unaryOp()->getText();
|
|
|
|
|
|
|
|
|
|
if (op == "+") {
|
|
|
|
|
// +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()));
|
|
|
|
|
} else if (op == "!") {
|
|
|
|
|
return builder_.CreateNot(operand, module_.GetContext().NextTemp());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "暂不支持的一元表达式形式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 实现函数调用
|
|
|
|
|
std::any IRGenImpl::visitFuncRParams(SysYParser::FuncRParamsContext* ctx) {
|
|
|
|
|
if (!ctx) return std::vector<ir::Value*>{};
|
|
|
|
|
std::vector<ir::Value*> args;
|
|
|
|
|
for (auto* exp : ctx->exp()) {
|
|
|
|
|
args.push_back(EvalExpr(*exp));
|
|
|
|
|
}
|
|
|
|
|
return args;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 修改 visitConstExp 以支持常量表达式求值
|
|
|
|
|
std::any IRGenImpl::visitConstExp(SysYParser::ConstExpContext* ctx) {
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法常量表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitConstInitVal(SysYParser::ConstInitValContext* ctx) {
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法常量初始化值"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果是单个表达式
|
|
|
|
|
if (ctx->constExp()) {
|
|
|
|
|
try {
|
|
|
|
|
return ctx->constExp()->accept(this);
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
std::cerr << "[WARNING] visitConstInitVal: 常量表达式求值失败: " << e.what()
|
|
|
|
|
<< ",返回默认值0" << std::endl;
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 如果是聚合初始化(花括号列表)
|
|
|
|
|
else if (!ctx->constInitVal().empty()) {
|
|
|
|
|
// 处理嵌套聚合初始化
|
|
|
|
|
std::vector<ir::Value*> all_values;
|
|
|
|
|
|
|
|
|
|
for (auto* init_val : ctx->constInitVal()) {
|
|
|
|
|
auto result = init_val->accept(this);
|
|
|
|
|
if (result.has_value()) {
|
|
|
|
|
try {
|
|
|
|
|
// 尝试获取单个值
|
|
|
|
|
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", "不支持的常量初始化值类型"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return all_values;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 空初始化列表
|
|
|
|
|
return std::vector<ir::Value*>{};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 关系表达式(支持 <, >, <=, >=)
|
|
|
|
|
std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法关系表达式"));
|
|
|
|
|
@ -330,17 +514,69 @@ std::any IRGenImpl::visitEqExp(SysYParser::EqExpContext* ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "相等表达式暂未实现"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 条件表达式
|
|
|
|
|
std::any IRGenImpl::visitCond(SysYParser::CondContext* ctx) {
|
|
|
|
|
ir::Value* IRGenImpl::EvalAssign(SysYParser::StmtContext* ctx) {
|
|
|
|
|
std::cout << "[DEBUG IRGEN] visitCond: " << (ctx ? ctx->getText() : "<null>") << std::endl;
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法条件表达式"));
|
|
|
|
|
if (!ctx || !ctx->lVal() || !ctx->exp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法赋值语句"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 简化:返回 lOrExp 的值
|
|
|
|
|
if (ctx->lOrExp()) {
|
|
|
|
|
return ctx->lOrExp()->accept(this);
|
|
|
|
|
// 计算右值
|
|
|
|
|
ir::Value* rhs = EvalExpr(*ctx->exp());
|
|
|
|
|
|
|
|
|
|
auto* lval = ctx->lVal();
|
|
|
|
|
std::string varName = lval->Ident()->getText();
|
|
|
|
|
|
|
|
|
|
// 首先尝试从语义分析获取变量定义
|
|
|
|
|
auto* var_decl = sema_.ResolveVarUse(lval);
|
|
|
|
|
|
|
|
|
|
if (var_decl) {
|
|
|
|
|
// 是变量赋值
|
|
|
|
|
// 从storage_map_获取存储位置
|
|
|
|
|
auto it = storage_map_.find(var_decl);
|
|
|
|
|
if (it == storage_map_.end()) {
|
|
|
|
|
throw std::runtime_error(
|
|
|
|
|
FormatError("irgen", "变量声明缺少存储槽位: " + varName));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ir::Value* base_ptr = it->second;
|
|
|
|
|
|
|
|
|
|
// 检查是否有数组下标
|
|
|
|
|
auto 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);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 尝试获取常量定义
|
|
|
|
|
auto* const_decl = sema_.ResolveConstUse(lval);
|
|
|
|
|
if (const_decl) {
|
|
|
|
|
// 尝试给常量赋值,这是错误的
|
|
|
|
|
throw std::runtime_error(
|
|
|
|
|
FormatError("irgen", "不能给常量赋值: " + varName));
|
|
|
|
|
} else {
|
|
|
|
|
throw std::runtime_error(
|
|
|
|
|
FormatError("irgen", "变量/常量使用缺少语义绑定: " + varName));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "条件表达式暂未实现"));
|
|
|
|
|
return rhs;
|
|
|
|
|
}
|
|
|
|
|
|