|
|
|
|
@ -25,20 +25,51 @@ ir::Value* IRGenImpl::EvalExpr(SysYParser::ExpContext& expr) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitParenExp(SysYParser::ParenExpContext* ctx) {
|
|
|
|
|
if (!ctx || !ctx->exp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法括号表达式"));
|
|
|
|
|
std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
|
|
|
|
|
if (!ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法基本表达式"));
|
|
|
|
|
}
|
|
|
|
|
// 处理括号表达式:LPAREN exp RPAREN
|
|
|
|
|
if (ctx->exp()) {
|
|
|
|
|
return EvalExpr(*ctx->exp());
|
|
|
|
|
}
|
|
|
|
|
// 处理 lVal(变量使用)- 交给 visitLVal 处理
|
|
|
|
|
if (ctx->lVal()) {
|
|
|
|
|
// 直接在这里处理变量读取,避免 accept 调用可能导致的问题
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateLoad(it->second, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
return EvalExpr(*ctx->exp());
|
|
|
|
|
// 处理 number
|
|
|
|
|
if (ctx->number()) {
|
|
|
|
|
return ctx->number()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "不支持的基本表达式类型"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::any IRGenImpl::visitNumberExp(SysYParser::NumberExpContext* ctx) {
|
|
|
|
|
if (!ctx || !ctx->number() || !ctx->number()->ILITERAL()) {
|
|
|
|
|
std::any IRGenImpl::visitNumber(SysYParser::NumberContext* ctx) {
|
|
|
|
|
if (!ctx || !ctx->intConst()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "当前仅支持整数字面量"));
|
|
|
|
|
}
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateConstInt(std::stoi(ctx->number()->getText())));
|
|
|
|
|
builder_.CreateConstInt(std::stoi(ctx->intConst()->getText())));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 变量使用的处理流程:
|
|
|
|
|
@ -47,33 +78,46 @@ 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::visitLVal(SysYParser::LValContext* ctx) {
|
|
|
|
|
if (!ctx || !ctx->ID()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "当前仅支持普通整型变量"));
|
|
|
|
|
}
|
|
|
|
|
auto* decl = sema_.ResolveVarUse(ctx->var());
|
|
|
|
|
const auto* decl = sema_.ResolveObjectUse(ctx);
|
|
|
|
|
if (!decl) {
|
|
|
|
|
throw std::runtime_error(
|
|
|
|
|
FormatError("irgen",
|
|
|
|
|
"变量使用缺少语义绑定: " + ctx->var()->ID()->getText()));
|
|
|
|
|
"变量使用缺少语义绑定:" + ctx->ID()->getText()));
|
|
|
|
|
}
|
|
|
|
|
auto it = storage_map_.find(decl);
|
|
|
|
|
// 使用变量名查找存储槽位
|
|
|
|
|
std::string var_name = ctx->ID()->getText();
|
|
|
|
|
auto it = storage_map_.find(var_name);
|
|
|
|
|
if (it == storage_map_.end()) {
|
|
|
|
|
throw std::runtime_error(
|
|
|
|
|
FormatError("irgen",
|
|
|
|
|
"变量声明缺少存储槽位: " + ctx->var()->ID()->getText()));
|
|
|
|
|
"变量声明缺少存储槽位:" + var_name));
|
|
|
|
|
}
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
|
|
builder_.CreateLoad(it->second, module_.GetContext().NextTemp()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
|
|
|
|
|
// 如果是 mulExp 直接返回(addExp : mulExp)
|
|
|
|
|
if (ctx->mulExp() && ctx->addExp() == nullptr) {
|
|
|
|
|
return ctx->mulExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理 addExp op mulExp 的递归形式
|
|
|
|
|
if (!ctx->addExp() || !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));
|
|
|
|
|
|
|
|
|
|
ir::Opcode op = ir::Opcode::Add;
|
|
|
|
|
if (ctx->ADD()) {
|
|
|
|
|
@ -93,18 +137,18 @@ std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法乘除法表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果是 unaryExp 直接返回
|
|
|
|
|
if (ctx->unaryExp()) {
|
|
|
|
|
// 如果是 unaryExp 直接返回(mulExp : unaryExp)
|
|
|
|
|
if (ctx->unaryExp() && ctx->mulExp() == nullptr) {
|
|
|
|
|
return ctx->unaryExp()->accept(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理 MulExp op unaryExp 的递归形式
|
|
|
|
|
if (!ctx->exp(0) || !ctx->unaryExp(0)) {
|
|
|
|
|
// 处理 mulExp op unaryExp 的递归形式
|
|
|
|
|
if (!ctx->mulExp() || !ctx->unaryExp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法乘除法表达式结构"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ir::Value* lhs = std::any_cast<ir::Value*>(ctx->exp(0)->accept(this));
|
|
|
|
|
ir::Value* rhs = std::any_cast<ir::Value*>(ctx->unaryExp(0)->accept(this));
|
|
|
|
|
ir::Value* lhs = std::any_cast<ir::Value*>(ctx->mulExp()->accept(this));
|
|
|
|
|
ir::Value* rhs = std::any_cast<ir::Value*>(ctx->unaryExp()->accept(this));
|
|
|
|
|
|
|
|
|
|
ir::Opcode op = ir::Opcode::Mul;
|
|
|
|
|
if (ctx->MUL()) {
|
|
|
|
|
|