|
|
|
|
@ -7,49 +7,38 @@
|
|
|
|
|
#include "utils/Log.h"
|
|
|
|
|
|
|
|
|
|
ir::Value* IRGenImpl::GenExpr(SysYParser::ExpContext& expr) {
|
|
|
|
|
if (!expr.addExp()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "非法表达式"));
|
|
|
|
|
if (auto* paren = dynamic_cast<SysYParser::ParenExpContext*>(&expr)) {
|
|
|
|
|
return GenExpr(*paren->exp());
|
|
|
|
|
}
|
|
|
|
|
return GenAddExpr(*expr.addExp());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ir::Value* IRGenImpl::GenAddExpr(SysYParser::AddExpContext& add) {
|
|
|
|
|
// 当前表达式层次仍是最小实现,直接贴合 addExp -> primary 的语法形状。
|
|
|
|
|
const auto& terms = add.primary();
|
|
|
|
|
if (terms.empty()) {
|
|
|
|
|
throw std::runtime_error(FormatError("irgen", "空加法表达式"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ir::Value* acc = GenPrimary(*terms[0]);
|
|
|
|
|
for (size_t i = 1; i < terms.size(); ++i) {
|
|
|
|
|
ir::Value* rhs = GenPrimary(*terms[i]);
|
|
|
|
|
std::string name = module_.GetContext().NextTemp();
|
|
|
|
|
acc = builder_.CreateBinary(ir::Opcode::Add, acc, rhs, name);
|
|
|
|
|
}
|
|
|
|
|
return acc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ir::Value* IRGenImpl::GenPrimary(SysYParser::PrimaryContext& primary) {
|
|
|
|
|
if (primary.Number()) {
|
|
|
|
|
return builder_.CreateConstInt(std::stoi(primary.Number()->getText()));
|
|
|
|
|
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 (primary.Ident()) {
|
|
|
|
|
auto* decl = sema_.ResolveVarUse(&primary);
|
|
|
|
|
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",
|
|
|
|
|
"变量使用缺少语义绑定: " + primary.Ident()->getText()));
|
|
|
|
|
"变量使用缺少语义绑定: " + var->var()->ID()->getText()));
|
|
|
|
|
}
|
|
|
|
|
auto it = storage_map_.find(decl);
|
|
|
|
|
if (it == storage_map_.end()) {
|
|
|
|
|
throw std::runtime_error(
|
|
|
|
|
FormatError("irgen",
|
|
|
|
|
"变量声明缺少存储槽位: " + primary.Ident()->getText()));
|
|
|
|
|
"变量声明缺少存储槽位: " + var->var()->ID()->getText()));
|
|
|
|
|
}
|
|
|
|
|
return builder_.CreateLoad(it->second, module_.GetContext().NextTemp());
|
|
|
|
|
}
|
|
|
|
|
if (primary.exp()) {
|
|
|
|
|
return GenExpr(*primary.exp());
|
|
|
|
|
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", "暂不支持的表达式形式"));
|
|
|
|
|
}
|
|
|
|
|
|