diff --git a/CMakeLists.txt b/CMakeLists.txt index 96dd3cb..0b18fb4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ 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") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -Wall -Wextra -Wno-unused -Wshadow -g -pedantic") # include generated files in project environment include_directories(${CMAKE_CURRENT_BINARY_DIR}) diff --git a/src/SysYFIRBuilder/IRBuilder.cpp b/src/SysYFIRBuilder/IRBuilder.cpp index 8237206..0152bd6 100644 --- a/src/SysYFIRBuilder/IRBuilder.cpp +++ b/src/SysYFIRBuilder/IRBuilder.cpp @@ -13,9 +13,10 @@ namespace IR // to store state // store temporary value -Ptr tmp_val = nullptr; -std::vector> funcFParam; -int exprRes = 0; +int tmpConstVal = 0; +Ptr tmpVal = nullptr; +std::vector> funcFParam; +std::vector> arrayInitializer; std::string curFuncName = ""; Ptr tmpInst; bool isFloat = false; @@ -102,23 +103,59 @@ void IRBuilder::visit(SyntaxTree::FuncParam &node) { void IRBuilder::visit(SyntaxTree::VarDef &node) { // TODOļ¼š high dim array (not now) - Ptr arrayLength; + int arrayLength; Ptr initVal; if (node.is_constant) { assert(node.is_inited); switch (node.btype) { case (SyntaxTree::Type::INT): if (!node.array_length.empty()) { - + node.array_length[0]->accept(*this); + // expr need to return ConstVal if possible + arrayLength = tmpConstVal; + auto arrayType = ArrayType::get(INT32_T, arrayLength); + auto alloca = builder->create_alloca(arrayType); + arrayInitializer.clear(); + // const int a[] = {}; + int i = 0; + for ( const auto &expr : node.initializers->elementList) { + expr->accept(*this); + auto tmpInit = tmpInst; + tmpInst = builder->create_gep(alloca, {CONST_INT(0), CONST_INT(i)}); + builder->create_store(tmpInit, tmpInst); + i ++; + } } else { - + // const int a = 1; + auto alloca = builder->create_alloca(INT32_T); + node.initializers->expr->accept(*this); + initVal = tmpInst; + builder->create_store(initVal, alloca); } break; case (SyntaxTree::Type::FLOAT): if (!node.array_length.empty()) { - + node.array_length[0]->accept(*this); + // expr need to return ConstVal if possible + arrayLength = tmpConstVal; + auto arrayType = ArrayType::get(FLOAT_T, arrayLength); + auto alloca = builder->create_alloca(arrayType); + arrayInitializer.clear(); + // const int a[] = {}; + int i = 0; + for ( const auto &expr : node.initializers->elementList) { + expr->accept(*this); + auto tmpInit = tmpInst; + tmpInst = builder->create_gep(alloca, {CONST_INT(0), CONST_INT(i)}); + builder->create_store(tmpInit, tmpInst); + i ++; + } } else { - + // const float a = 1.0; + auto alloca = builder->create_alloca(FLOAT_T); + node.initializers->expr->accept(*this); + initVal = tmpInst; + builder->create_store(initVal, alloca); } break; default: @@ -128,12 +165,28 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) { switch (node.btype) { case (SyntaxTree::Type::INT): if (!node.array_length.empty()) { - + node.array_length[0]->accept(*this); + // expr need to return ConstVal if possible + arrayLength = tmpConstVal; + auto arrayType = ArrayType::get(INT32_T, arrayLength); + auto alloca = builder->create_alloca(arrayType); + if (node.is_inited) { + int i = 0; + for ( const auto &expr : node.initializers->elementList) { + expr->accept(*this); + auto tmpInit = tmpInst; + tmpInst = builder->create_gep(alloca, {CONST_INT(0), CONST_INT(i)}); + builder->create_store(tmpInit, tmpInst); + i ++; + } + } else { + ; + } } else { auto alloca = builder->create_alloca(INT32_T); if (node.is_inited) { - - + node.initializers->expr->accept(*this); + initVal = tmpInst; builder->create_store(initVal, alloca); } else { builder->create_store(CONST_INT(0), alloca); @@ -143,15 +196,32 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) { break; case (SyntaxTree::Type::FLOAT): if (!node.array_length.empty()) { + node.array_length[0]->accept(*this); + // expr need to return ConstVal if possible + arrayLength = tmpConstVal; + auto arrayType = ArrayType::get(FLOAT_T, arrayLength); + auto alloca = builder->create_alloca(arrayType); + if (node.is_inited) { + int i = 0; + for ( const auto &expr : node.initializers->elementList) { + expr->accept(*this); + auto tmpInit = tmpInst; + tmpInst = builder->create_gep(alloca, {CONST_INT(0), CONST_INT(i)}); + builder->create_store(tmpInit, tmpInst); + i ++; + } + } else { + ; + } } else { auto alloca = builder->create_alloca(FLOAT_T); if (node.is_inited) { - - + node.initializers->expr->accept(*this); + initVal = tmpInst; builder->create_store(initVal, alloca); } else { - builder->create_store(CONST_FLOAT(0), alloca); + builder->create_store(CONST_FLOAT(0.0), alloca); scope.push(node.name, alloca); } } @@ -194,22 +264,22 @@ void IRBuilder::visit(SyntaxTree::AssignStmt &node) { void IRBuilder::visit(SyntaxTree::Literal &node) { switch(node.literal_type) { case SyntaxTree::Type::INT: - tmp_val = CONST_INT(node.int_const); + tmpVal = CONST_INT(node.int_const); isFloat = false; break; case SyntaxTree::Type::FLOAT: - tmp_val = CONST_FLOAT(node.float_const); + tmpVal = CONST_FLOAT(node.float_const); isFloat = true; break; default: - tmp_val = CONST_INT(0); + tmpVal = CONST_INT(0); break; } } void IRBuilder::visit(SyntaxTree::ReturnStmt &node) { node.ret->accept(*this); - builder->create_ret(tmp_val); + builder->create_ret(tmpVal); } void IRBuilder::visit(SyntaxTree::BlockStmt &node) { @@ -417,7 +487,7 @@ void IRBuilder::visit(SyntaxTree::FuncCallStmt &node) { std::vector> funcRParam; for (const auto ¶m : node.params) { param->accept(*this); - funcRParam.push_back(tmp_val); + funcRParam.push_back(tmpVal); } builder->create_call(curFunc, funcRParam); } @@ -425,7 +495,7 @@ void IRBuilder::visit(SyntaxTree::FuncCallStmt &node) { void IRBuilder::visit(SyntaxTree::IfStmt &node) { auto curFunc = builder->get_insert_block()->get_parent(); node.cond_exp->accept(*this); - auto cond = tmp_val; + auto cond = tmpVal; auto trueBB = BasicBlock::create(module, "trueBB_if", curFunc); auto falseBB = BasicBlock::create(module, "falseBB_if", curFunc); builder->create_cond_br(cond, trueBB, falseBB); @@ -447,7 +517,7 @@ void IRBuilder::visit(SyntaxTree::WhileStmt &node) { builder->set_insert_point(condBB); node.cond_exp->accept(*this); - auto cond = tmp_val; + auto cond = tmpVal; builder->create_cond_br(cond, bodyBB, afterBB);