函数返回错误类型

potapo 3 weeks ago
parent b93d769576
commit f53f7ec82c

@ -216,7 +216,16 @@ class ConstantInt : public ConstantValue {
};
// 后续还需要扩展更多指令类型。
enum class Opcode { Add, Sub, Mul, Alloca, Load, Store, Ret };
enum class Opcode {
Add, Sub, Mul,
Alloca, Load, Store, Ret,
Div, Mod,
ICmpEQ, ICmpNE,
ICmpSLT, ICmpSLE,
ICmpSGT, ICmpSGE,
And, Or, Not,
GEP, Call,
};
// User 是所有“会使用其他 Value 作为输入”的 IR 对象的抽象基类。
// 当前实现中只有 Instruction 继承自 User。
@ -287,6 +296,26 @@ class StoreInst : public Instruction {
Value* GetPtr() const;
};
class GEPInst : public Instruction {
public:
GEPInst(std::shared_ptr<Type> ptr_ty,
Value* base,
const std::vector<Value*>& indices,
const std::string& name);
Value* GetBase() const;
const std::vector<Value*>& GetIndices() const;
};
class CallInst : public Instruction {
public:
CallInst(std::shared_ptr<Type> ret_ty,
Function* callee,
const std::vector<Value*>& args,
const std::string& name);
Function* GetCallee() const;
const std::vector<Value*>& GetArgs() const;
};
// BasicBlock 已纳入 Value 体系,便于后续向更完整 IR 类图靠拢。
// 当前其类型仍使用 void 作为占位,后续可替换为专门的 label type。
class BasicBlock : public Value {
@ -346,6 +375,7 @@ class Module {
// 创建函数时当前只显式传入返回类型,尚未接入完整的 FunctionType。
Function* CreateFunction(const std::string& name,
std::shared_ptr<Type> ret_type);
Function* FindFunction(const std::string& name) const;
const std::vector<std::unique_ptr<Function>>& GetFunctions() const;
private:
@ -369,6 +399,26 @@ class IRBuilder {
StoreInst* CreateStore(Value* val, Value* ptr);
ReturnInst* CreateRet(Value* v);
BinaryInst* CreateDiv(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateMod(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateMul(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateSub(Value* lhs, Value* rhs, const std::string& name);
// 比较运算接口
BinaryInst* CreateICmpEQ(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateICmpNE(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateICmpSLT(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateICmpSLE(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateICmpSGT(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateICmpSGE(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateAnd(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateOr(Value* lhs, Value* rhs, const std::string& name);
BinaryInst* CreateNot(Value* val, const std::string& name);
GEPInst* CreateGEP(Value* base, const std::vector<Value*>& indices, const std::string& name);
CallInst* CreateCall(Function* callee, const std::vector<Value*>& args, const std::string& name);
private:
Context& ctx_;
BasicBlock* insert_block_;

@ -21,7 +21,7 @@ class Value;
}
class IRGenImpl final : public SysYBaseVisitor {
public:
public:
IRGenImpl(ir::Module& module, const SemanticContext& sema);
// 顶层
@ -29,36 +29,49 @@ class IRGenImpl final : public SysYBaseVisitor {
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
// 块
std::any visitBlock(SysYParser::BlockContext* ctx) override;
std::any visitBlock(SysYParser::BlockContext* ctx) override; // 注意:规则名为 Block
std::any visitBlockItem(SysYParser::BlockItemContext* ctx) override;
// 声明
std::any visitDecl(SysYParser::DeclContext* ctx) override;
std::any visitVarDef(SysYParser::VarDefContext* ctx) override;
std::any visitConstDecl(SysYParser::ConstDeclContext* ctx) override;
std::any visitConstDef(SysYParser::ConstDefContext* ctx) override;
std::any visitInitVal(SysYParser::InitValContext* ctx) override;
std::any visitConstInitVal(SysYParser::ConstInitValContext* ctx) override;
// 语句
std::any visitStmt(SysYParser::StmtContext* ctx) override;
// 表达式
std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) override;
std::any visitExp(SysYParser::ExpContext* ctx) override;
std::any visitCond(SysYParser::CondContext* ctx) override;
std::any visitLVal(SysYParser::LValContext* ctx) override;
std::any visitAddExp(SysYParser::AddExpContext* ctx) override;
std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) override;
std::any visitUnaryExp(SysYParser::UnaryExpContext* ctx) override;
std::any visitFuncRParams(SysYParser::FuncRParamsContext* ctx) override;
std::any visitMulExp(SysYParser::MulExpContext* ctx) override;
std::any visitAddExp(SysYParser::AddExpContext* ctx) override;
std::any visitRelExp(SysYParser::RelExpContext* ctx) override;
std::any visitEqExp(SysYParser::EqExpContext* ctx) override;
std::any visitCond(SysYParser::CondContext* ctx) override;
std::any visitLAndExp(SysYParser::LAndExpContext* ctx) override;
std::any visitLOrExp(SysYParser::LOrExpContext* ctx) override;
std::any visitConstExp(SysYParser::ConstExpContext* ctx) override;
private:
enum class BlockFlow {
// 辅助函数
ir::Value* EvalExpr(SysYParser::ExpContext& expr); // 只保留一处
ir::Value* EvalCond(SysYParser::CondContext& cond);
ir::Value* visitCallExp(SysYParser::UnaryExpContext* ctx);
private:
// 辅助函数声明
enum class BlockFlow{
Continue,
Terminated,
};
BlockFlow VisitBlockItemResult(SysYParser::BlockItemContext& item);
ir::Value* EvalExpr(SysYParser::ExpContext& expr);
ir::Value* EvalCond(SysYParser::CondContext& cond);
// 辅助函数
BlockFlow HandleReturnStmt(SysYParser::StmtContext* ctx);
BlockFlow HandleIfStmt(SysYParser::StmtContext* ctx);
BlockFlow HandleWhileStmt(SysYParser::StmtContext* ctx);
@ -66,20 +79,27 @@ class IRGenImpl final : public SysYBaseVisitor {
BlockFlow HandleContinueStmt(SysYParser::StmtContext* ctx);
BlockFlow HandleAssignStmt(SysYParser::StmtContext* ctx);
ir::Module& module_;
const SemanticContext& sema_;
ir::Function* func_;
ir::IRBuilder builder_;
// 名称绑定由 Sema 负责IRGen 只维护“声明 -> 存储槽位”的代码生成状态。
std::unordered_map<SysYParser::VarDefContext*, ir::Value*> storage_map_;
// 循环栈,用于 break/continue
// 循环上下文结构
struct LoopContext {
ir::BasicBlock* condBlock;
ir::BasicBlock* bodyBlock;
ir::BasicBlock* exitBlock;
};
struct ArrayInfo {
std::vector<ir::Value*> elements;
std::vector<int> dimensions;
};
std::vector<LoopContext> loopStack_;
ir::Module& module_;
const SemanticContext& sema_;
ir::Function* func_;
ir::IRBuilder builder_;
std::unordered_map<SysYParser::VarDefContext*, ir::Value*> storage_map_;
std::unordered_map<SysYParser::VarDefContext*, ArrayInfo> array_info_map_;
};
std::unique_ptr<ir::Module> GenerateIR(SysYParser::CompUnitContext& tree,

@ -86,4 +86,221 @@ ReturnInst* IRBuilder::CreateRet(Value* v) {
return insert_block_->Append<ReturnInst>(Type::GetVoidType(), v);
}
BinaryInst* IRBuilder::CreateDiv(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateDiv 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateDiv 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(Opcode::Div, lhs->GetType(), lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateMod(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateMod 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateMod 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(Opcode::Mod, lhs->GetType(), lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateICmpEQ(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpEQ 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpEQ 缺少 rhs"));
}
// 比较运算返回int32类型0表示假1表示真
return insert_block_->Append<BinaryInst>(Opcode::ICmpEQ, Type::GetInt32Type(), lhs, rhs, name);
}
// 不等于比较
BinaryInst* IRBuilder::CreateICmpNE(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpNE 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpNE 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(Opcode::ICmpNE, Type::GetInt32Type(), lhs, rhs, name);
}
// 有符号小于
BinaryInst* IRBuilder::CreateICmpSLT(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpSLT 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpSLT 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(Opcode::ICmpSLT, Type::GetInt32Type(), lhs, rhs, name);
}
// 有符号小于等于
BinaryInst* IRBuilder::CreateICmpSLE(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpSLE 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpSLE 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(Opcode::ICmpSLE, Type::GetInt32Type(), lhs, rhs, name);
}
// 有符号大于
BinaryInst* IRBuilder::CreateICmpSGT(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpSGT 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpSGT 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(Opcode::ICmpSGT, Type::GetInt32Type(), lhs, rhs, name);
}
// 有符号大于等于
BinaryInst* IRBuilder::CreateICmpSGE(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpSGE 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateICmpSGE 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(Opcode::ICmpSGE, Type::GetInt32Type(), lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateAnd(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateAnd 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateAnd 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(Opcode::And, Type::GetInt32Type(), lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateOr(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateOr 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateOr 缺少 rhs"));
}
return insert_block_->Append<BinaryInst>(Opcode::Or, Type::GetInt32Type(), lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateNot(Value* val, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!val) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateNot 缺少 operand"));
}
auto zero = CreateConstInt(0);
return CreateICmpEQ(val, zero, name);
}
GEPInst* IRBuilder::CreateGEP(Value* base,
const std::vector<Value*>& indices,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!base) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateGEP 缺少 base"));
}
// 检查所有索引
for (size_t i = 0; i < indices.size(); ++i) {
if (!indices[i]) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateGEP 索引 " + std::to_string(i) + " 为空"));
}
}
// GEP返回指针类型假设与base类型相同
return insert_block_->Append<GEPInst>(base->GetType(), base, indices, name);
}
CallInst* IRBuilder::CreateCall(Function* callee,
const std::vector<Value*>& args,
const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!callee) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateCall 缺少 callee"));
}
// 检查所有参数
for (size_t i = 0; i < args.size(); ++i) {
if (!args[i]) {
throw std::runtime_error(
FormatError("ir", "IRBuilder::CreateCall 参数 " + std::to_string(i) + " 为空"));
}
}
// Call返回函数的返回类型
return insert_block_->Append<CallInst>(callee->GetType(), callee, args, name);
}
BinaryInst* IRBuilder::CreateMul(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateMul 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateMul 缺少 rhs"));
}
return CreateBinary(Opcode::Mul, lhs, rhs, name);
}
BinaryInst* IRBuilder::CreateSub(Value* lhs, Value* rhs, const std::string& name) {
if (!insert_block_) {
throw std::runtime_error(FormatError("ir", "IRBuilder 未设置插入点"));
}
if (!lhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateSub 缺少 lhs"));
}
if (!rhs) {
throw std::runtime_error(FormatError("ir", "IRBuilder::CreateSub 缺少 rhs"));
}
return CreateBinary(Opcode::Sub, lhs, rhs, name);
}
} // namespace ir

@ -43,6 +43,32 @@ static const char* OpcodeToString(Opcode op) {
return "store";
case Opcode::Ret:
return "ret";
case Opcode::Div:
return "div";
case Opcode::Mod:
return "mod";
case Opcode::ICmpEQ:
return "icmp eq";
case Opcode::ICmpNE:
return "icmp ne";
case Opcode::ICmpSLT:
return "icmp slt";
case Opcode::ICmpSLE:
return "icmp sle";
case Opcode::ICmpSGT:
return "icmp sgt";
case Opcode::ICmpSGE:
return "icmp sge";
case Opcode::And:
return "and";
case Opcode::Or:
return "or";
case Opcode::Not:
return "not";
case Opcode::GEP:
return "getelementptr";
case Opcode::Call:
return "call";
}
return "?";
}
@ -68,7 +94,18 @@ void IRPrinter::Print(const Module& module, std::ostream& os) {
switch (inst->GetOpcode()) {
case Opcode::Add:
case Opcode::Sub:
case Opcode::Mul: {
case Opcode::Mul:
case Opcode::Div:
case Opcode::Mod:
case Opcode::And:
case Opcode::Not:
case Opcode::Or:
case Opcode::ICmpEQ:
case Opcode::ICmpNE:
case Opcode::ICmpSLT:
case Opcode::ICmpSLE:
case Opcode::ICmpSGT:
case Opcode::ICmpSGE:{
auto* bin = static_cast<const BinaryInst*>(inst);
os << " " << bin->GetName() << " = "
<< OpcodeToString(bin->GetOpcode()) << " "
@ -100,6 +137,33 @@ void IRPrinter::Print(const Module& module, std::ostream& os) {
<< ValueToString(ret->GetValue()) << "\n";
break;
}
case Opcode::GEP:{
// 简化打印:只打印基本信息和操作数数量
os << " " << inst->GetName() << " = getelementptr ";
os << TypeToString(*inst->GetType()) << " (";
for (size_t i = 0; i < inst->GetNumOperands(); ++i) {
if (i > 0) os << ", ";
os << ValueToString(inst->GetOperand(i));
}
os << ")\n";
break;
}
case Opcode::Call:{
// 简化打印:只打印基本信息和操作数数量
os << " " << inst->GetName() << " = call ";
os << TypeToString(*inst->GetType()) << " (";
for (size_t i = 0; i < inst->GetNumOperands(); ++i) {
if (i > 0) os << ", ";
os << ValueToString(inst->GetOperand(i));
}
os << ")\n";
break;
}
default: {
// 处理未知操作码
os << " ; 未知指令: " << OpcodeToString(inst->GetOpcode()) << "\n";
break;
}
}
}
}

@ -148,4 +148,74 @@ Value* StoreInst::GetValue() const { return GetOperand(0); }
Value* StoreInst::GetPtr() const { return GetOperand(1); }
GEPInst::GEPInst(std::shared_ptr<Type> ptr_ty,
Value* base,
const std::vector<Value*>& indices,
const std::string& name)
: Instruction(Opcode::GEP, ptr_ty, name) {
// 添加base作为第一个操作数
AddOperand(base);
// 添加所有索引作为后续操作数
for (auto* index : indices) {
AddOperand(index);
}
}
Value* GEPInst::GetBase() const {
// 第一个操作数是base
return GetOperand(0);
}
const std::vector<Value*>& GEPInst::GetIndices() const {
// 需要返回索引列表但Instruction只存储操作数
// 这是一个设计问题:要么修改架构,要么提供辅助方法
// 简化实现返回空vector或创建临时vector
static std::vector<Value*> indices;
indices.clear();
// 索引从操作数1开始
for (size_t i = 1; i < GetNumOperands(); ++i) {
indices.push_back(GetOperand(i));
}
return indices;
}
// CallInst构造函数实现
CallInst::CallInst(std::shared_ptr<Type> ret_ty,
Function* callee,
const std::vector<Value*>& args,
const std::string& name)
: Instruction(Opcode::Call, ret_ty, name) {
// 添加callee作为第一个操作数
AddOperand(callee);
// 添加所有参数作为后续操作数
for (auto* arg : args) {
AddOperand(arg);
}
}
Function* CallInst::GetCallee() const {
// 第一个操作数是callee
return dynamic_cast<Function*>(GetOperand(0));
}
const std::vector<Value*>& CallInst::GetArgs() const {
// 需要返回参数列表但Instruction只存储操作数
// 简化实现返回空vector或创建临时vector
static std::vector<Value*> args;
args.clear();
// 参数从操作数1开始
for (size_t i = 1; i < GetNumOperands(); ++i) {
args.push_back(GetOperand(i));
}
return args;
}
} // namespace ir

@ -14,6 +14,15 @@ Function* Module::CreateFunction(const std::string& name,
return functions_.back().get();
}
Function* Module::FindFunction(const std::string& name) const {
for (const auto& func : functions_) {
if (func->GetName() == name) {
return func.get();
}
}
return nullptr;
}
const std::vector<std::unique_ptr<Function>>& Module::GetFunctions() const {
return functions_;
}

@ -37,9 +37,53 @@ std::any IRGenImpl::visitDecl(SysYParser::DeclContext* ctx) {
}
}
// 处理 constDecl(暂不支持)
// 处理 constDecl
if (ctx->constDecl()) {
throw std::runtime_error(FormatError("irgen", "常量声明暂未实现"));
auto* constDecl = ctx->constDecl();
if (constDecl->bType() && constDecl->bType()->Int()) {
for (auto* constDef : constDecl->constDef()) {
constDef->accept(this);
}
} else if (constDecl->bType() && constDecl->bType()->Float()) {
throw std::runtime_error(FormatError("irgen", "float常量暂未实现"));
} else {
throw std::runtime_error(FormatError("irgen", "未知的常量类型"));
}
}
return {};
}
// 实现常量定义
std::any IRGenImpl::visitConstDef(SysYParser::ConstDefContext* ctx) {
if (!ctx || !ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "非法常量定义"));
}
std::string const_name = ctx->Ident()->getText();
// 检查是否为数组
bool is_array = !ctx->constExp().empty();
if (is_array) {
// 数组常量
throw std::runtime_error(FormatError("irgen", "数组常量暂未实现"));
} else {
// 标量常量
if (!ctx->constInitVal()) {
throw std::runtime_error(FormatError("irgen", "常量缺少初始值"));
}
// 处理常量初始化值
auto* const_init_val = ctx->constInitVal();
if (const_init_val->constExp()) {
// 常量表达式求值需要语义分析支持
throw std::runtime_error(FormatError("irgen", "常量表达式求值暂未实现"));
} else {
// 聚合初始化
throw std::runtime_error(FormatError("irgen", "常量聚合初始化暂未实现"));
}
}
return {};
@ -61,23 +105,87 @@ std::any IRGenImpl::visitVarDef(SysYParser::VarDefContext* ctx) {
throw std::runtime_error(FormatError("irgen", "声明重复生成存储槽位: " + varName));
}
// 分配存储
auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp());
storage_map_[ctx] = slot;
bool is_array = !ctx->constExp().empty();
ir::Value* init = nullptr;
// 使用 initVal() 而不是 initValue()
if (auto* initVal = ctx->initVal()) {
if (initVal->exp()) {
init = EvalExpr(*initVal->exp());
if (is_array) {
// 数组变量
// 获取数组维度(简化处理)
int array_size = 10; // 默认数组大小
if (!ctx->constExp().empty()) {
// 尝试获取数组大小(需要常量表达式求值)
// 简化假设第一个维度为10
array_size = 10;
}
// 分配数组存储(简化:为每个元素分配独立存储)
if (array_size > 100) {
throw std::runtime_error(FormatError("irgen", "数组大小太大"));
}
std::vector<ir::Value*> element_slots;
for (int i = 0; i < array_size; i++) {
auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp() + "_" + std::to_string(i));
element_slots.push_back(slot);
}
// 处理初始化
if (auto* initVal = ctx->initVal()) {
if (initVal->exp()) {
// 标量初始化(只初始化第一个元素)
ir::Value* init = EvalExpr(*initVal->exp());
builder_.CreateStore(init, element_slots[0]);
// 其他元素初始化为0
for (int i = 1; i < array_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
} else {
// 聚合初始化
throw std::runtime_error(FormatError("irgen", "数组聚合初始化暂未实现"));
}
}else {
// 无初始化所有元素初始化为0
for (int i = 0; i < array_size; i++) {
builder_.CreateStore(builder_.CreateConstInt(0), element_slots[i]);
}
}
// 存储第一个元素的地址
storage_map_[ctx] = element_slots[0];
// 保存数组信息
ArrayInfo info;
info.elements = element_slots;
info.dimensions = {array_size};
array_info_map_[ctx] = info;
} else {
// 标量变量
auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp());
storage_map_[ctx] = slot;
ir::Value* init = nullptr;
if (auto* initVal = ctx->initVal()) {
if (initVal->exp()) {
init = EvalExpr(*initVal->exp());
} else {
// 聚合初始化(对于标量,大括号内应该只有一个值)
auto initVals = initVal->initVal();
if (initVals.empty()) {
init = builder_.CreateConstInt(0);
} else if (initVals.size() == 1) {
init = std::any_cast<ir::Value*>(initVals[0]->accept(this));
} else {
throw std::runtime_error(
FormatError("irgen", "标量变量聚合初始化只能有一个值"));
}
}
} else {
// 数组初始化暂不支持
init = builder_.CreateConstInt(0);
}
} else {
init = builder_.CreateConstInt(0);
builder_.CreateStore(init, slot);
}
builder_.CreateStore(init, slot);
return {};
}

@ -105,100 +105,255 @@ std::any IRGenImpl::visitLVal(SysYParser::LValContext* ctx) {
// 加法表达式
std::any IRGenImpl::visitAddExp(SysYParser::AddExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法加法表达式"));
}
// 注意mulExp() 返回的是 MulExpContext*,不是 vector
// 需要递归处理 AddExp 的左结合性
// AddExp : MulExp | AddExp ('+' | '-') MulExp
// 先处理左操作数
ir::Value* result = nullptr;
// 如果有左子节点AddExp递归处理
if (ctx->addExp()) {
result = std::any_cast<ir::Value*>(ctx->addExp()->accept(this));
} else {
// 否则是 MulExp
result = std::any_cast<ir::Value*>(ctx->mulExp()->accept(this));
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法加法表达式"));
if (!ctx->addExp()) {
return ctx->mulExp()->accept(this);
}
// 如果有运算符和右操作数
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());
}
ir::Value* left = std::any_cast<ir::Value*>(ctx->addExp()->accept(this));
ir::Value* right = std::any_cast<ir::Value*>(ctx->mulExp()->accept(this));
if (ctx->AddOp()) {
return builder_.CreateAdd(left, right, module_.GetContext().NextTemp());
} else if (ctx->SubOp()) {
return builder_.CreateSub(left, right, module_.GetContext().NextTemp());
}
return static_cast<ir::Value*>(result);
throw std::runtime_error(FormatError("irgen", "未知的加法操作符"));
}
// 在 IRGenExp.cpp 中添加
// 简化版 visitMulExp
// visitMulExp
std::any IRGenImpl::visitMulExp(SysYParser::MulExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法乘法表达式"));
}
// 暂时只返回 unaryExp 的值
if (ctx->unaryExp()) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法乘法表达式"));
// 如果是基本形式 UnaryExp
if (!ctx->mulExp()) {
return ctx->unaryExp()->accept(this);
}
// 如果有 mulExp 子节点,递归处理
if (ctx->mulExp()) {
return ctx->mulExp()->accept(this);
// 否则有左子节点和操作符
ir::Value* left = std::any_cast<ir::Value*>(ctx->mulExp()->accept(this));
ir::Value* right = std::any_cast<ir::Value*>(ctx->unaryExp()->accept(this));
std::string op;
if (ctx->MulOp()) op = "*";
else if (ctx->DivOp()) op = "/";
else if (ctx->QuoOp()) op = "%";
else throw std::runtime_error(FormatError("irgen", "缺少乘法类操作符"));
if (op == "*") {
return builder_.CreateMul(left, right, module_.GetContext().NextTemp());
} else if (op == "/") {
return builder_.CreateDiv(left, right, module_.GetContext().NextTemp());
} else if (op == "%") {
return builder_.CreateMod(left, right, module_.GetContext().NextTemp());
}
throw std::runtime_error(FormatError("irgen", "乘法表达式暂未实现"));
throw std::runtime_error(FormatError("irgen", "未知的乘法操作符"));
}
// 关系表达式(暂未完整实现)
// 关系表达式
std::any IRGenImpl::visitRelExp(SysYParser::RelExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法关系表达式"));
}
// 简化:返回 addExp 的值
if (ctx->addExp()) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法关系表达式"));
if (!ctx->relExp()) {
return ctx->addExp()->accept(this);
}
throw std::runtime_error(FormatError("irgen", "关系表达式暂未实现"));
ir::Value* left = std::any_cast<ir::Value*>(ctx->relExp()->accept(this));
ir::Value* right = std::any_cast<ir::Value*>(ctx->addExp()->accept(this));
if (ctx->LOp()) {
return builder_.CreateICmpSLT(left, right, module_.GetContext().NextTemp());
} else if (ctx->GOp()) {
return builder_.CreateICmpSGT(left, right, module_.GetContext().NextTemp());
} else if (ctx->LeOp()) {
return builder_.CreateICmpSLE(left, right, module_.GetContext().NextTemp());
} else if (ctx->GeOp()) {
return builder_.CreateICmpSGE(left, right, module_.GetContext().NextTemp());
}
throw std::runtime_error(FormatError("irgen", "未知的关系操作符"));
}
// 相等表达式(暂未完整实现)
// 相等表达式
std::any IRGenImpl::visitEqExp(SysYParser::EqExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法相等表达式"));
}
// 简化:返回 relExp 的值
if (ctx->relExp()) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法相等表达式"));
if (!ctx->eqExp()) {
return ctx->relExp()->accept(this);
}
throw std::runtime_error(FormatError("irgen", "相等表达式暂未实现"));
ir::Value* left = std::any_cast<ir::Value*>(ctx->eqExp()->accept(this));
ir::Value* right = std::any_cast<ir::Value*>(ctx->relExp()->accept(this));
if (ctx->EqOp()) {
return builder_.CreateICmpEQ(left, right, module_.GetContext().NextTemp());
} else if (ctx->NeOp()) {
return builder_.CreateICmpNE(left, right, module_.GetContext().NextTemp());
}
throw std::runtime_error(FormatError("irgen", "未知的相等操作符"));
}
// 逻辑与
std::any IRGenImpl::visitLAndExp(SysYParser::LAndExpContext* ctx) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法逻辑与表达式"));
if (!ctx->lAndExp()) {
return ctx->eqExp()->accept(this);
}
ir::Value* left = std::any_cast<ir::Value*>(ctx->lAndExp()->accept(this));
ir::Value* right = std::any_cast<ir::Value*>(ctx->eqExp()->accept(this));
auto zero = builder_.CreateConstInt(0);
auto left_bool = builder_.CreateICmpNE(left, zero, module_.GetContext().NextTemp());
auto right_bool = builder_.CreateICmpNE(right, zero, module_.GetContext().NextTemp());
return builder_.CreateAnd(left_bool, right_bool, module_.GetContext().NextTemp());
}
// 逻辑或
std::any IRGenImpl::visitLOrExp(SysYParser::LOrExpContext* ctx) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法逻辑或表达式"));
if (!ctx->lOrExp()) {
return ctx->lAndExp()->accept(this);
}
ir::Value* left = std::any_cast<ir::Value*>(ctx->lOrExp()->accept(this));
ir::Value* right = std::any_cast<ir::Value*>(ctx->lAndExp()->accept(this));
auto zero = builder_.CreateConstInt(0);
auto left_bool = builder_.CreateICmpNE(left, zero, module_.GetContext().NextTemp());
auto right_bool = builder_.CreateICmpNE(right, zero, module_.GetContext().NextTemp());
return builder_.CreateOr(left_bool, right_bool, module_.GetContext().NextTemp());
}
std::any IRGenImpl::visitExp(SysYParser::ExpContext* ctx) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法表达式"));
return ctx->addExp()->accept(this);
}
// 条件表达式
std::any IRGenImpl::visitCond(SysYParser::CondContext* ctx) {
if (!ctx) throw std::runtime_error(FormatError("irgen", "非法条件表达式"));
return ctx->lOrExp()->accept(this);
}
ir::Value* IRGenImpl::visitCallExp(SysYParser::UnaryExpContext* ctx) {
if (!ctx || !ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "非法函数调用"));
}
std::string funcName = ctx->Ident()->getText();
// 语义检查(如果需要)
// auto* funcDecl = sema_.ResolveFuncCall(ctx);
// if (!funcDecl) throw ...
// 收集实参
std::vector<ir::Value*> args;
if (ctx->funcRParams()) {
auto argList = ctx->funcRParams()->accept(this);
args = std::any_cast<std::vector<ir::Value*>>(argList);
}
// 查找函数对象
ir::Function* callee = module_.FindFunction(funcName);
if (!callee) {
throw std::runtime_error(FormatError("irgen", "未找到函数: " + funcName));
}
// 生成调用指令
return builder_.CreateCall(callee, args, module_.GetContext().NextTemp());
}
// 实现一元表达式
std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
if (!ctx) {
throw std::runtime_error(FormatError("irgen", "非法条件表达式"));
throw std::runtime_error(FormatError("irgen", "非法一元表达式"));
}
// 基本表达式
if (ctx->primaryExp()) {
return ctx->primaryExp()->accept(this);
}
// 简化:返回 lOrExp 的值
if (ctx->lOrExp()) {
return ctx->lOrExp()->accept(this);
// 函数调用
if (ctx->Ident()) {
return visitCallExp(ctx);
}
throw std::runtime_error(FormatError("irgen", "条件表达式暂未实现"));
// 一元运算
if (ctx->unaryOp() && ctx->unaryExp()) {
auto* operand = std::any_cast<ir::Value*>(ctx->unaryExp()->accept(this));
std::string op = ctx->unaryOp()->getText();
if (op == "+") {
// +x 等价于 x
return operand;
} else if (op == "-") {
// -x 等价于 0 - x
ir::Value* zero = builder_.CreateConstInt(0);
return static_cast<ir::Value*>(
builder_.CreateBinary(ir::Opcode::Sub, zero, operand,
module_.GetContext().NextTemp()));
} else if (op == "!") {
return builder_.CreateNot(operand, module_.GetContext().NextTemp());
}
}
throw std::runtime_error(FormatError("irgen", "暂不支持的一元表达式形式"));
}
// 实现函数调用
std::any IRGenImpl::visitFuncRParams(SysYParser::FuncRParamsContext* ctx) {
if (!ctx) return std::vector<ir::Value*>{};
std::vector<ir::Value*> args;
for (auto* exp : ctx->exp()) {
args.push_back(EvalExpr(*exp));
}
return args;
}
std::any IRGenImpl::visitConstDecl(SysYParser::ConstDeclContext* ctx) {
// 常量声明在编译时求值,不分配存储。只需遍历常量定义,将常量值存入符号表即可。
// 由于 IRGen 阶段不需要常量的存储槽位,这里只触发子节点访问(常量定义会处理值)。
for (auto* constDef : ctx->constDef()) {
constDef->accept(this);
}
return {};
}
std::any IRGenImpl::visitConstInitVal(SysYParser::ConstInitValContext* ctx) {
// 常量初始化值可能是单一常量表达式,也可能是大括号列表(聚合)。
// 为简化,我们仅支持单一表达式(标量常量),数组常量暂未实现。
if (ctx->constExp()) {
// 常量表达式求值:需要语义分析支持常量折叠,这里我们返回求值后的常量值。
// 假设 sema_ 有方法 EvaluateConstExp 返回 int。
auto* constExp = ctx->constExp();
// 通过语义分析求值(暂未实现,先抛异常)
// int val = sema_.EvaluateConstExp(constExp);
// return builder_.CreateConstInt(val);
throw std::runtime_error(FormatError("irgen", "常量表达式求值暂未实现"));
} else {
// 聚合初始化:返回数组值,暂未实现
throw std::runtime_error(FormatError("irgen", "常量聚合初始化暂未实现"));
}
}
std::any IRGenImpl::visitInitVal(SysYParser::InitValContext* ctx) {
// 返回初始化的值(可能是单个表达式或聚合列表)
if (ctx->exp()) {
return EvalExpr(*ctx->exp());
} else {
// 聚合初始化:需要返回一个列表,暂未实现
throw std::runtime_error(FormatError("irgen", "聚合初始化暂未实现"));
}
}
std::any IRGenImpl::visitConstExp(SysYParser::ConstExpContext* ctx) {
// 常量表达式由 AddExp 构成,我们直接复用表达式求值(但需要常量折叠)。
// 由于常量表达式在编译时求值IR 生成阶段其实不需要计算值,语义分析会提供。
// 这里我们只用来获取 IR 值(例如数组大小),但数组大小需要在 IR 生成前就知道。
// 暂时复用 EvalExpr但 EvalExpr 生成 IR 指令这不合适。实际上常量表达式应在语义分析阶段求值IRGen 直接使用结果。
// 为避免复杂,我们暂时返回表达式的 IR 值(但会产生计算指令,不适合数组大小)。
// 更好的做法是调用语义分析求值。
// 这里先抛异常,等待语义团队提供接口。
throw std::runtime_error(FormatError("irgen", "常量表达式求值暂未实现"));
}

Loading…
Cancel
Save