From ec8deeeebfaba9f3461e4c762a934340e61c56dc Mon Sep 17 00:00:00 2001 From: ladev789 Date: Wed, 2 Apr 2025 18:40:01 +0800 Subject: [PATCH] [lab2][night release]temporary stable version 0.1 --- src/SysYIRGenerator.cpp | 103 +++++++++++++++++++++++++++++++--------- src/SysYIRGenerator.h | 2 + test/01_add.sy | 38 ++------------- 3 files changed, 86 insertions(+), 57 deletions(-) diff --git a/src/SysYIRGenerator.cpp b/src/SysYIRGenerator.cpp index 63a4bd7..27eb9af 100644 --- a/src/SysYIRGenerator.cpp +++ b/src/SysYIRGenerator.cpp @@ -1,7 +1,11 @@ // SysYIRGenerator.cpp +// TODO:类型转换及其检查 +// TODO:sysy库函数处理 +// TODO:数组处理 +// TODO:对while、continue、break的测试 #include "SysYIRGenerator.h" #include -// #TODO浮点数精度还是有问题 + std::string SysYIRGenerator::generateIR(SysYParser::CompUnitContext* unit) { visitCompUnit(unit); return irStream.str(); @@ -26,22 +30,83 @@ std::any SysYIRGenerator::visitCompUnit(SysYParser::CompUnitContext* ctx) { decl->accept(this); } for (auto funcDef : ctx->funcDef()) { + inFunction = true; // 进入函数定义 funcDef->accept(this); + inFunction = false; // 离开函数定义 + } + return nullptr; +} + +std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext* ctx) { + // TODO:数组初始化 + std::string type = ctx->bType()->getText(); + currentVarType = getLLVMType(type); + + for (auto varDef : ctx->varDef()) { + if (!inFunction) { + // 全局变量声明 + std::string varName = varDef->Ident()->getText(); + std::string llvmType = getLLVMType(type); + std::string value = "0"; // 默认值为 0 + + if (varDef->ASSIGN()) { + value = std::any_cast(varDef->initVal()->accept(this)); + } + + irStream << "@" << varName << " = dso_local global " << llvmType << " " << value << ", align 4\n"; + globalVars.push_back(varName); // 记录全局变量 + } else { + // 局部变量声明 + varDef->accept(this); + } } return nullptr; } std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext* ctx) { + // TODO:数组初始化 std::string type = ctx->bType()->getText(); for (auto constDef : ctx->constDef()) { - std::string varName = constDef->Ident()->getText(); - std::string llvmType = getLLVMType(type); - std::string allocaName = getNextTemp(); - - irStream << " " << allocaName << " = alloca " << llvmType << ", align 4\n"; - - if (constDef->constInitVal()) { - std::string value = std::any_cast(constDef->constInitVal()->accept(this)); + if (!inFunction) { + // 全局常量声明 + std::string varName = constDef->Ident()->getText(); + std::string llvmType = getLLVMType(type); + std::string value = "0"; // 默认值为 0 + + try { + value = std::any_cast(constDef->constInitVal()->accept(this)); + } catch (...) { + throw std::runtime_error("Const value must be initialized upon definition."); + } + + if (llvmType == "float") { + try { + double floatValue = std::stod(value); + uint64_t hexValue = reinterpret_cast(floatValue); + std::stringstream ss; + ss << "0x" << std::hex << std::uppercase << hexValue; + value = ss.str(); + } catch (...) { + throw std::runtime_error("Invalid float literal: " + value); + } + } + + irStream << "@" << varName << " = dso_local constant " << llvmType << " " << value << ", align 4\n"; + globalVars.push_back(varName); // 记录全局变量 + } else { + // 局部常量声明 + std::string varName = constDef->Ident()->getText(); + std::string llvmType = getLLVMType(type); + std::string allocaName = getNextTemp(); + std::string value = "0"; // 默认值为 0 + + try { + value = std::any_cast(constDef->constInitVal()->accept(this)); + } catch (...) { + throw std::runtime_error("Const value must be initialized upon definition."); + } + + irStream << " " << allocaName << " = alloca " << llvmType << ", align 4\n"; if (llvmType == "float") { try { double floatValue = std::stod(value); @@ -54,24 +119,17 @@ std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext* ctx) { } } irStream << " store " << llvmType << " " << value << ", " << llvmType - << "* " << allocaName << ", align 4\n"; - } - symbolTable[varName] = {allocaName, llvmType}; - tmpTable[allocaName] = llvmType; - } - return nullptr; -} - -std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext* ctx) { - std::string type = ctx->bType()->getText(); - currentVarType = getLLVMType(type); - for (auto varDef : ctx->varDef()) { - varDef->accept(this); + << "* " << allocaName << ", align 4\n"; + + symbolTable[varName] = {allocaName, llvmType}; + tmpTable[allocaName] = llvmType; + } } return nullptr; } std::any SysYIRGenerator::visitVarDef(SysYParser::VarDefContext* ctx) { + // TODO:数组初始化 std::string varName = ctx->Ident()->getText(); std::string type = currentVarType; std::string llvmType = getLLVMType(type); @@ -331,7 +389,6 @@ std::any SysYIRGenerator::visitAddExp(SysYParser::AddExpContext* ctx) { std::string left = std::any_cast(mulExps[0]->accept(this)); for (size_t i = 1; i < mulExps.size(); ++i) { std::string right = std::any_cast(mulExps[i]->accept(this)); - irStream << "right is " << right << "\n"; std::string op = ctx->children[2*i-1]->getText(); std::string temp = getNextTemp(); std::string type = tmpTable[left]; diff --git a/src/SysYIRGenerator.h b/src/SysYIRGenerator.h index 50c2568..f5000ff 100644 --- a/src/SysYIRGenerator.h +++ b/src/SysYIRGenerator.h @@ -32,6 +32,8 @@ private: std::string getNextTemp(); std::string getLLVMType(const std::string& type); + bool inFunction = false; // 标识当前是否处于函数内部 + // 访问方法 std::any visitCompUnit(SysYParser::CompUnitContext* ctx) override; std::any visitConstDecl(SysYParser::ConstDeclContext* ctx) override; diff --git a/test/01_add.sy b/test/01_add.sy index 325c3ca..51e5659 100644 --- a/test/01_add.sy +++ b/test/01_add.sy @@ -1,40 +1,10 @@ //test add +//const int a33[2] = {66,88}; -int a1 = 1; -int a2 = 2; -int a3 = 3; -int a4 = 4; -int a5 = 5; -int a6 = 6; -int a7 = 7; -int a8 = 8; -int a9 = 9; -int a10 = 10; -int a11 = 11; -int a12 = 12; -int a13 = 13; -int a14 = 14; -int a15 = 15; -int a16 = 16; -int a17 = 1; -int a18 = 2; -int a19 = 3; -int a20 = 4; -int a21 = 5; -int a22 = 6; -int a23 = 7; -int a24 = 8; -int a25 = 9; -int a26 = 10; -int a27 = 11; -int a28 = 12; -int a29 = 13; -int a30 = 14; -int a31 = 15; -int a32 = 16; - -int main(int e){ +int main(){ int a, b; +// int g[2][3][4] = {0,1,2,3,4,5,6,7,8,}; +// const int f[2] = {33,44}; float c; a = 10; b = 2;