|
|
|
|
@ -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", "暂不支持的语句类型"));
|
|
|
|
|
}
|
|
|
|
|
|