forked from NUDT-compiler/nudt-compiler-cpp
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.
54 lines
1.3 KiB
54 lines
1.3 KiB
#include "irgen/IRGen.h"
|
|
|
|
#include <stdexcept>
|
|
|
|
#include "SysYParser.h"
|
|
#include "ir/IR.h"
|
|
#include "utils/Log.h"
|
|
|
|
void IRGenImpl::GenBlock(SysYParser::BlockContext& block) {
|
|
for (auto* item : block.blockItem()) {
|
|
if (item) {
|
|
if (GenBlockItem(*item)) {
|
|
// 当前语法要求 return 为块内最后一条语句;命中后可停止生成。
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool IRGenImpl::GenBlockItem(SysYParser::BlockItemContext& item) {
|
|
if (item.decl()) {
|
|
GenDecl(*item.decl());
|
|
return false;
|
|
}
|
|
if (item.stmt()) {
|
|
return GenStmt(*item.stmt());
|
|
}
|
|
throw std::runtime_error(FormatError("irgen", "暂不支持的语句或声明"));
|
|
}
|
|
|
|
void IRGenImpl::GenDecl(SysYParser::DeclContext& decl) {
|
|
if (decl.varDecl()) {
|
|
GenVarDecl(*decl.varDecl());
|
|
return;
|
|
}
|
|
throw std::runtime_error(FormatError("irgen", "暂不支持的声明类型"));
|
|
}
|
|
|
|
void IRGenImpl::GenVarDecl(SysYParser::VarDeclContext& decl) {
|
|
if (storage_map_.find(&decl) != storage_map_.end()) {
|
|
throw std::runtime_error(FormatError("irgen", "声明重复生成存储槽位"));
|
|
}
|
|
auto* slot = builder_.CreateAllocaI32(module_.GetContext().NextTemp());
|
|
storage_map_[&decl] = slot;
|
|
|
|
ir::Value* init = nullptr;
|
|
if (decl.exp()) {
|
|
init = GenExpr(*decl.exp());
|
|
} else {
|
|
init = builder_.CreateConstInt(0);
|
|
}
|
|
builder_.CreateStore(init, slot);
|
|
}
|