From 355db97ef029d5067dd97f18e4219dcb23d7b84e Mon Sep 17 00:00:00 2001 From: llh Date: Fri, 29 Dec 2023 17:32:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=88=E5=B9=B6IRbuilder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 36 ++++++++++ report/report.md | 17 ++++- src/SysYFIRBuilder/IRBuilder.cpp | 111 ++++++++++++++++++++++--------- 3 files changed, 131 insertions(+), 33 deletions(-) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..4b1c6ad --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,36 @@ +project(SysYFCompiler) + +cmake_minimum_required(VERSION 3.5) + +set(CMAKE_CXX_STANDARD 14) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -Wall -Wextra -Wno-unused -Wshadow -Werror -g -pedantic") +# include generated files in project environment +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/AST) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/ErrorReporter) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/Frontend) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/SysYFIR) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/SysYFIRBuilder) + +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/AST) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/ErrorReporter) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/Frontend) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/SysYFIR) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src/SysYFIRBuilder) + +add_executable( + SysYFCompiler + ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp +) + +target_link_libraries( + SysYFCompiler + SysYFIRBuilder + IRLib + Driver + ASTPrinter + ErrReporter +) diff --git a/report/report.md b/report/report.md index 5300493..8ebdb71 100644 --- a/report/report.md +++ b/report/report.md @@ -1,7 +1,7 @@ # PW6 实验报告 PB21000117 陈应豪 - +PB21111663 李璐豪 ## 问题回答 ### task1 @@ -29,10 +29,25 @@ PB21000117 陈应豪 ## 实验设计 +在task1的时候,学习SysYF的语法,并编写等效的ll文件 + +在task2的时候,学习能够生成SysYF的IR文法,使之能生成等效的ll文件 + +在task3的时候,利用实验框架,通过类比上一关的IR认罚的编写,利用已经生成的AST树为不同的模块编写对应的IR语法 + ## 实验难点及解决方案 +在函数外表达式的计算中,由于全局变量无法使用bb模块内的build相关函数,需要根据变量名,单独取出值并计算 + +Const数组不会在函数外进行再赋值的操作 + ## 实验总结 +利用PW5学到的AST以及访问者模式,我们编写了能够生成IR的实验框架,对AST和IR的理解更加深刻 + ## 实验反馈 +配置文件不够齐全 + ## 组间交流 + diff --git a/src/SysYFIRBuilder/IRBuilder.cpp b/src/SysYFIRBuilder/IRBuilder.cpp index ea7f3e9..2c6628f 100644 --- a/src/SysYFIRBuilder/IRBuilder.cpp +++ b/src/SysYFIRBuilder/IRBuilder.cpp @@ -34,6 +34,9 @@ namespace SysYF Ptr FLOAT_T; Ptr INT32PTR_T; Ptr FLOATPTR_T; + + int if_BB_num = 0; + int while_BB_num = 0; #define get_true_type(left_type, right) \ if (!scope.in_global()) \ { \ @@ -803,21 +806,42 @@ namespace SysYF case SyntaxTree::BinOp::DIVIDE: if (expr_type == INT32_T) { - tmp_val = CONST_INT(lhs_int / rhs_int); + if(rhs_int == 0){ + cout << "Wrong Number" << endl; + } + else{ + tmp_val = CONST_INT(lhs_int / rhs_int); + } } else { - tmp_val = CONST_FLOAT(lhs_float / rhs_float); + if(rhs_float == 0){ + cout << "Wrong Number" << endl; + } + else{ + + tmp_val = CONST_FLOAT(lhs_float / rhs_float); + } } break; case SyntaxTree::BinOp::MODULO: if (expr_type == INT32_T) { - tmp_val = CONST_INT(lhs_int % rhs_int); + if(rhs_int == 0){ + cout << "Wrong Number" << endl; + } + else{ + tmp_val = CONST_INT(lhs_int % rhs_int); + } } else { - tmp_val = CONST_INT(static_cast(lhs_float) % static_cast(rhs_float)); + if(rhs_float == 0){ + cout << "Wrong Number" << endl; + } + else{ + tmp_val = CONST_INT(static_cast(lhs_float) % static_cast(rhs_float)); + } } break; } @@ -988,21 +1012,23 @@ namespace SysYF // 数组 if (arg_func_type == INT32PTR_T || arg_func_type == FLOATPTR_T) { - // if(value->get_type() == INT32PTR_T || value->get_type() == FLOATPTR_T){ - // tmp_val = value; - // } - // else{ - // tmp_val = builder->create_alloca(arg_func_type); - // builder->create_store(value, tmp_val); - // } + if (value->get_type() == INT32PTR_T || value->get_type() == FLOATPTR_T) + { + tmp_val = value; + } + else + { + tmp_val = builder->create_alloca(arg_func_type); + builder->create_store(value, tmp_val); + } } else { - if (value->get_type() == INT32_T && arg_func_type == FLOAT_T) + if (value->get_type() == INT32_T && (arg_func_type == FLOAT_T || arg_func_type == FLOATPTR_T)) { tmp_val = builder->create_sitofp(value, FLOAT_T); } - else if (value->get_type() == FLOAT_T && arg_func_type == INT32_T) + else if (value->get_type() == FLOAT_T && (arg_func_type == INT32_T || arg_func_type == INT32PTR_T)) { tmp_val = builder->create_fptosi(value, INT32_T); } @@ -1011,7 +1037,7 @@ namespace SysYF tmp_val = value; } } - + arg_func++; args.push_back(tmp_val); } @@ -1022,26 +1048,47 @@ namespace SysYF void IRBuilder::visit(SyntaxTree::IfStmt &node) { scope.enter(); - auto trueBB = BasicBlock::create(module, "trueBB_if", + auto trueBB = BasicBlock::create(module, "trueBB_if" + std::to_string(if_BB_num), module->get_functions().back()); - auto nextBB = BasicBlock::create(module, "nextBB_if", + auto nextBB = BasicBlock::create(module, "nextBB_if" + std::to_string(if_BB_num), module->get_functions().back()); - scope.push("trueBB", trueBB); - scope.push("falseBB", nextBB); + scope.push("trueBB" + std::to_string(if_BB_num), trueBB); + scope.push("falseBB" + std::to_string(if_BB_num), nextBB); node.cond_exp->accept(*this); LVal_to_RVal(tmp_val); auto cond = tmp_val; - builder->create_cond_br(cond, trueBB, nextBB); - builder->set_insert_point(trueBB); - node.if_statement->accept(*this); - - builder->set_insert_point(nextBB); if (node.else_statement) { + auto elseBB = BasicBlock::create(module, "elseBB_if" + std::to_string(if_BB_num), + module->get_functions().back()); + + scope.push("elseBB_if" + std::to_string(if_BB_num), elseBB); + + if_BB_num++; + + builder->create_cond_br(cond, trueBB, elseBB); + builder->set_insert_point(trueBB); + node.if_statement->accept(*this); + builder->create_br(nextBB); + + builder->set_insert_point(elseBB); node.else_statement->accept(*this); + builder->create_br(nextBB); + + builder->set_insert_point(nextBB); + } + else + { + if_BB_num++; + builder->create_cond_br(cond, trueBB, nextBB); + builder->set_insert_point(trueBB); + node.if_statement->accept(*this); + builder->create_br(nextBB); + + builder->set_insert_point(nextBB); } scope.exit(); } @@ -1050,17 +1097,17 @@ namespace SysYF { // auto func_name = scope.find("func", 0); scope.enter(); - auto condBB = BasicBlock::create(module, "condBB_while", + auto condBB = BasicBlock::create(module, "condBB_while" + std::to_string(while_BB_num), module->get_functions().back()); - auto trueBB = BasicBlock::create(module, "trueBB_while", + auto trueBB = BasicBlock::create(module, "trueBB_while" + std::to_string(while_BB_num), module->get_functions().back()); - auto falseBB = BasicBlock::create(module, "falseBB_while", + auto falseBB = BasicBlock::create(module, "falseBB_while" + std::to_string(while_BB_num), module->get_functions().back()); - scope.push("condBB_while", condBB); - scope.push("trueBB_while", trueBB); - scope.push("falseBB_while", falseBB); - + scope.push("condBB_while" + std::to_string(while_BB_num), condBB); + scope.push("trueBB_while" + std::to_string(while_BB_num), trueBB); + scope.push("falseBB_while" + std::to_string(while_BB_num), falseBB); + while_BB_num++; builder->create_br(condBB); builder->set_insert_point(condBB); @@ -1082,13 +1129,13 @@ namespace SysYF void IRBuilder::visit(SyntaxTree::BreakStmt &node) { - auto falseBB = scope.find("falseBB_while", 0); + auto falseBB = scope.find("falseBB_while" + std::to_string(while_BB_num - 1), 0); builder->create_br(dynamic_pointer_cast(falseBB)); } void IRBuilder::visit(SyntaxTree::ContinueStmt &node) { - auto condBB = scope.find("condBB_while", 0); + auto condBB = scope.find("condBB_while" + std::to_string(while_BB_num - 1), 0); builder->create_br(dynamic_pointer_cast(condBB)); } }