style(ir): 纠正代码位置
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "SysYParser.h"
|
||||
#include "ir/IR.h"
|
||||
#include "sem/Sema.h"
|
||||
|
||||
namespace antlr4 {
|
||||
namespace tree {
|
||||
@@ -25,7 +26,7 @@ class Value;
|
||||
|
||||
class IRGenImpl {
|
||||
public:
|
||||
explicit IRGenImpl(ir::Module& module);
|
||||
IRGenImpl(ir::Module& module, const SemanticContext& sema);
|
||||
|
||||
void Gen(SysYParser::CompUnitContext& cu);
|
||||
|
||||
@@ -43,10 +44,12 @@ class IRGenImpl {
|
||||
ir::Value* GenPrimary(SysYParser::PrimaryContext& primary);
|
||||
|
||||
ir::Module& module_;
|
||||
const SemanticContext& sema_;
|
||||
ir::Function* func_;
|
||||
ir::IRBuilder builder_;
|
||||
// 当前只维护函数级局部变量表;若后续引入嵌套块作用域,需要改成作用域栈。
|
||||
std::unordered_map<std::string, ir::Value*> locals_;
|
||||
// 名称绑定由 Sema 负责;IRGen 只维护“声明 -> 存储槽位”的代码生成状态。
|
||||
std::unordered_map<SysYParser::VarDeclContext*, ir::Value*> storage_map_;
|
||||
};
|
||||
|
||||
std::unique_ptr<ir::Module> GenerateIR(antlr4::tree::ParseTree* tree);
|
||||
std::unique_ptr<ir::Module> GenerateIR(SysYParser::CompUnitContext& tree,
|
||||
const SemanticContext& sema);
|
||||
|
||||
@@ -36,12 +36,11 @@ void IRGenImpl::GenDecl(SysYParser::DeclContext& decl) {
|
||||
}
|
||||
|
||||
void IRGenImpl::GenVarDecl(SysYParser::VarDeclContext& decl) {
|
||||
const std::string name = decl.Ident()->getText();
|
||||
if (locals_.find(name) != locals_.end()) {
|
||||
throw std::runtime_error("[irgen] 重复定义变量: " + name);
|
||||
if (storage_map_.find(&decl) != storage_map_.end()) {
|
||||
throw std::runtime_error("[irgen] 声明重复生成存储槽位");
|
||||
}
|
||||
auto* slot = builder_.CreateAllocaI32(ir::DefaultContext().NextTemp());
|
||||
locals_[name] = slot;
|
||||
storage_map_[&decl] = slot;
|
||||
|
||||
ir::Value* init = nullptr;
|
||||
if (decl.exp()) {
|
||||
|
||||
@@ -4,21 +4,12 @@
|
||||
#include <stdexcept>
|
||||
|
||||
#include "SysYParser.h"
|
||||
#include "antlr4-runtime.h"
|
||||
#include "ir/IR.h"
|
||||
|
||||
std::unique_ptr<ir::Module> GenerateIR(antlr4::tree::ParseTree* tree) {
|
||||
if (!tree) {
|
||||
throw std::runtime_error("[irgen] 语法树为空");
|
||||
}
|
||||
|
||||
auto* cu = dynamic_cast<SysYParser::CompUnitContext*>(tree);
|
||||
if (!cu) {
|
||||
throw std::runtime_error("[irgen] 语法树根节点不是 compUnit");
|
||||
}
|
||||
|
||||
std::unique_ptr<ir::Module> GenerateIR(SysYParser::CompUnitContext& tree,
|
||||
const SemanticContext& sema) {
|
||||
auto module = std::make_unique<ir::Module>();
|
||||
IRGenImpl gen(*module);
|
||||
gen.Gen(*cu);
|
||||
IRGenImpl gen(*module, sema);
|
||||
gen.Gen(tree);
|
||||
return module;
|
||||
}
|
||||
|
||||
@@ -33,10 +33,15 @@ ir::Value* IRGenImpl::GenPrimary(SysYParser::PrimaryContext& primary) {
|
||||
return ir::DefaultContext().GetConstInt(std::stoi(primary.Number()->getText()));
|
||||
}
|
||||
if (primary.Ident()) {
|
||||
const std::string name = primary.Ident()->getText();
|
||||
auto it = locals_.find(name);
|
||||
if (it == locals_.end()) {
|
||||
throw std::runtime_error("[irgen] 变量未找到: " + name);
|
||||
auto* decl = sema_.ResolveVarUse(&primary);
|
||||
if (!decl) {
|
||||
throw std::runtime_error("[irgen] 变量使用缺少语义绑定: " +
|
||||
primary.Ident()->getText());
|
||||
}
|
||||
auto it = storage_map_.find(decl);
|
||||
if (it == storage_map_.end()) {
|
||||
throw std::runtime_error("[irgen] 变量声明缺少存储槽位: " +
|
||||
primary.Ident()->getText());
|
||||
}
|
||||
return builder_.CreateLoad(it->second, ir::DefaultContext().NextTemp());
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ void VerifyFunctionStructure(const ir::Function& func) {
|
||||
|
||||
} // namespace
|
||||
|
||||
IRGenImpl::IRGenImpl(ir::Module& module)
|
||||
: module_(module), func_(nullptr), builder_(nullptr) {}
|
||||
IRGenImpl::IRGenImpl(ir::Module& module, const SemanticContext& sema)
|
||||
: module_(module), sema_(sema), func_(nullptr), builder_(nullptr) {}
|
||||
|
||||
void IRGenImpl::Gen(SysYParser::CompUnitContext& cu) {
|
||||
if (!cu.funcDef()) {
|
||||
@@ -39,7 +39,7 @@ void IRGenImpl::GenFuncDef(SysYParser::FuncDefContext& func) {
|
||||
|
||||
func_ = module_.CreateFunction(func.Ident()->getText(), ir::Type::Int32());
|
||||
builder_.SetInsertPoint(func_->entry());
|
||||
locals_.clear();
|
||||
storage_map_.clear();
|
||||
|
||||
GenBlock(*func.block());
|
||||
// 语义正确性主要由 sema 保证,这里只兜底检查 IR 结构是否合法。
|
||||
|
||||
Reference in New Issue
Block a user