diff --git a/src/SysYFIRBuilder/IRBuilder.cpp b/src/SysYFIRBuilder/IRBuilder.cpp index f5c1b62..537c735 100644 --- a/src/SysYFIRBuilder/IRBuilder.cpp +++ b/src/SysYFIRBuilder/IRBuilder.cpp @@ -17,18 +17,12 @@ namespace IR std::vector> funcFParam; struct WhileBlock { - BasicBlock *condBB; - BasicBlock *innerBB; - BasicBlock *exitBB; + Ptr condBB; + Ptr bodyBB; + Ptr afterBB; }; auto curWhileBlock = WhileBlock{nullptr, nullptr, nullptr}; -struct CondBlock { - BasicBlock *trueBB; - BasicBlock *falseBB; -}; -auto curCondStruct = CondBlock{nullptr, nullptr}; - Ptr retBB; Ptr retAlloca; @@ -91,14 +85,24 @@ void IRBuilder::TypeConvert(Ptr origin, Ptr expected) { origin = builder->create_load(origin); } + if (type == INT32_T && expected == INT1_T) { + tmpInst = builder->create_icmp_ne(origin, CONST_INT(0)); + return; + } + if (type == FLOAT_T && expected == INT1_T) { + tmpInst = builder->create_fcmp_ne(origin, CONST_FLOAT(0)); + return; + } + if (type == INT32_T && expected == FLOAT_T) { - origin = builder->create_sitofp(origin, expected); + tmpInst = builder->create_sitofp(origin, expected); return; } if (type == FLOAT_T && expected == INT32_T) { - origin = builder->create_fptosi(origin, expected); + tmpInst = builder->create_fptosi(origin, expected); return; } + } else { auto tmpInt = dynamic_pointer_cast(origin); auto tmpFloat = dynamic_pointer_cast(origin); @@ -157,7 +161,11 @@ void IRBuilder::visit(SyntaxTree::FuncDef &node) { builder->set_insert_point(entryBlock); auto para = node.param_list->params.begin(); + auto para_end = node.param_list->params.end(); for (auto arg = func->arg_begin(); arg != func->arg_end() ; arg++) { + if(para == para_end) { + break; + } auto name = (*para)->name; auto val = (*arg); auto argAlloca = builder->create_alloca(val->get_type()); @@ -590,84 +598,107 @@ void IRBuilder::visit(SyntaxTree::BinaryExpr &node) { } -// TODO +// FINISH void IRBuilder::visit(SyntaxTree::UnaryExpr &node) { node.rhs->accept(*this); switch (node.op) { case SyntaxTree::UnaryOp::PLUS: break; case SyntaxTree::UnaryOp::MINUS: - if(isFloat){ - tmpInst = builder->create_fsub(CONST_FLOAT(0.0), tmpInst); + auto constInt = dynamic_pointer_cast(tmpInst); + auto constFloat = dynamic_pointer_cast(tmpInst); + if (constInt != nullptr) { + tmpInst = CONST_INT(-constInt->get_value()); + } else if (constFloat != nullptr) { + tmpInst = CONST_FLOAT(-constFloat->get_value()); + } else { + //TODO; } - else - tmpInst = builder->create_isub(CONST_INT(0), tmpInst); break; default: break; } } -// TODO +// Finish void IRBuilder::visit(SyntaxTree::FuncCallStmt &node) { - auto curFunc = builder->get_insert_block()->get_parent(); + auto name = node.name; + auto funcIdent = dynamic_pointer_cast(scope.find(name, true)); std::vector> funcRParam; + auto arg = funcIdent->arg_begin(); + auto arg_end = funcIdent->arg_end(); for (const auto ¶m : node.params) { + if(arg == arg_end) { + break; + } param->accept(*this); - funcRParam.push_back(tmpVal); + TypeConvert(tmpInst, (*arg)->get_type()); + funcRParam.push_back(tmpInst); + arg++; } - builder->create_call(curFunc, funcRParam); + tmpInst = builder->create_call(funcIdent, funcRParam); } -// TODO +// FINISH void IRBuilder::visit(SyntaxTree::IfStmt &node) { auto curFunc = builder->get_insert_block()->get_parent(); - node.cond_exp->accept(*this); - 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); + auto exitBB = node.else_statement == nullptr ? falseBB : BasicBlock::create(module, "exitBB_if", curFunc); + + node.cond_exp->accept(*this); + + TypeConvert(tmpInst, INT1_T); + builder->create_cond_br(tmpInst, trueBB, falseBB); + builder->set_insert_point(trueBB); node.if_statement->accept(*this); - builder->set_insert_point(falseBB); - node.else_statement->accept(*this); + builder->create_br(exitBB); + + if (node.else_statement) { + builder->set_insert_point(falseBB); + node.else_statement->accept(*this); + builder->create_br(exitBB); + } + if (!exitBB->get_pre_basic_blocks().empty()) { + builder->set_insert_point(exitBB); + } } -// TODO +//FINISH void IRBuilder::visit(SyntaxTree::WhileStmt &node) { auto curFunc = builder->get_insert_block()->get_parent(); auto condBB = BasicBlock::create(module, "condBB_while", curFunc); auto bodyBB = BasicBlock::create(module, "bodyBB_while", curFunc); auto afterBB = BasicBlock::create(module, "afterBB_while", curFunc); - curCondBB = condBB; - curAfterBB = afterBB; + auto tmpWhileBlock = curWhileBlock; + curWhileBlock = WhileBlock{condBB, bodyBB, afterBB}; builder->create_br(condBB); builder->set_insert_point(condBB); node.cond_exp->accept(*this); - auto cond = tmpVal; - - builder->create_cond_br(cond, bodyBB, afterBB); + TypeConvert(tmpInst, INT1_T); + builder->create_cond_br(tmpInst, bodyBB, afterBB); builder->set_insert_point(bodyBB); node.statement->accept(*this); builder->create_br(condBB); builder->set_insert_point(afterBB); - + curWhileBlock = tmpWhileBlock; return ; } -// TODO +//FINISH void IRBuilder::visit(SyntaxTree::BreakStmt &node) { - builder->create_br(curAfterBB); + builder->create_br(curWhileBlock.afterBB); return ; } -// TODO +//FINISH void IRBuilder::visit(SyntaxTree::ContinueStmt &node) { - builder->create_br(curCondBB); + builder->create_br(curWhileBlock.condBB); return ; } }