基本测试通过但有函数没有实现

potapo 3 weeks ago
parent f53f7ec82c
commit 97c01debbd

@ -22,9 +22,38 @@
// - ...
ir::Value* IRGenImpl::EvalExpr(SysYParser::ExpContext& expr) {
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));
}
@ -35,62 +64,70 @@ 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", "不支持的基本表达式类型"));
}
// 左值(变量)处理
// 1. 先通过语义分析结果把变量使用绑定回声明;
// 2. 再通过 storage_map_ 找到该声明对应的栈槽位;
// 3. 最后生成 load把内存中的值读出来。
// visitLVal
std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
if (!ctx || !ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "非法左值"));
}
std::string varName = ctx->Ident()->getText();
std::cerr << "[DEBUG] visitLVal: " << varName << std::endl;
// 从语义分析获取变量定义
auto* decl = sema_.ResolveVarUse(ctx);
if (!decl) {
auto* const_def = sema_.ResolveConstUse(ctx);
if (!const_def) {
throw std::runtime_error(
FormatError("irgen",
"使用缺少语义绑定: " + varName);
}
"变量使用缺少语义绑定: " + varName));
}
// 使用 storage_map_ 而不是 varNameToSlot_
auto it = storage_map_.find(decl);
if (it == storage_map_.end()) {
throw std::runtime_error(
@ -98,26 +135,49 @@ std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
"变量声明缺少存储槽位: " + varName));
}
return static_cast<ir::Value*>(
builder_.CreateLoad(it->second, module_.GetContext().NextTemp()));
ir::Value* load_result = builder_.CreateLoad(it->second, module_.GetContext().NextTemp());
std::cerr << "[DEBUG] visitLVal: created load, result = " << (void*)load_result << std::endl;
return static_cast<ir::Value*>(load_result);
}
// 加法表达式
std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法加法表达式"));
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法加法表达式"));
}
// 如果没有 addExp(),说明是单个 mulExp()
if (!ctx->addExp()) {
return ctx->mulExp()->accept(this);
}
ir::Value* left = std::any_cast<ir::Value*>(ctx->addExp()->accept(this));
ir::Value* right = std::any_cast<ir::Value*>(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);
// 正确提取右操作数
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);
std::cerr << "[DEBUG] visitAddExp: left=" << (void*)left << ", right=" << (void*)right << std::endl;
// 根据操作符生成相应的指令
if (ctx->AddOp()) {
return builder_.CreateAdd(left, right, module_.GetContext().NextTemp());
return static_cast<ir::Value*>(
builder_.CreateAdd(left, right, module_.GetContext().NextTemp()));
} else if (ctx->SubOp()) {
return builder_.CreateSub(left, right, module_.GetContext().NextTemp());
return static_cast<ir::Value*>(
builder_.CreateSub(left, right, module_.GetContext().NextTemp()));
}
throw std::runtime_error(FormatError("irgen", "未知的加法操作符"));
}
@ -125,53 +185,42 @@ std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
// visitMulExp
std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法乘法表达式"));
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法乘法表达式"));
}
// 如果是基本形式 UnaryExp
if (!ctx->mulExp()) {
return ctx->unaryExp()->accept(this);
}
// 否则有左子节点和操作符
ir::Value* left = std::any_cast<ir::Value*>(ctx->mulExp()->accept(this));
ir::Value* right = std::any_cast<ir::Value*>(ctx->unaryExp()->accept(this));
std::string op;
if (ctx->MulOp()) op = "*";
else if (ctx->DivOp()) op = "/";
else if (ctx->QuoOp()) op = "%";
else throw std::runtime_error(FormatError("irgen", "缺少乘法类操作符"));
if (op == "*") {
return builder_.CreateMul(left, right, module_.GetContext().NextTemp());
} else if (op == "/") {
return builder_.CreateDiv(left, right, module_.GetContext().NextTemp());
} else if (op == "%") {
return builder_.CreateMod(left, right, module_.GetContext().NextTemp());
// 提取左操作数
auto left_any = ctx->mulExp()->accept(this);
if (!left_any.has_value()) {
throw std::runtime_error(FormatError("irgen", "左操作数求值失败"));
}
throw std::runtime_error(FormatError("irgen", "未知的乘法操作符"));
}
// 关系表达式
std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法关系表达式"));
if (!ctx->relExp()) {
return ctx->addExp()->accept(this);
ir::Value* left = std::any_cast<ir::Value*>(left_any);
// 提取右操作数
auto right_any = ctx->unaryExp()->accept(this);
if (!right_any.has_value()) {
throw std::runtime_error(FormatError("irgen", "右操作数求值失败"));
}
ir::Value* left = std::any_cast<ir::Value*>(ctx->relExp()->accept(this));
ir::Value* right = std::any_cast<ir::Value*>(ctx->addExp()->accept(this));
if (ctx->LOp()) {
return builder_.CreateICmpSLT(left, right, module_.GetContext().NextTemp());
} else if (ctx->GOp()) {
return builder_.CreateICmpSGT(left, right, module_.GetContext().NextTemp());
} else if (ctx->LeOp()) {
return builder_.CreateICmpSLE(left, right, module_.GetContext().NextTemp());
} else if (ctx->GeOp()) {
return builder_.CreateICmpSGE(left, right, module_.GetContext().NextTemp());
ir::Value* right = std::any_cast<ir::Value*>(right_any);
// 根据操作符生成指令
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()));
}
throw std::runtime_error(FormatError("irgen", "未知的关系操作符"));
throw std::runtime_error(FormatError("irgen", "未知的乘法操作符"));
}
// 相等表达式
@ -326,7 +375,7 @@ std::any IRGenImpl::visitConstInitVal(SysYParser::ConstInitValContext* ctx) {
if (ctx->constExp()) {
// 常量表达式求值:需要语义分析支持常量折叠,这里我们返回求值后的常量值。
// 假设 sema_ 有方法 EvaluateConstExp 返回 int。
auto* constExp = ctx->constExp();
// auto* constExp = ctx->constExp(); // 这行可以删除,因为不需要使用
// 通过语义分析求值(暂未实现,先抛异常)
// int val = sema_.EvaluateConstExp(constExp);
// return builder_.CreateConstInt(val);
@ -348,6 +397,9 @@ std::any IRGenImpl::visitInitVal(SysYParser::InitValContext* ctx) {
}
std::any IRGenImpl::visitConstExp(SysYParser::ConstExpContext* ctx) {
// 消除未使用参数警告
(void)ctx; // 明确表示参数未使用
// 常量表达式由 AddExp 构成,我们直接复用表达式求值(但需要常量折叠)。
// 由于常量表达式在编译时求值IR 生成阶段其实不需要计算值,语义分析会提供。
// 这里我们只用来获取 IR 值(例如数组大小),但数组大小需要在 IR 生成前就知道。
@ -357,3 +409,47 @@ std::any IRGenImpl::visitConstExp(SysYParser::ConstExpContext* ctx) {
// 这里先抛异常,等待语义团队提供接口。
throw std::runtime_error(FormatError("irgen", "常量表达式求值暂未实现"));
}
std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法关系表达式"));
}
// 如果是基本形式 AddExp
if (!ctx->relExp()) {
return ctx->addExp()->accept(this);
}
// 提取左操作数
auto left_any = ctx->relExp()->accept(this);
if (!left_any.has_value()) {
throw std::runtime_error(FormatError("irgen", "左操作数求值失败"));
}
ir::Value* left = std::any_cast<ir::Value*>(left_any);
// 提取右操作数
auto right_any = ctx->addExp()->accept(this);
if (!right_any.has_value()) {
throw std::runtime_error(FormatError("irgen", "右操作数求值失败"));
}
ir::Value* right = std::any_cast<ir::Value*>(right_any);
// 根据操作符生成相应的比较指令
std::string op = ctx->relExp()->getText();
if (op == "<") {
return static_cast<ir::Value*>(
builder_.CreateICmpSLT(left, right, module_.GetContext().NextTemp()));
} else if (op == ">") {
return static_cast<ir::Value*>(
builder_.CreateICmpSGT(left, right, module_.GetContext().NextTemp()));
} else if (op == "<=") {
return static_cast<ir::Value*>(
builder_.CreateICmpSLE(left, right, module_.GetContext().NextTemp()));
} else if (op == ">=") {
return static_cast<ir::Value*>(
builder_.CreateICmpSGE(left, right, module_.GetContext().NextTemp()));
}
throw std::runtime_error(FormatError("irgen", "未知的关系操作符: " + op));
}
Loading…
Cancel
Save