|
|
|
|
@ -2,7 +2,7 @@
|
|
|
|
|
|
|
|
|
|
#include <stdexcept>
|
|
|
|
|
|
|
|
|
|
#include "antlr4/SysYParser.h"
|
|
|
|
|
#include "SysYParser.h"
|
|
|
|
|
#include "ir/IR.h"
|
|
|
|
|
#include "utils/Log.h"
|
|
|
|
|
|
|
|
|
|
@ -53,14 +53,6 @@ ir::Value* IRGenImpl::ToBoolValue(ir::Value* v) {
|
|
|
|
|
return builder_.CreateCmp(ir::CmpOp::Ne, v, zero, module_.GetContext().NextTemp());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ir::Value* IRGenImpl::FindInScope(const std::string& name) {
|
|
|
|
|
for (auto it = scope_storage_.rbegin(); it != scope_storage_.rend(); ++it) {
|
|
|
|
|
auto found = it->find(name);
|
|
|
|
|
if (found != it->end()) return found->second;
|
|
|
|
|
}
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string IRGenImpl::NextBlockName() {
|
|
|
|
|
std::string temp = module_.GetContext().NextTemp();
|
|
|
|
|
if (!temp.empty() && temp.front() == '%') {
|
|
|
|
|
@ -265,36 +257,9 @@ 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->ID() && ctx->LPAREN()) {
|
|
|
|
|
auto func_name = ctx->ID()->getText();
|
|
|
|
|
ir::Function* callee = FindFunctionByName(func_name);
|
|
|
|
|
if (!callee) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "函数未定义: " + func_name));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<ir::Value*> args;
|
|
|
|
|
if (ctx->funcRParams()) {
|
|
|
|
|
for (auto* exp : ctx->funcRParams()->exp()) {
|
|
|
|
|
if (!exp) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "函数参数缺失"));
|
|
|
|
|
}
|
|
|
|
|
args.push_back(EvalExpr(*exp));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto* call = builder_.CreateCall(callee, args, module_.GetContext().NextTemp());
|
|
|
|
|
if (callee->GetType()->IsVoid()) {
|
|
|
|
|
// void 类型调用表达式在值上下文下暂时返回 0。
|
|
|
|
|
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
|
|
|
|
|
}
|
|
|
|
|
return static_cast<ir::Value*>(call);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ctx->unaryOp() && ctx->unaryExp()) {
|
|
|
|
|
ir::Value* v = std::any_cast<ir::Value*>(ctx->unaryExp()->accept(this));
|
|
|
|
|
if (ctx->unaryOp()->SUB()) {
|
|
|
|
|
@ -489,10 +454,9 @@ std::any IRGenImpl::visitLAndExp(SysYParser::LAndExpContext* ctx) {
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法逻辑与表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ctx->lAndExp()) {
|
|
|
|
|
if (ctx->eqExp()) {
|
|
|
|
|
return ToBoolValue(std::any_cast<ir::Value*>(ctx->eqExp()->accept(this)));
|
|
|
|
|
if (ctx->lAndExp()) {
|
|
|
|
|
if (!ctx->eqExp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法逻辑与表达式"));
|
|
|
|
|
}
|
|
|
|
|
// 短路求值:a && b
|
|
|
|
|
// 使用函数级临时槽位(0=false,1=true),避免 phi 依赖和循环内动态 alloca。
|
|
|
|
|
@ -523,46 +487,19 @@ std::any IRGenImpl::visitLAndExp(SysYParser::LAndExpContext* ctx) {
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateLoad(slot, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ctx->eqExp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法逻辑与表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto* lhs = ToBoolValue(std::any_cast<ir::Value*>(ctx->lAndExp()->accept(this)));
|
|
|
|
|
|
|
|
|
|
auto* result_slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp());
|
|
|
|
|
auto* rhs_bb = func_->CreateBlock(NextBlockName());
|
|
|
|
|
auto* false_bb = func_->CreateBlock(NextBlockName());
|
|
|
|
|
auto* merge_bb = func_->CreateBlock(NextBlockName());
|
|
|
|
|
|
|
|
|
|
builder_.CreateCondBr(lhs, rhs_bb, false_bb);
|
|
|
|
|
|
|
|
|
|
builder_.SetInsertPoint(rhs_bb);
|
|
|
|
|
auto* rhs = ToBoolValue(std::any_cast<ir::Value*>(ctx->eqExp()->accept(this)));
|
|
|
|
|
builder_.CreateStore(rhs, result_slot);
|
|
|
|
|
if (!rhs_bb->HasTerminator()) {
|
|
|
|
|
builder_.CreateBr(merge_bb);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
builder_.SetInsertPoint(false_bb);
|
|
|
|
|
builder_.CreateStore(builder_.CreateConstInt(0), result_slot);
|
|
|
|
|
if (!false_bb->HasTerminator()) {
|
|
|
|
|
builder_.CreateBr(merge_bb);
|
|
|
|
|
if (ctx->eqExp()) {
|
|
|
|
|
return ToBoolValue(std::any_cast<ir::Value*>(ctx->eqExp()->accept(this)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
builder_.SetInsertPoint(merge_bb);
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateLoad(result_slot, module_.GetContext().NextTemp()));
|
|
|
|
|
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()) {
|
|
|
|
|
return ToBoolValue(std::any_cast<ir::Value*>(ctx->lAndExp()->accept(this)));
|
|
|
|
|
if (ctx->lOrExp()) {
|
|
|
|
|
if (!ctx->lAndExp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法逻辑或表达式"));
|
|
|
|
|
}
|
|
|
|
|
// 短路求值:a || b
|
|
|
|
|
if (!short_circuit_slot_) {
|
|
|
|
|
@ -597,34 +534,8 @@ std::any IRGenImpl::visitLOrExp(SysYParser::LOrExpContext* ctx) {
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateLoad(slot, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ctx->lAndExp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法逻辑或表达式"));
|
|
|
|
|
if (ctx->lAndExp()) {
|
|
|
|
|
return ToBoolValue(std::any_cast<ir::Value*>(ctx->lAndExp()->accept(this)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto* lhs = ToBoolValue(std::any_cast<ir::Value*>(ctx->lOrExp()->accept(this)));
|
|
|
|
|
|
|
|
|
|
auto* result_slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp());
|
|
|
|
|
auto* true_bb = func_->CreateBlock(NextBlockName());
|
|
|
|
|
auto* rhs_bb = func_->CreateBlock(NextBlockName());
|
|
|
|
|
auto* merge_bb = func_->CreateBlock(NextBlockName());
|
|
|
|
|
|
|
|
|
|
builder_.CreateCondBr(lhs, true_bb, rhs_bb);
|
|
|
|
|
|
|
|
|
|
builder_.SetInsertPoint(true_bb);
|
|
|
|
|
builder_.CreateStore(builder_.CreateConstInt(1), result_slot);
|
|
|
|
|
if (!true_bb->HasTerminator()) {
|
|
|
|
|
builder_.CreateBr(merge_bb);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
builder_.SetInsertPoint(rhs_bb);
|
|
|
|
|
auto* rhs = ToBoolValue(std::any_cast<ir::Value*>(ctx->lAndExp()->accept(this)));
|
|
|
|
|
builder_.CreateStore(rhs, result_slot);
|
|
|
|
|
if (!rhs_bb->HasTerminator()) {
|
|
|
|
|
builder_.CreateBr(merge_bb);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
builder_.SetInsertPoint(merge_bb);
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateLoad(result_slot, module_.GetContext().NextTemp()));
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法逻辑或表达式"));
|
|
|
|
|
}
|
|
|
|
|
|