You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

347 lines
11 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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", "条件表达式暂未实现"));
}