|
|
|
|
@ -24,21 +24,62 @@ ir::Value* IRGenImpl::EvalExpr(SysYParser::ExpContext& expr) {
|
|
|
|
|
return std::any_cast<ir::Value*>(expr.accept(this));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ir::Value* IRGenImpl::EvalCond(SysYParser::CondContext& cond) {
|
|
|
|
|
return std::any_cast<ir::Value*>(cond.accept(this));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitParenExp(SysYParser::ParenExpContext* ctx) {
|
|
|
|
|
if (!ctx || !ctx->exp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法括号表达式"));
|
|
|
|
|
ir::Value* IRGenImpl::ToBoolValue(ir::Value* v) {
|
|
|
|
|
if (!v) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "条件值为空"));
|
|
|
|
|
}
|
|
|
|
|
return EvalExpr(*ctx->exp());
|
|
|
|
|
auto* zero = builder_.CreateConstInt(0);
|
|
|
|
|
return builder_.CreateCmp(ir::CmpOp::Ne, v, zero, module_.GetContext().NextTemp());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string IRGenImpl::NextBlockName() {
|
|
|
|
|
std::string temp = module_.GetContext().NextTemp();
|
|
|
|
|
if (!temp.empty() && temp.front() == '%') {
|
|
|
|
|
return "bb" + temp.substr(1);
|
|
|
|
|
}
|
|
|
|
|
return "bb" + temp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitNumberExp(SysYParser::NumberExpContext* ctx) {
|
|
|
|
|
if (!ctx || !ctx->number() || !ctx->number()->ILITERAL()) {
|
|
|
|
|
std::any IRGenImpl::visitExp(SysYParser::ExpContext* ctx) {
|
|
|
|
|
if (!ctx || !ctx->addExp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法表达式"));
|
|
|
|
|
}
|
|
|
|
|
return ctx->addExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitCond(SysYParser::CondContext* ctx) {
|
|
|
|
|
if (!ctx || !ctx->lOrExp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法条件表达式"));
|
|
|
|
|
}
|
|
|
|
|
return ctx->lOrExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法基本表达式"));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->exp()) {
|
|
|
|
|
return EvalExpr(*ctx->exp());
|
|
|
|
|
}
|
|
|
|
|
if (ctx->number()) {
|
|
|
|
|
return ctx->number()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
if (ctx->lValue()) {
|
|
|
|
|
return ctx->lValue()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "不支持的基本表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitNumber(SysYParser::NumberContext* ctx) {
|
|
|
|
|
if (!ctx || !ctx->ILITERAL()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "当前仅支持整数字面量"));
|
|
|
|
|
}
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateConstInt(std::stoi(ctx->number()->getText())));
|
|
|
|
|
builder_.CreateConstInt(std::stoi(ctx->getText())));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 变量使用的处理流程:
|
|
|
|
|
@ -47,34 +88,192 @@ std::any IRGenImpl::visitNumberExp(SysYParser::NumberExpContext* ctx) {
|
|
|
|
|
// 3. 最后生成 load,把内存中的值读出来。
|
|
|
|
|
//
|
|
|
|
|
// 因此当前 IRGen 自己不再做名字查找,而是直接消费 Sema 的绑定结果。
|
|
|
|
|
std::any IRGenImpl::visitVarExp(SysYParser::VarExpContext* ctx) {
|
|
|
|
|
if (!ctx || !ctx->var() || !ctx->var()->ID()) {
|
|
|
|
|
std::any IRGenImpl::visitLValue(SysYParser::LValueContext* ctx) {
|
|
|
|
|
if (!ctx || !ctx->ID()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "当前仅支持普通整型变量"));
|
|
|
|
|
}
|
|
|
|
|
auto* decl = sema_.ResolveVarUse(ctx->var());
|
|
|
|
|
if (!decl) {
|
|
|
|
|
throw std::runtime_error(
|
|
|
|
|
FormatError("irgen",
|
|
|
|
|
"变量使用缺少语义绑定: " + ctx->var()->ID()->getText()));
|
|
|
|
|
}
|
|
|
|
|
auto it = storage_map_.find(decl);
|
|
|
|
|
if (it == storage_map_.end()) {
|
|
|
|
|
const std::string name = ctx->ID()->getText();
|
|
|
|
|
auto it = named_storage_.find(name);
|
|
|
|
|
if (it == named_storage_.end()) {
|
|
|
|
|
throw std::runtime_error(
|
|
|
|
|
FormatError("irgen",
|
|
|
|
|
"变量声明缺少存储槽位: " + ctx->var()->ID()->getText()));
|
|
|
|
|
FormatError("irgen", "变量声明缺少存储槽位: " + name));
|
|
|
|
|
}
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateLoad(it->second, 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->unaryOp() && ctx->unaryExp()) {
|
|
|
|
|
ir::Value* v = std::any_cast<ir::Value*>(ctx->unaryExp()->accept(this));
|
|
|
|
|
if (ctx->unaryOp()->SUB()) {
|
|
|
|
|
auto* zero = builder_.CreateConstInt(0);
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateSub(
|
|
|
|
|
zero, v, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->unaryOp()->ADD()) {
|
|
|
|
|
return v;
|
|
|
|
|
}
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "当前不支持逻辑非运算"));
|
|
|
|
|
}
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "当前不支持函数调用表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) {
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法乘法表达式"));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->mulExp()) {
|
|
|
|
|
if (!ctx->unaryExp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法乘法表达式"));
|
|
|
|
|
}
|
|
|
|
|
ir::Value* lhs = std::any_cast<ir::Value*>(ctx->mulExp()->accept(this));
|
|
|
|
|
ir::Value* rhs = std::any_cast<ir::Value*>(ctx->unaryExp()->accept(this));
|
|
|
|
|
if (ctx->MUL()) {
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateMul(lhs, rhs, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->DIV()) {
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateDiv(lhs, rhs, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->MOD()) {
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateMod(lhs, rhs, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法乘法表达式"));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->unaryExp()) {
|
|
|
|
|
return ctx->unaryExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法乘法表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitAdditiveExp(SysYParser::AdditiveExpContext* ctx) {
|
|
|
|
|
if (!ctx || !ctx->exp(0) || !ctx->exp(1)) {
|
|
|
|
|
std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法加法表达式"));
|
|
|
|
|
}
|
|
|
|
|
ir::Value* lhs = EvalExpr(*ctx->exp(0));
|
|
|
|
|
ir::Value* rhs = EvalExpr(*ctx->exp(1));
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateBinary(ir::Opcode::Add, lhs, rhs,
|
|
|
|
|
module_.GetContext().NextTemp()));
|
|
|
|
|
if (ctx->addExp()) {
|
|
|
|
|
if (!ctx->mulExp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法加法表达式"));
|
|
|
|
|
}
|
|
|
|
|
ir::Value* lhs = std::any_cast<ir::Value*>(ctx->addExp()->accept(this));
|
|
|
|
|
ir::Value* rhs = std::any_cast<ir::Value*>(ctx->mulExp()->accept(this));
|
|
|
|
|
if (ctx->ADD()) {
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateAdd(lhs, rhs, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->SUB()) {
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateSub(lhs, rhs, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法加法表达式"));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->mulExp()) {
|
|
|
|
|
return ctx->mulExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法加法表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法关系表达式"));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->relExp()) {
|
|
|
|
|
if (!ctx->addExp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法关系表达式"));
|
|
|
|
|
}
|
|
|
|
|
ir::Value* lhs = std::any_cast<ir::Value*>(ctx->relExp()->accept(this));
|
|
|
|
|
ir::Value* rhs = std::any_cast<ir::Value*>(ctx->addExp()->accept(this));
|
|
|
|
|
if (ctx->LT()) {
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateCmp(
|
|
|
|
|
ir::CmpOp::Lt, lhs, rhs, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->LE()) {
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateCmp(
|
|
|
|
|
ir::CmpOp::Le, lhs, rhs, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->GT()) {
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateCmp(
|
|
|
|
|
ir::CmpOp::Gt, lhs, rhs, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->GE()) {
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateCmp(
|
|
|
|
|
ir::CmpOp::Ge, lhs, rhs, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法关系表达式"));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->addExp()) {
|
|
|
|
|
return ctx->addExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法关系表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitEqExp(SysYParser::EqExpContext* ctx) {
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法相等表达式"));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->eqExp()) {
|
|
|
|
|
if (!ctx->relExp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法相等表达式"));
|
|
|
|
|
}
|
|
|
|
|
ir::Value* lhs = std::any_cast<ir::Value*>(ctx->eqExp()->accept(this));
|
|
|
|
|
ir::Value* rhs = std::any_cast<ir::Value*>(ctx->relExp()->accept(this));
|
|
|
|
|
if (ctx->EQ()) {
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateCmp(
|
|
|
|
|
ir::CmpOp::Eq, lhs, rhs, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->NE()) {
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateCmp(
|
|
|
|
|
ir::CmpOp::Ne, lhs, rhs, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法相等表达式"));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->relExp()) {
|
|
|
|
|
return ctx->relExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法相等表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitLAndExp(SysYParser::LAndExpContext* ctx) {
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法逻辑与表达式"));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->lAndExp()) {
|
|
|
|
|
if (!ctx->eqExp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法逻辑与表达式"));
|
|
|
|
|
}
|
|
|
|
|
auto* lhs = ToBoolValue(std::any_cast<ir::Value*>(ctx->lAndExp()->accept(this)));
|
|
|
|
|
auto* rhs = ToBoolValue(std::any_cast<ir::Value*>(ctx->eqExp()->accept(this)));
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateMul(lhs, rhs, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->eqExp()) {
|
|
|
|
|
return ToBoolValue(std::any_cast<ir::Value*>(ctx->eqExp()->accept(this)));
|
|
|
|
|
}
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法逻辑与表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitLOrExp(SysYParser::LOrExpContext* ctx) {
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法逻辑或表达式"));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->lOrExp()) {
|
|
|
|
|
if (!ctx->lAndExp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法逻辑或表达式"));
|
|
|
|
|
}
|
|
|
|
|
auto* lhs = ToBoolValue(std::any_cast<ir::Value*>(ctx->lOrExp()->accept(this)));
|
|
|
|
|
auto* rhs = ToBoolValue(std::any_cast<ir::Value*>(ctx->lAndExp()->accept(this)));
|
|
|
|
|
auto* sum = builder_.CreateAdd(lhs, rhs, module_.GetContext().NextTemp());
|
|
|
|
|
return static_cast<ir::Value*>(ToBoolValue(sum));
|
|
|
|
|
}
|
|
|
|
|
if (ctx->lAndExp()) {
|
|
|
|
|
return ToBoolValue(std::any_cast<ir::Value*>(ctx->lAndExp()->accept(this)));
|
|
|
|
|
}
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法逻辑或表达式"));
|
|
|
|
|
}
|
|
|
|
|
|