From 5567f8278366f1e7324d9f6daa5b2be9abe65fae Mon Sep 17 00:00:00 2001 From: ladev789 Date: Sat, 22 Mar 2025 22:33:00 +0800 Subject: [PATCH] =?UTF-8?q?[lab2]=E4=BF=AE=E5=A4=8D=E4=BA=86=E6=A0=87?= =?UTF-8?q?=E7=AD=BE=E5=86=97=E4=BD=99=E9=94=99=E8=AF=AF=EF=BC=8C=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E4=B8=80=E4=BA=9B=E5=85=B6=E4=BB=96bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SysYIRGenerator.cpp | 47 +++++++++++++++++++++++++++++++++++------ src/SysYIRGenerator.h | 2 ++ test/01_add.sy | 14 +++++++----- 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/SysYIRGenerator.cpp b/src/SysYIRGenerator.cpp index 6fe421f..f221205 100644 --- a/src/SysYIRGenerator.cpp +++ b/src/SysYIRGenerator.cpp @@ -8,7 +8,9 @@ std::string SysYIRGenerator::generateIR(SysYParser::CompUnitContext* unit) { } std::string SysYIRGenerator::getNextTemp() { - return "%" + std::to_string(tempCounter++); + std::string ret = "%" + std::to_string(tempCounter++); + tmpTable[ret] = "void"; + return ret; } std::string SysYIRGenerator::getLLVMType(const std::string& type) { @@ -44,12 +46,14 @@ std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext* ctx) { << "* " << 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); } @@ -58,7 +62,7 @@ std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext* ctx) { std::any SysYIRGenerator::visitVarDef(SysYParser::VarDefContext* ctx) { std::string varName = ctx->Ident()->getText(); - std::string type = symbolTable[varName].second; + std::string type = currentVarType; std::string llvmType = getLLVMType(type); std::string allocaName = getNextTemp(); @@ -66,10 +70,23 @@ std::any SysYIRGenerator::visitVarDef(SysYParser::VarDefContext* ctx) { if (ctx->ASSIGN()) { std::string value = std::any_cast(ctx->initVal()->accept(this)); + + 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 << " store " << llvmType << " " << value << ", " << llvmType << "* " << allocaName << ", align 4\n"; } symbolTable[varName] = {allocaName, llvmType}; + tmpTable[allocaName] = llvmType; return nullptr; } @@ -78,18 +95,20 @@ std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext* ctx) { currentReturnType = getLLVMType(ctx->funcType()->getText()); symbolTable.clear(); hasReturn = false; - tempCounter = 0; irStream << "define dso_local " << currentReturnType << " @" << currentFunction << "("; if (ctx->funcFParams()) { auto params = ctx->funcFParams()->funcFParam(); + tempCounter += params.size(); for (size_t i = 0; i < params.size(); ++i) { if (i > 0) irStream << ", "; std::string paramType = getLLVMType(params[i]->bType()->getText()); irStream << paramType << " noundef %" << i; symbolTable[params[i]->Ident()->getText()] = {"%" + std::to_string(i), paramType}; + tmpTable["%" + std::to_string(i)] = paramType; } } + tempCounter++; irStream << ") #0 {\n"; ctx->blockStmt()->accept(this); @@ -117,6 +136,17 @@ std::any SysYIRGenerator::visitStmt(SysYParser::StmtContext* ctx) { std::string lhsAlloca = std::any_cast(ctx->lValue()->accept(this)); std::string lhsType = symbolTable[ctx->lValue()->Ident()->getText()].second; std::string rhs = std::any_cast(ctx->exp()->accept(this)); + if (lhsType == "float") { + try { + double floatValue = std::stod(rhs); + uint64_t hexValue = reinterpret_cast(floatValue); + std::stringstream ss; + ss << "0x" << std::hex << std::uppercase << hexValue; + rhs = ss.str(); + } catch (...) { + throw std::runtime_error("Invalid float literal: " + rhs); + } + } irStream << " store " << lhsType << " " << rhs << ", " << lhsType << "* " << lhsAlloca << ", align 4\n"; } else if (ctx->RETURN()) { @@ -162,6 +192,7 @@ std::any SysYIRGenerator::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) { std::string type = symbolTable[varName].second; std::string temp = getNextTemp(); irStream << " " << temp << " = load " << type << ", " << type << "* " << allocaPtr << ", align 4\n"; + tmpTable[temp] = type; return temp; } else if (ctx->exp()) { return ctx->exp()->accept(this); @@ -172,9 +203,9 @@ std::any SysYIRGenerator::visitPrimaryExp(SysYParser::PrimaryExpContext* ctx) { std::any SysYIRGenerator::visitNumber(SysYParser::NumberContext* ctx) { if (ctx->ILITERAL()) { - return "i32 " + ctx->ILITERAL()->getText(); + return ctx->ILITERAL()->getText(); } else if (ctx->FLITERAL()) { - return "float " + ctx->FLITERAL()->getText(); + return ctx->FLITERAL()->getText(); } return ""; } @@ -185,6 +216,7 @@ std::any SysYIRGenerator::visitUnaryExp(SysYParser::UnaryExpContext* ctx) { std::string op = ctx->unaryOp()->getText(); std::string temp = getNextTemp(); std::string type = operand.substr(0, operand.find(' ')); + tmpTable[temp] = type; if (op == "-") { irStream << " " << temp << " = sub " << type << " 0, " << operand << "\n"; } else if (op == "!") { @@ -206,6 +238,7 @@ std::any SysYIRGenerator::visitUnaryExp(SysYParser::UnaryExpContext* ctx) { argList += args[i]; } irStream << " " << temp << " = call " << currentReturnType << " @" << funcName << "(" << argList << ")\n"; + tmpTable[temp] = currentReturnType; return temp; } return ctx->primaryExp()->accept(this); @@ -218,7 +251,7 @@ std::any SysYIRGenerator::visitMulExp(SysYParser::MulExpContext* ctx) { std::string right = std::any_cast(unaryExps[i]->accept(this)); std::string op = ctx->children[2*i-1]->getText(); std::string temp = getNextTemp(); - std::string type = left.substr(0, left.find(' ')); + std::string type = tmpTable[left]; if (op == "*") { irStream << " " << temp << " = mul nsw " << type << " " << left << ", " << right << "\n"; } else if (op == "/") { @@ -238,7 +271,7 @@ std::any SysYIRGenerator::visitAddExp(SysYParser::AddExpContext* ctx) { std::string right = std::any_cast(mulExps[i]->accept(this)); std::string op = ctx->children[2*i-1]->getText(); std::string temp = getNextTemp(); - std::string type = left.substr(0, left.find(' ')); + std::string type = tmpTable[left]; if (op == "+") { irStream << " " << temp << " = add nsw " << type << " " << left << ", " << right << "\n"; } else if (op == "-") { diff --git a/src/SysYIRGenerator.h b/src/SysYIRGenerator.h index c65e1ff..3e07914 100644 --- a/src/SysYIRGenerator.h +++ b/src/SysYIRGenerator.h @@ -14,7 +14,9 @@ public: private: std::stringstream irStream; int tempCounter = 0; + std::string currentVarType; std::map> symbolTable; + std::map tmpTable; std::vector globalVars; std::string currentFunction; std::string currentReturnType; diff --git a/test/01_add.sy b/test/01_add.sy index fc6c9be..d28d6f8 100644 --- a/test/01_add.sy +++ b/test/01_add.sy @@ -1,12 +1,16 @@ //test add -int main(){ +int main(int e){ int a, b; - float d; + float c; a = 10; b = 2; - int c = a; - d = 1.1 ; - return a + b + c; + a = 11; + c = 1.3 ; + return a+b; } + +int add(int a, int b){ + return a+b; +} \ No newline at end of file