函数调用

feature/sem
potapo 3 weeks ago
parent 700bbb4e3b
commit d9201de428

@ -65,9 +65,11 @@ public:
// 辅助函数
ir::Value* EvalExpr(SysYParser::ExpContext& expr); // 只保留一处
ir::Value* EvalCond(SysYParser::CondContext& cond);
ir::Value* visitCallExp(SysYParser::UnaryExpContext* ctx);
std::any visitCallExp(SysYParser::UnaryExpContext* ctx);
std::vector<ir::Value*> ProcessNestedInitVals(SysYParser::InitValContext* ctx);
int TryEvaluateConstInt(SysYParser::ConstExpContext* ctx);
void AddRuntimeFunctions();
ir::Function* CreateRuntimeFunctionDecl(const std::string& funcName);
private:
// 辅助函数声明
enum class BlockFlow{

File diff suppressed because it is too large Load Diff

@ -343,34 +343,120 @@ std::any IRGenImpl::visitCond(SysYParser::CondContext* ctx) {
return ctx->lOrExp()->accept(this);
}
ir::Value* IRGenImpl::visitCallExp(SysYParser::UnaryExpContext* ctx) {
std::any IRGenImpl::visitCallExp(SysYParser::UnaryExpContext* ctx) {
if (!ctx || !ctx->Ident()) {
throw std::runtime_error(FormatError("irgen", "非法函数调用"));
}
std::string funcName = ctx->Ident()->getText();
std::cout << "[DEBUG IRGEN] visitCallExp: 调用函数 " << funcName << std::endl;
// 语义检查(如果需要)
// auto* funcDecl = sema_.ResolveFuncCall(ctx);
// if (!funcDecl) throw ...
// 查找函数对象
ir::Function* callee = module_.FindFunction(funcName);
// 如果没找到,可能是运行时函数还没声明,尝试动态声明
if (!callee) {
std::cout << "[DEBUG IRGEN] 函数 " << funcName << " 未找到,尝试动态声明" << std::endl;
// 根据函数名动态创建运行时函数声明
callee = CreateRuntimeFunctionDecl(funcName);
if (!callee) {
throw std::runtime_error(FormatError("irgen", "未找到函数: " + funcName));
}
}
// 收集实参
std::vector<ir::Value*> args;
if (ctx->funcRParams()) {
auto argList = ctx->funcRParams()->accept(this);
args = std::any_cast<std::vector<ir::Value*>>(argList);
try {
args = std::any_cast<std::vector<ir::Value*>>(argList);
std::cout << "[DEBUG IRGEN] visitCallExp: 收集到 " << args.size() << " 个参数" << std::endl;
} catch (const std::bad_any_cast& e) {
std::cerr << "[ERROR] visitCallExp: 函数调用参数类型错误: " << e.what() << std::endl;
}
}
// 查找函数对象
ir::Function* callee = module_.FindFunction(funcName);
if (!callee) {
throw std::runtime_error(FormatError("irgen", "未找到函数: " + funcName));
// 生成调用指令
ir::Value* callResult = builder_.CreateCall(callee, args, module_.GetContext().NextTemp());
// 如果函数返回 void返回一个默认值用于表达式上下文
if (callResult->GetType()->IsVoid()) {
// void 函数调用不产生值,但我们返回一个 0 常量以保持类型一致性
return static_cast<ir::Value*>(builder_.CreateConstInt(0));
}
std::cout << "[DEBUG IRGEN] visitCallExp: 函数调用完成,返回值 " << (void*)callResult << std::endl;
return static_cast<ir::Value*>(callResult);
}
// 生成调用指令
return builder_.CreateCall(callee, args, module_.GetContext().NextTemp());
// 动态创建运行时函数声明的辅助函数
ir::Function* IRGenImpl::CreateRuntimeFunctionDecl(const std::string& funcName) {
std::cout << "[DEBUG IRGEN] CreateRuntimeFunctionDecl: " << funcName << std::endl;
// 根据常见运行时函数名创建对应的函数类型
if (funcName == "getint" || funcName == "getch") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(ir::Type::GetInt32Type(), {}));
}
else if (funcName == "putint" || funcName == "putch") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type()}));
}
else if (funcName == "getarray") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetInt32Type(),
{ir::Type::GetPtrInt32Type(), ir::Type::GetInt32Type()}));
}
else if (funcName == "putarray") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type(), ir::Type::GetPtrInt32Type()}));
}
else if (funcName == "puts") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetPtrInt32Type()}));
}
else if (funcName == "starttime" || funcName == "stoptime") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(ir::Type::GetVoidType(), {}));
}
else if (funcName == "_sysy_starttime" || funcName == "_sysy_stoptime") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type()}));
}
else if (funcName == "read_map") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(ir::Type::GetInt32Type(), {}));
}
else if (funcName == "float_eq") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetInt32Type(),
{ir::Type::GetFloatType(), ir::Type::GetFloatType()}));
}
else if (funcName == "memset") {
return module_.CreateFunction(funcName,
ir::Type::GetFunctionType(
ir::Type::GetPtrInt32Type(),
{ir::Type::GetPtrInt32Type(),
ir::Type::GetInt32Type(),
ir::Type::GetInt32Type()}));
}
// 其他函数不支持动态创建
return nullptr;
}
// 实现一元表达式
std::any IRGenImpl::visitUnaryExp(SysYParser::UnaryExpContext* ctx) {
if (!ctx) {

@ -26,7 +26,83 @@ IRGenImpl::IRGenImpl(ir::Module& module, const SemanticContext& sema)
: module_(module),
sema_(sema),
func_(nullptr),
builder_(module.GetContext(), nullptr) {}
builder_(module.GetContext(), nullptr) {
AddRuntimeFunctions();
}
void IRGenImpl::AddRuntimeFunctions() {
std::cout << "[DEBUG IRGEN] 添加运行时库函数声明" << std::endl;
// 输入函数(返回 int
module_.CreateFunction("getint",
ir::Type::GetFunctionType(ir::Type::GetInt32Type(), {}));
module_.CreateFunction("getch",
ir::Type::GetFunctionType(ir::Type::GetInt32Type(), {}));
// getarray(int* a, int n): int
module_.CreateFunction("getarray",
ir::Type::GetFunctionType(
ir::Type::GetInt32Type(),
{ir::Type::GetPtrInt32Type(), ir::Type::GetInt32Type()}));
// 输出函数(返回 void
module_.CreateFunction("putint",
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type()}));
module_.CreateFunction("putch",
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type()}));
// putarray(int n, int* a): void
module_.CreateFunction("putarray",
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type(), ir::Type::GetPtrInt32Type()}));
// 字符串输出(暂时用 int* 替代 char*
module_.CreateFunction("puts",
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetPtrInt32Type()}));
// 时间测量函数SysY 标准库)
module_.CreateFunction("_sysy_starttime",
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type()}));
module_.CreateFunction("_sysy_stoptime",
ir::Type::GetFunctionType(
ir::Type::GetVoidType(),
{ir::Type::GetInt32Type()}));
// 简化版本
module_.CreateFunction("starttime",
ir::Type::GetFunctionType(ir::Type::GetVoidType(), {}));
module_.CreateFunction("stoptime",
ir::Type::GetFunctionType(ir::Type::GetVoidType(), {}));
// 其他可能需要的函数
module_.CreateFunction("read_map",
ir::Type::GetFunctionType(ir::Type::GetInt32Type(), {}));
// 浮点数
module_.CreateFunction("float_eq",
ir::Type::GetFunctionType(
ir::Type::GetInt32Type(),
{ir::Type::GetFloatType(), ir::Type::GetFloatType()}));
// 内存操作函数
module_.CreateFunction("memset",
ir::Type::GetFunctionType(
ir::Type::GetPtrInt32Type(),
{ir::Type::GetPtrInt32Type(),
ir::Type::GetInt32Type(),
ir::Type::GetInt32Type()}));
std::cout << "[DEBUG IRGEN] 运行时库函数声明完成" << std::endl;
}
// 修正:没有 mainFuncDef通过函数名找到 main
std::any IRGenImpl::visitCompUnit(SysYParser::CompUnitContext* ctx) {

Loading…
Cancel
Save