|
|
#include "irgen/IRGen.h"
|
|
|
|
|
|
#include <stdexcept>
|
|
|
|
|
|
#include "antlr4/SysYParser.h"
|
|
|
#include "ir/IR.h"
|
|
|
#include "utils/Log.h"
|
|
|
|
|
|
static std::string FormatErrorCtx(antlr4::ParserRuleContext* ctx,
|
|
|
const std::string& msg) {
|
|
|
if (ctx && ctx->getStart()) {
|
|
|
return FormatErrorAt("irgen", ctx->getStart()->getLine(),
|
|
|
ctx->getStart()->getCharPositionInLine() + 1, msg);
|
|
|
}
|
|
|
return FormatError("irgen", msg);
|
|
|
}
|
|
|
|
|
|
|
|
|
// 语句生成当前只实现了最小子集。
|
|
|
// 目前支持:
|
|
|
// - return <exp>;
|
|
|
//
|
|
|
// 还未支持:
|
|
|
// - 赋值语句
|
|
|
// - if / while 等控制流
|
|
|
// - 空语句、块语句嵌套分发之外的更多语句形态
|
|
|
|
|
|
std::any IRGenImpl::visitStmt(SysYParser::StmtContext* ctx) {
|
|
|
if (!ctx) {
|
|
|
throw std::runtime_error(FormatError("irgen", "缺少语句"));
|
|
|
}
|
|
|
if (ctx->lValue() && ctx->ASSIGN() && ctx->exp()) {
|
|
|
if (!ctx->lValue()->ID()) {
|
|
|
throw std::runtime_error(FormatError("irgen", "赋值语句左值非法"));
|
|
|
}
|
|
|
ir::Value* dest = ResolveLValueAddress(ctx->lValue());
|
|
|
if (!dest) {
|
|
|
throw std::runtime_error(
|
|
|
FormatError("irgen", "赋值目标地址解析失败"));
|
|
|
}
|
|
|
ir::Value* rhs = EvalExpr(*ctx->exp());
|
|
|
builder_.CreateStore(rhs, dest);
|
|
|
return BlockFlow::Continue;
|
|
|
}
|
|
|
if (ctx->blockStmt()) {
|
|
|
ctx->blockStmt()->accept(this);
|
|
|
return builder_.GetInsertBlock() && builder_.GetInsertBlock()->HasTerminator()
|
|
|
? BlockFlow::Terminated
|
|
|
: BlockFlow::Continue;
|
|
|
}
|
|
|
if (ctx->IF()) {
|
|
|
if (!ctx->cond() || ctx->stmt().empty()) {
|
|
|
throw std::runtime_error(FormatError("irgen", "if 语句不完整"));
|
|
|
}
|
|
|
auto* then_bb = func_->CreateBlock(NextBlockName());
|
|
|
auto* merge_bb = func_->CreateBlock(NextBlockName());
|
|
|
auto* else_bb = ctx->ELSE() ? func_->CreateBlock(NextBlockName()) : merge_bb;
|
|
|
|
|
|
ir::Value* cond = ToBoolValue(EvalCond(*ctx->cond()));
|
|
|
builder_.CreateCondBr(cond, then_bb, else_bb);
|
|
|
|
|
|
builder_.SetInsertPoint(then_bb);
|
|
|
auto then_flow = std::any_cast<BlockFlow>(ctx->stmt(0)->accept(this));
|
|
|
if (then_flow != BlockFlow::Terminated) {
|
|
|
builder_.CreateBr(merge_bb);
|
|
|
}
|
|
|
|
|
|
if (ctx->ELSE()) {
|
|
|
builder_.SetInsertPoint(else_bb);
|
|
|
auto else_flow = std::any_cast<BlockFlow>(ctx->stmt(1)->accept(this));
|
|
|
if (else_flow != BlockFlow::Terminated) {
|
|
|
builder_.CreateBr(merge_bb);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
builder_.SetInsertPoint(merge_bb);
|
|
|
return BlockFlow::Continue;
|
|
|
}
|
|
|
if (ctx->WHILE()) {
|
|
|
if (!ctx->cond() || ctx->stmt().empty()) {
|
|
|
throw std::runtime_error(FormatError("irgen", "while 语句不完整"));
|
|
|
}
|
|
|
auto* cond_bb = func_->CreateBlock(NextBlockName());
|
|
|
auto* body_bb = func_->CreateBlock(NextBlockName());
|
|
|
auto* exit_bb = func_->CreateBlock(NextBlockName());
|
|
|
|
|
|
builder_.CreateBr(cond_bb);
|
|
|
builder_.SetInsertPoint(cond_bb);
|
|
|
ir::Value* cond = ToBoolValue(EvalCond(*ctx->cond()));
|
|
|
builder_.CreateCondBr(cond, body_bb, exit_bb);
|
|
|
|
|
|
loop_stack_.push_back({cond_bb, exit_bb});
|
|
|
builder_.SetInsertPoint(body_bb);
|
|
|
auto body_flow = std::any_cast<BlockFlow>(ctx->stmt(0)->accept(this));
|
|
|
if (body_flow != BlockFlow::Terminated) {
|
|
|
builder_.CreateBr(cond_bb);
|
|
|
}
|
|
|
loop_stack_.pop_back();
|
|
|
|
|
|
builder_.SetInsertPoint(exit_bb);
|
|
|
return BlockFlow::Continue;
|
|
|
}
|
|
|
if (ctx->BREAK()) {
|
|
|
if (loop_stack_.empty()) {
|
|
|
throw std::runtime_error(FormatError("irgen", "break 不在循环中"));
|
|
|
}
|
|
|
builder_.CreateBr(loop_stack_.back().break_target);
|
|
|
return BlockFlow::Terminated;
|
|
|
}
|
|
|
if (ctx->CONTINUE()) {
|
|
|
if (loop_stack_.empty()) {
|
|
|
throw std::runtime_error(FormatError("irgen", "continue 不在循环中"));
|
|
|
}
|
|
|
builder_.CreateBr(loop_stack_.back().continue_target);
|
|
|
return BlockFlow::Terminated;
|
|
|
}
|
|
|
if (ctx->returnStmt()) {
|
|
|
return ctx->returnStmt()->accept(this);
|
|
|
}
|
|
|
if (ctx->exp()) {
|
|
|
EvalExpr(*ctx->exp());
|
|
|
return BlockFlow::Continue;
|
|
|
}
|
|
|
if (ctx->SEMICOLON()) {
|
|
|
return BlockFlow::Continue;
|
|
|
}
|
|
|
throw std::runtime_error(FormatError("irgen", "暂不支持的语句类型"));
|
|
|
}
|
|
|
|
|
|
ir::Value* IRGenImpl::ResolveLValueAddress(SysYParser::LValueContext* ctx) {
|
|
|
if (!ctx || !ctx->ID()) {
|
|
|
throw std::runtime_error(FormatError("irgen", "非法左值"));
|
|
|
}
|
|
|
const std::string name = ctx->ID()->getText();
|
|
|
ir::Value* base = FindInScope(name);
|
|
|
if (!base) {
|
|
|
throw std::runtime_error(FormatError("irgen", "变量未声明: " + name));
|
|
|
}
|
|
|
|
|
|
if (ctx->LBRACK().empty()) {
|
|
|
return base;
|
|
|
}
|
|
|
|
|
|
// 到目前为止只支持一维数组,占位实现
|
|
|
if (ctx->exp().empty()) {
|
|
|
throw std::runtime_error(FormatError("irgen", "数组下标缺失"));
|
|
|
}
|
|
|
return EmitArrayIndex(base, ctx->exp(0));
|
|
|
}
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitReturnStmt(SysYParser::ReturnStmtContext* ctx) {
|
|
|
if (!ctx) {
|
|
|
throw std::runtime_error(FormatError("irgen", "缺少 return 语句"));
|
|
|
}
|
|
|
if (!ctx->exp()) {
|
|
|
throw std::runtime_error(FormatError("irgen", "return 缺少表达式"));
|
|
|
}
|
|
|
ir::Value* v = EvalExpr(*ctx->exp());
|
|
|
builder_.CreateRet(v);
|
|
|
return BlockFlow::Terminated;
|
|
|
}
|
|
|
|
|
|
ir::Value* IRGenImpl::EmitArrayIndex(ir::Value* base_ptr,
|
|
|
SysYParser::ExpContext* idx_expr) {
|
|
|
if (!base_ptr) {
|
|
|
throw std::runtime_error(FormatError("irgen", "数组基址为空"));
|
|
|
}
|
|
|
if (!idx_expr) {
|
|
|
throw std::runtime_error(FormatError("irgen", "缺少数组下标表达式"));
|
|
|
}
|
|
|
ir::Value* idx = EvalExpr(*idx_expr);
|
|
|
if (!idx) {
|
|
|
throw std::runtime_error(FormatError("irgen", "数组下标计算失败"));
|
|
|
}
|
|
|
// 当前 IR 仍只支持 i32 / i32*,还未实现真正的 GEP。
|
|
|
// 这里提供一个占位:直接将基址作为元素地址返回(仅用于结构化接口),
|
|
|
// 具体语义需在后续 IR 指令集扩展后完成。
|
|
|
// TODO: 实现指针加法/GEP,以支持数组下标访问
|
|
|
(void)idx;
|
|
|
return base_ptr;
|
|
|
}
|
|
|
|
|
|
void IRGenImpl::EmitGlobalVariable(SysYParser::VarDefContext* ctx) {
|
|
|
if (!ctx) {
|
|
|
throw std::runtime_error(FormatError("irgen", "缺少全局变量定义"));
|
|
|
}
|
|
|
// GlobalValue 还未完成,暂时抛异常以提醒后续实现。
|
|
|
throw std::runtime_error(FormatError("irgen", "全局变量生成未实现"));
|
|
|
}
|
|
|
|