|
|
#include "irgen/IRGen.h"
|
|
|
|
|
|
#include <stdexcept>
|
|
|
|
|
|
#include "SysYParser.h"
|
|
|
#include "ir/IR.h"
|
|
|
#include "utils/Log.h"
|
|
|
|
|
|
// 表达式生成当前也只实现了很小的一个子集。
|
|
|
// 目前支持:
|
|
|
// - 整数字面量
|
|
|
// - 普通局部变量读取
|
|
|
// - 括号表达式
|
|
|
// - 二元加法
|
|
|
//
|
|
|
// 还未支持:
|
|
|
// - 减乘除与一元运算
|
|
|
// - 赋值表达式
|
|
|
// - 函数调用
|
|
|
// - 数组、指针、下标访问
|
|
|
// - 条件与比较表达式
|
|
|
// - ...
|
|
|
|
|
|
ir::Value* IRGenImpl::EvalExpr(SysYParser::ExpContext& expr) {
|
|
|
std::cout << "[DEBUG IRGEN] EvalExpr: " << expr.getText() << std::endl;
|
|
|
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::visitExp(SysYParser::ExpContext* ctx) {
|
|
|
if (!ctx) {
|
|
|
throw std::runtime_error(FormatError("irgen", "缺少表达式"));
|
|
|
}
|
|
|
std::cout << "[DEBUG IRGEN] visitExp: " << ctx->getText() << std::endl;
|
|
|
return ctx->addExp()->accept(this);
|
|
|
}
|
|
|
|
|
|
// 基本表达式:数字、变量、括号表达式
|
|
|
std::any IRGenImpl::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) {
|
|
|
std::cout << "[DEBUG IRGEN] visitPrimaryExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
|
|
|
if (!ctx) {
|
|
|
throw std::runtime_error(FormatError("irgen", "缺少基本表达式"));
|
|
|
}
|
|
|
|
|
|
// 处理数字字面量
|
|
|
if (ctx->DECIMAL_INT()) {
|
|
|
int value = std::stoi(ctx->DECIMAL_INT()->getText());
|
|
|
return static_cast<ir::Value*>(builder_.CreateConstInt(value));
|
|
|
}
|
|
|
|
|
|
if (ctx->HEX_INT()) {
|
|
|
std::string hex = ctx->HEX_INT()->getText();
|
|
|
int value = std::stoi(hex, nullptr, 16);
|
|
|
return static_cast<ir::Value*>(builder_.CreateConstInt(value));
|
|
|
}
|
|
|
|
|
|
if (ctx->OCTAL_INT()) {
|
|
|
std::string oct = ctx->OCTAL_INT()->getText();
|
|
|
int value = std::stoi(oct, nullptr, 8);
|
|
|
return static_cast<ir::Value*>(builder_.CreateConstInt(value));
|
|
|
}
|
|
|
|
|
|
if (ctx->ZERO()) {
|
|
|
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
|
|
|
}
|
|
|
|
|
|
// 处理变量
|
|
|
if (ctx->lVal()) {
|
|
|
return ctx->lVal()->accept(this);
|
|
|
}
|
|
|
|
|
|
// 处理括号表达式
|
|
|
if (ctx->L_PAREN() && ctx->exp()) {
|
|
|
return EvalExpr(*ctx->exp());
|
|
|
}
|
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "不支持的基本表达式类型"));
|
|
|
}
|
|
|
|
|
|
std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
|
|
|
std::cout << "[DEBUG IRGEN] visitUnaryExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
|
|
|
if (!ctx) {
|
|
|
throw std::runtime_error(FormatError("irgen", "缺少一元表达式"));
|
|
|
}
|
|
|
|
|
|
if (ctx->primaryExp()) {
|
|
|
auto result = ctx->primaryExp()->accept(this);
|
|
|
std::cout << "[DEBUG IRGEN] visitUnaryExp primary result: " << (ctx->primaryExp() ? ctx->primaryExp()->getText() : "<null>") << std::endl;
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
if (ctx->Ident() && ctx->L_PAREN()) {
|
|
|
std::string funcName = ctx->Ident()->getText();
|
|
|
ir::Function* callee = nullptr;
|
|
|
for (auto& f : module_.GetFunctions()) {
|
|
|
if (f->GetName() == funcName) {
|
|
|
callee = f.get();
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
if (!callee) {
|
|
|
throw std::runtime_error(FormatError("irgen", "找不到函数: " + funcName));
|
|
|
}
|
|
|
|
|
|
std::vector<ir::Value*> args;
|
|
|
if (ctx->funcRParams()) {
|
|
|
for (auto* exp : ctx->funcRParams()->exp()) {
|
|
|
args.push_back(EvalExpr(*exp));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
ir::Value* result = builder_.CreateCall(callee, args, module_.GetContext().NextTemp());
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
if (ctx->unaryOp() && ctx->unaryExp()) {
|
|
|
auto operand_any = ctx->unaryExp()->accept(this);
|
|
|
std::cout << "[DEBUG IRGEN] visitUnaryExp operand_any.type=" << operand_any.type().name() << " text=" << ctx->unaryExp()->getText() << std::endl;
|
|
|
auto* operand = std::any_cast<ir::Value*>(operand_any);
|
|
|
if (ctx->unaryOp()->AddOp()) {
|
|
|
return operand;
|
|
|
}
|
|
|
if (ctx->unaryOp()->SubOp()) {
|
|
|
auto* zero = builder_.CreateConstInt(0);
|
|
|
return static_cast<ir::Value*>(
|
|
|
builder_.CreateBinary(ir::Opcode::Sub, zero, operand,
|
|
|
module_.GetContext().NextTemp()));
|
|
|
}
|
|
|
if (ctx->unaryOp()->NotOp()) {
|
|
|
// 逻辑非暂不支持,先默认 0/1 取反
|
|
|
// 这里简化:如果 operand ==0 返回1,否则返回0。(不做真实比较)
|
|
|
// 需要后续完善比较指令。
|
|
|
return operand;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "不支持的 unaryExp"));
|
|
|
}
|
|
|
|
|
|
// 左值(变量)处理
|
|
|
// 1. 先通过语义分析结果把变量使用绑定回声明;
|
|
|
// 2. 再通过 storage_map_ 找到该声明对应的栈槽位;
|
|
|
// 3. 最后生成 load,把内存中的值读出来。
|
|
|
std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
|
|
|
std::cout << "[DEBUG IRGEN] visitLVal: " << (ctx ? ctx->getText() : "<null>") << std::endl;
|
|
|
if (!ctx || !ctx->Ident()) {
|
|
|
throw std::runtime_error(FormatError("irgen", "非法左值"));
|
|
|
}
|
|
|
|
|
|
std::string varName = ctx->Ident()->getText();
|
|
|
|
|
|
// 从语义分析获取变量定义
|
|
|
auto* decl = sema_.ResolveVarUse(ctx);
|
|
|
ir::Value* ptr = nullptr;
|
|
|
if (decl) {
|
|
|
auto it = storage_map_.find(decl);
|
|
|
if (it != storage_map_.end()) {
|
|
|
ptr = it->second;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!ptr) {
|
|
|
auto it2 = param_map_.find(varName);
|
|
|
if (it2 != param_map_.end()) {
|
|
|
ptr = it2->second;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!ptr) {
|
|
|
auto it3 = global_map_.find(varName);
|
|
|
if (it3 != global_map_.end()) {
|
|
|
ptr = it3->second;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (!ptr) {
|
|
|
throw std::runtime_error(
|
|
|
FormatError("irgen",
|
|
|
"变量声明缺少存储槽位: " + varName));
|
|
|
}
|
|
|
|
|
|
return static_cast<ir::Value*>(
|
|
|
builder_.CreateLoad(ptr, module_.GetContext().NextTemp()));
|
|
|
}
|
|
|
|
|
|
|
|
|
// 加法表达式
|
|
|
std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
|
|
|
std::cout << "[DEBUG IRGEN] visitAddExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
|
|
|
if (!ctx) {
|
|
|
throw std::runtime_error(FormatError("irgen", "非法加法表达式"));
|
|
|
}
|
|
|
|
|
|
// 注意:mulExp() 返回的是 MulExpContext*,不是 vector
|
|
|
// 需要递归处理 AddExp 的左结合性
|
|
|
// AddExp : MulExp | AddExp ('+' | '-') MulExp
|
|
|
|
|
|
// 先处理左操作数
|
|
|
ir::Value* result = nullptr;
|
|
|
|
|
|
// 如果有左子节点(AddExp),递归处理
|
|
|
if (ctx->addExp()) {
|
|
|
auto left_any = ctx->addExp()->accept(this);
|
|
|
std::cout << "[DEBUG IRGEN] visitAddExp left_any.type=" << left_any.type().name() << " text=" << ctx->addExp()->getText() << std::endl;
|
|
|
result = std::any_cast<ir::Value*>(left_any);
|
|
|
} else {
|
|
|
// 否则是 MulExp
|
|
|
auto right_any = ctx->mulExp()->accept(this);
|
|
|
std::cout << "[DEBUG IRGEN] visitAddExp right_any.type=" << right_any.type().name() << " text=" << ctx->mulExp()->getText() << std::endl;
|
|
|
result = std::any_cast<ir::Value*>(right_any);
|
|
|
}
|
|
|
|
|
|
// 如果有运算符和右操作数
|
|
|
if (ctx->AddOp() || ctx->SubOp()) {
|
|
|
ir::Value* rhs = std::any_cast<ir::Value*>(ctx->mulExp()->accept(this));
|
|
|
|
|
|
if (ctx->AddOp()) {
|
|
|
result = builder_.CreateAdd(result, rhs, module_.GetContext().NextTemp());
|
|
|
} else if (ctx->SubOp()) {
|
|
|
// 减法:a - b = a + (-b)
|
|
|
// 暂时用加法,后续需要实现真正的减法
|
|
|
result = builder_.CreateAdd(result, rhs, module_.GetContext().NextTemp());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return static_cast<ir::Value*>(result);
|
|
|
}
|
|
|
|
|
|
// 在 IRGenExp.cpp 中添加
|
|
|
|
|
|
std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) {
|
|
|
std::cout << "[DEBUG IRGEN] visitMulExp: " << (ctx ? ctx->getText() : "<null>") << std::endl;
|
|
|
if (!ctx) {
|
|
|
throw std::runtime_error(FormatError("irgen", "非法乘法表达式"));
|
|
|
}
|
|
|
|
|
|
// 检查 unaryExp(返回指针,可能为 nullptr)
|
|
|
auto* unaryExp = ctx->unaryExp();
|
|
|
std::cout << "[DEBUG] unaryExp is " << (unaryExp ? "not null" : "null") << std::endl;
|
|
|
|
|
|
if (unaryExp) {
|
|
|
std::cout << "[DEBUG] calling unaryExp->accept(this)" << std::endl;
|
|
|
auto result = unaryExp->accept(this);
|
|
|
std::cout << "[DEBUG] returned from unaryExp" << std::endl;
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
// 检查 mulExp
|
|
|
auto* mulExp = ctx->mulExp();
|
|
|
std::cout << "[DEBUG] mulExp is " << (mulExp ? "not null" : "null") << std::endl;
|
|
|
if (mulExp) {
|
|
|
std::cout << "[DEBUG] calling mulExp->accept(this)" << std::endl;
|
|
|
auto result = mulExp->accept(this);
|
|
|
std::cout << "[DEBUG] returned from mulExp" << std::endl;
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
std::cout << "[DEBUG] no unaryExp or mulExp found!" << std::endl;
|
|
|
throw std::runtime_error(FormatError("irgen", "乘法表达式暂未实现"));
|
|
|
}
|
|
|
|
|
|
// 关系表达式(支持 <, >, <=, >=)
|
|
|
std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
|
|
|
if (!ctx) {
|
|
|
throw std::runtime_error(FormatError("irgen", "非法关系表达式"));
|
|
|
}
|
|
|
|
|
|
if (ctx->relExp() && ctx->addExp()) {
|
|
|
auto left_any = ctx->relExp()->accept(this);
|
|
|
auto right_any = ctx->addExp()->accept(this);
|
|
|
auto* lhs = std::any_cast<ir::Value*>(left_any);
|
|
|
auto* rhs = std::any_cast<ir::Value*>(right_any);
|
|
|
|
|
|
if (ctx->LOp()) {
|
|
|
return static_cast<ir::Value*>(
|
|
|
builder_.CreateICmpLT(lhs, rhs, module_.GetContext().NextTemp()));
|
|
|
}
|
|
|
if (ctx->GOp()) {
|
|
|
return static_cast<ir::Value*>(
|
|
|
builder_.CreateICmpGT(lhs, rhs, module_.GetContext().NextTemp()));
|
|
|
}
|
|
|
if (ctx->LeOp()) {
|
|
|
return static_cast<ir::Value*>(
|
|
|
builder_.CreateICmpLE(lhs, rhs, module_.GetContext().NextTemp()));
|
|
|
}
|
|
|
if (ctx->GeOp()) {
|
|
|
return static_cast<ir::Value*>(
|
|
|
builder_.CreateICmpGE(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() && ctx->relExp()) {
|
|
|
auto left_any = ctx->eqExp()->accept(this);
|
|
|
auto right_any = ctx->relExp()->accept(this);
|
|
|
auto* lhs = std::any_cast<ir::Value*>(left_any);
|
|
|
auto* rhs = std::any_cast<ir::Value*>(right_any);
|
|
|
|
|
|
if (ctx->EqOp()) {
|
|
|
return static_cast<ir::Value*>(
|
|
|
builder_.CreateICmpEQ(lhs, rhs, module_.GetContext().NextTemp()));
|
|
|
}
|
|
|
if (ctx->NeOp()) {
|
|
|
return static_cast<ir::Value*>(
|
|
|
builder_.CreateICmpNE(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::visitCond(SysYParser::CondContext* ctx) {
|
|
|
std::cout << "[DEBUG IRGEN] visitCond: " << (ctx ? ctx->getText() : "<null>") << std::endl;
|
|
|
if (!ctx) {
|
|
|
throw std::runtime_error(FormatError("irgen", "非法条件表达式"));
|
|
|
}
|
|
|
|
|
|
// 简化:返回 lOrExp 的值
|
|
|
if (ctx->lOrExp()) {
|
|
|
return ctx->lOrExp()->accept(this);
|
|
|
}
|
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "条件表达式暂未实现"));
|
|
|
}
|