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.

55 lines
1.4 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) {
const std::string name = decl.Ident()->getText();
if (locals_.find(name) != locals_.end()) {
throw std::runtime_error(FormatError("irgen", "重复定义变量: " + name));
}
auto* slot = builder_.CreateAllocaI32(ir::DefaultContext().NextTemp());
locals_[name] = slot;
ir::Value* init = nullptr;
if (decl.exp()) {
init = GenExpr(*decl.exp());
} else {
init = ir::DefaultContext().GetConstInt(0);
}
builder_.CreateStore(init, slot);
}