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.

45 lines
1.7 KiB

#include "irgen/IRGen.h"
#include <stdexcept>
#include "SysYParser.h"
#include "ir/IR.h"
#include "utils/Log.h"
ir::Value* IRGenImpl::GenExpr(SysYParser::ExpContext& expr) {
if (auto* paren = dynamic_cast<SysYParser::ParenExpContext*>(&expr)) {
return GenExpr(*paren->exp());
}
if (auto* number = dynamic_cast<SysYParser::NumberExpContext*>(&expr)) {
if (!number->number() || !number->number()->ILITERAL()) {
throw std::runtime_error(FormatError("irgen", "当前仅支持整数字面量"));
}
return builder_.CreateConstInt(std::stoi(number->number()->getText()));
}
if (auto* var = dynamic_cast<SysYParser::VarExpContext*>(&expr)) {
if (!var->var() || !var->var()->ID()) {
throw std::runtime_error(FormatError("irgen", "当前仅支持普通整型变量"));
}
auto* decl = sema_.ResolveVarUse(var->var());
if (!decl) {
throw std::runtime_error(
FormatError("irgen",
"变量使用缺少语义绑定: " + var->var()->ID()->getText()));
}
auto it = storage_map_.find(decl);
if (it == storage_map_.end()) {
throw std::runtime_error(
FormatError("irgen",
"变量声明缺少存储槽位: " + var->var()->ID()->getText()));
}
return builder_.CreateLoad(it->second, module_.GetContext().NextTemp());
}
if (auto* binary = dynamic_cast<SysYParser::AdditiveExpContext*>(&expr)) {
ir::Value* lhs = GenExpr(*binary->exp(0));
ir::Value* rhs = GenExpr(*binary->exp(1));
return builder_.CreateBinary(ir::Opcode::Add, lhs, rhs,
module_.GetContext().NextTemp());
}
throw std::runtime_error(FormatError("irgen", "暂不支持的表达式形式"));
}