IRGen部分实现:支持赋值表达式

dyz
lc 1 week ago committed by olivame
parent 7efc0b9ad4
commit 8e12df10bb

@ -9,9 +9,9 @@
// 语句生成当前只实现了最小子集。
// 目前支持:
// - return <exp>;
// - 赋值语句lVal = exp;
//
// 还未支持:
// - 赋值语句
// - if / while 等控制流
// - 空语句、块语句嵌套分发之外的更多语句形态
@ -19,6 +19,42 @@ std::any IRGenImpl::visitStmt(SysYParser::StmtContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "缺少语句"));
}
// 检查是否是赋值语句lVal ASSIGN exp SEMICOLON
if (ctx->lVal() && ctx->ASSIGN()) {
if (!ctx->exp()) {
throw std::runtime_error(FormatError("irgen", "赋值语句缺少表达式"));
}
// 1. 计算右值表达式的值
ir::Value* rhs = EvalExpr(*ctx->exp());
// 2. 找到左值变量对应的存储槽位
auto* lval_ctx = ctx->lVal();
if (!lval_ctx || !lval_ctx->ID()) {
throw std::runtime_error(FormatError("irgen", "当前仅支持普通整型变量赋值"));
}
const auto* decl = sema_.ResolveObjectUse(lval_ctx);
if (!decl) {
throw std::runtime_error(
FormatError("irgen",
"变量使用缺少语义绑定:" + lval_ctx->ID()->getText()));
}
std::string var_name = lval_ctx->ID()->getText();
auto it = storage_map_.find(var_name);
if (it == storage_map_.end()) {
throw std::runtime_error(
FormatError("irgen",
"变量声明缺少存储槽位:" + var_name));
}
// 3. 生成 store 指令
builder_.CreateStore(rhs, it->second);
return BlockFlow::Continue;
}
// 检查是否是 return 语句RETURN exp? SEMICOLON
if (ctx->RETURN()) {
if (!ctx->exp()) {
@ -28,5 +64,6 @@ std::any IRGenImpl::visitStmt(SysYParser::StmtContext* ctx) {
builder_.CreateRet(v);
return BlockFlow::Terminated;
}
throw std::runtime_error(FormatError("irgen", "暂不支持的语句类型"));
}

Loading…
Cancel
Save