From 9f562aa0be1349618d70202a67f48443ed94821d Mon Sep 17 00:00:00 2001 From: ladev789 Date: Tue, 1 Apr 2025 17:50:17 +0800 Subject: [PATCH] [lab2]implemented while, break, continue --- src/SysYIRGenerator.cpp | 35 +++++++++++++++++++++++++++++++++++ src/SysYIRGenerator.h | 5 +++-- test/01_add.sy | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/SysYIRGenerator.cpp b/src/SysYIRGenerator.cpp index 9974771..63a4bd7 100644 --- a/src/SysYIRGenerator.cpp +++ b/src/SysYIRGenerator.cpp @@ -205,6 +205,38 @@ std::any SysYIRGenerator::visitStmt(SysYParser::StmtContext* ctx) { irStream << " br label %" << mergeLabel << "\n"; irStream << mergeLabel << ":\n"; + } else if (ctx->WHILE()) { + std::string loop_cond = "while.cond." + std::to_string(tempCounter); + std::string loop_body = "while.body." + std::to_string(tempCounter); + std::string loop_end = "while.end." + std::to_string(tempCounter++); + + loopStack.push({loop_end, loop_cond}); + irStream << " br label %" << loop_cond << "\n"; + irStream << loop_cond << ":\n"; + + std::string cond = std::any_cast(ctx->cond()->accept(this)); + irStream << " br i1 " << cond << ", label %" << loop_body << ", label %" << loop_end << "\n"; + irStream << loop_body << ":\n"; + ctx->stmt(0)->accept(this); + irStream << " br label %" << loop_cond << "\n"; + irStream << loop_end << ":\n"; + + loopStack.pop(); + + } else if (ctx->BREAK()) { + if (loopStack.empty()) { + throw std::runtime_error("Break statement outside of a loop."); + } + irStream << " br label %" << loopStack.top().breakLabel << "\n"; + } else if (ctx->CONTINUE()) { + if (loopStack.empty()) { + throw std::runtime_error("Continue statement outside of a loop."); + } + irStream << " br label %" << loopStack.top().continueLabel << "\n"; + } else if (ctx->blockStmt()) { + ctx->blockStmt()->accept(this); + } else if (ctx->exp()) { + ctx->exp()->accept(this); } return nullptr; } @@ -289,6 +321,7 @@ std::any SysYIRGenerator::visitMulExp(SysYParser::MulExpContext* ctx) { irStream << " " << temp << " = srem " << type << " " << left << ", " << right << "\n"; } left = temp; + tmpTable[temp] = type; } return left; } @@ -298,6 +331,7 @@ 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]; @@ -307,6 +341,7 @@ std::any SysYIRGenerator::visitAddExp(SysYParser::AddExpContext* ctx) { irStream << " " << temp << " = sub nsw " << type << " " << left << ", " << right << "\n"; } left = temp; + tmpTable[temp] = type; } return left; } diff --git a/src/SysYIRGenerator.h b/src/SysYIRGenerator.h index 8608cc2..50c2568 100644 --- a/src/SysYIRGenerator.h +++ b/src/SysYIRGenerator.h @@ -23,9 +23,10 @@ private: std::vector breakStack; std::vector continueStack; bool hasReturn = false; + struct LoopLabels { - std::string breakLabel; - std::string continueLabel; + std::string breakLabel; // break跳转的目标标签 + std::string continueLabel; // continue跳转的目标标签 }; std::stack loopStack; // 用于管理循环的break和continue标签 std::string getNextTemp(); diff --git a/test/01_add.sy b/test/01_add.sy index 488d209..325c3ca 100644 --- a/test/01_add.sy +++ b/test/01_add.sy @@ -1,5 +1,37 @@ //test add +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 a, b; @@ -8,7 +40,7 @@ int main(int e){ b = 2; a = 11; c = 1.6 ; - return a+b; + return a+b+1; } int add(int a, int b){