diff --git a/src/SysYFIRBuilder/IRBuilder.cpp b/src/SysYFIRBuilder/IRBuilder.cpp index 0276fda..219b882 100644 --- a/src/SysYFIRBuilder/IRBuilder.cpp +++ b/src/SysYFIRBuilder/IRBuilder.cpp @@ -18,6 +18,9 @@ int exprRes = 0; std::string curFuncName = ""; Ptr tmpInst; bool isFloat = false; +bool isAddr = false; +Ptr curCondBB; +Ptr curAfterBB; // types Ptr VOID_T; @@ -35,10 +38,6 @@ Ptr GetType(SyntaxTree::Type type){ return INT1_T; case SyntaxTree::Type::VOID: return VOID_T; - case SyntaxTree::Type::BOOL: - return INT1_T; - case SyntaxTree::Type::STRING: - return INT32PTR_T; default: return nullptr; } @@ -88,21 +87,12 @@ void IRBuilder::visit(SyntaxTree::FuncParam &node) { break; case SyntaxTree::Type::FLOAT: if (!node.array_index.empty()) { - // TODO: high dim array + // TODO: high dim array (not now) funcFParam.push_back(FLOATPTR_T); } else funcFParam.push_back(FLOAT_T); break; - case SyntaxTree::Type::VOID: - funcFParam.push_back(VOID_T); - break; - case SyntaxTree::Type::STRING: - funcFParam.push_back(INT32PTR_T); - break; - case SyntaxTree::Type::BOOL: - funcFParam.push_back(INT1_T); - break; default: funcFParam.push_back(INT32_T); break; @@ -110,13 +100,13 @@ void IRBuilder::visit(SyntaxTree::FuncParam &node) { } void IRBuilder::visit(SyntaxTree::VarDef &node) { - + ; } void IRBuilder::visit(SyntaxTree::LVal &node) { auto ident = scope.find(node.name, false); if (!node.array_index.empty()) { - //TODO: high dim array + //TODO: high dim array (not now) node.array_index[0]->accept(*this); auto index = tmpInst; tmpInst = builder->create_gep(ident, {CONST_INT(0), index}); @@ -124,48 +114,50 @@ void IRBuilder::visit(SyntaxTree::LVal &node) { else { tmpInst = dynamic_pointer_cast(ident); } + isAddr = true; } void IRBuilder::visit(SyntaxTree::AssignStmt &node) { node.target->accept(*this); auto target = tmpInst; node.value->accept(*this); - auto value = tmpInst; + Ptr value; + if (isAddr) { + value = builder->create_load(tmpInst); + isAddr = false; + } + else + value = dynamic_pointer_cast(tmpInst); builder->create_store(value, target); } void IRBuilder::visit(SyntaxTree::Literal &node) { - /* switch(node.literal_type) { case SyntaxTree::Type::INT: - tmp_val = CONST_INT(node.int_val); + tmp_val = CONST_INT(node.int_const); + isFloat = false; break; case SyntaxTree::Type::FLOAT: - tmp_val = CONST_FLOAT(node.float_val); - break; - case SyntaxTree::Type::BOOL: - tmp_val = CONST_INT(node.bool_val); - break; - case SyntaxTree::Type::STRING: - tmp_val = CONST_INT(node.str_val); + tmp_val = CONST_FLOAT(node.float_const); + isFloat = true; break; default: tmp_val = CONST_INT(0); break; } - */ } void IRBuilder::visit(SyntaxTree::ReturnStmt &node) { node.ret->accept(*this); - builder->create_ret(tmpInst); - return ; + builder->create_ret(tmp_val); } void IRBuilder::visit(SyntaxTree::BlockStmt &node) { + scope.enter(); for (const auto &stmt : node.body) { stmt->accept(*this); } + scope.exit(); return ; } @@ -182,84 +174,127 @@ void IRBuilder::visit(SyntaxTree::UnaryCondExpr &node) { node.rhs->accept(*this); switch (node.op) { case SyntaxTree::UnaryCondOp::NOT: - if(isFloat){ + if (isFloat) { tmpInst = builder->create_fcmp_eq(tmpInst, CONST_FLOAT(0.0)); } - else + else { tmpInst = builder->create_icmp_eq(tmpInst, CONST_INT(0)); + } default: break; } } void IRBuilder::visit(SyntaxTree::BinaryCondExpr &node) { - node.lhs->accept(*this); - auto lhs = tmpInst; - node.rhs->accept(*this); - auto rhs = tmpInst; + auto curFunc = builder->get_insert_block()->get_parent(); + auto trueBB = BasicBlock::create(module, "trueBB_and", curFunc); + auto falseBB = BasicBlock::create(module, "falseBB_and", curFunc); + Ptr cond; switch (node.op) { - case SyntaxTree::BinaryCondOp::LT: - if (isFloat) { - tmpInst = builder->create_fcmp_lt(lhs, rhs); - } - else { - tmpInst = builder->create_icmp_gt(lhs, rhs); - } - break; - case SyntaxTree::BinaryCondOp::LTE: - if (isFloat) { - tmpInst = builder->create_fcmp_le(lhs, rhs); - } - else { - tmpInst = builder->create_icmp_le(lhs, rhs); - } - break; - case SyntaxTree::BinaryCondOp::GT: - if (isFloat) { - tmpInst = builder->create_fcmp_gt(lhs, rhs); - } - else { - tmpInst = builder->create_icmp_gt(lhs, rhs); - } - break; - case SyntaxTree::BinaryCondOp::GTE: - if (isFloat) { - tmpInst = builder->create_fcmp_ge(lhs, rhs); - } - else { - tmpInst = builder->create_icmp_ge(lhs, rhs); - } - break; - case SyntaxTree::BinaryCondOp::EQ: - if (isFloat) { - tmpInst = builder->create_fcmp_eq(lhs, rhs); - } - else { - tmpInst = builder->create_icmp_eq(lhs, rhs); - } - break; - case SyntaxTree::BinaryCondOp::NEQ: - if (isFloat) { - tmpInst = builder->create_fcmp_ne(lhs, rhs); - } - else { - tmpInst = builder->create_icmp_ne(lhs, rhs); - } - break; case SyntaxTree::BinaryCondOp::LAND: - //TODO: and + node.lhs->accept(*this); + cond = tmpInst; + builder->create_cond_br(cond, trueBB, falseBB); + + // True - continue + builder->set_insert_point(trueBB); + node.rhs->accept(*this); + cond = tmpInst; + + // False + builder->set_insert_point(falseBB); + tmpInst = cond; + break; case SyntaxTree::BinaryCondOp::LOR: - //TODO: or + + node.lhs->accept(*this); + cond = tmpInst; + builder->create_cond_br(cond, trueBB, falseBB); + + // False - continue + builder->set_insert_point(falseBB); + node.rhs->accept(*this); + cond = tmpInst; + + // True + builder->set_insert_point(trueBB); + tmpInst = cond; + break; + default: + node.lhs->accept(*this); + auto lhs = tmpInst; + node.rhs->accept(*this); + auto rhs = tmpInst; + switch (node.op) { + case SyntaxTree::BinaryCondOp::LT: + if (isFloat) { + tmpInst = builder->create_fcmp_lt(lhs, rhs); + } + else { + tmpInst = builder->create_icmp_gt(lhs, rhs); + } + break; + case SyntaxTree::BinaryCondOp::LTE: + if (isFloat) { + tmpInst = builder->create_fcmp_le(lhs, rhs); + } + else { + tmpInst = builder->create_icmp_le(lhs, rhs); + } + break; + case SyntaxTree::BinaryCondOp::GT: + if (isFloat) { + tmpInst = builder->create_fcmp_gt(lhs, rhs); + } + else { + tmpInst = builder->create_icmp_gt(lhs, rhs); + } + break; + case SyntaxTree::BinaryCondOp::GTE: + if (isFloat) { + tmpInst = builder->create_fcmp_ge(lhs, rhs); + } + else { + tmpInst = builder->create_icmp_ge(lhs, rhs); + } + break; + case SyntaxTree::BinaryCondOp::EQ: + if (isFloat) { + tmpInst = builder->create_fcmp_eq(lhs, rhs); + } + else { + tmpInst = builder->create_icmp_eq(lhs, rhs); + } + break; + case SyntaxTree::BinaryCondOp::NEQ: + if (isFloat) { + tmpInst = builder->create_fcmp_ne(lhs, rhs); + } + else { + tmpInst = builder->create_icmp_ne(lhs, rhs); + } + break; + default: + break; + } } } void IRBuilder::visit(SyntaxTree::BinaryExpr &node) { node.lhs->accept(*this); auto lhs = tmpInst; + if (isAddr) { + lhs = builder->create_load(lhs); + isAddr = false; + } node.rhs->accept(*this); auto rhs = tmpInst; + if(isAddr){ + rhs = builder->create_load(rhs); + isAddr = false; + } switch (node.op) { case SyntaxTree::BinOp::PLUS: if(isFloat){ @@ -291,7 +326,7 @@ void IRBuilder::visit(SyntaxTree::BinaryExpr &node) { break; case SyntaxTree::BinOp::MODULO: if(isFloat){ - // not support + ;// not support } else { tmpInst = builder->create_isrem(lhs, rhs); } @@ -318,11 +353,17 @@ void IRBuilder::visit(SyntaxTree::UnaryExpr &node) { } void IRBuilder::visit(SyntaxTree::FuncCallStmt &node) { - + auto curFunc = builder->get_insert_block()->get_parent(); + std::vector> funcRParam; + for (const auto ¶m : node.params) { + param->accept(*this); + funcRParam.push_back(tmp_val); + } + builder->create_call(curFunc, funcRParam); } void IRBuilder::visit(SyntaxTree::IfStmt &node) { - auto curFunc = dynamic_pointer_cast(scope.find(curFuncName, true)); + auto curFunc = builder->get_insert_block()->get_parent(); node.cond_exp->accept(*this); auto cond = tmp_val; auto trueBB = BasicBlock::create(module, "trueBB_if", curFunc); @@ -335,10 +376,12 @@ void IRBuilder::visit(SyntaxTree::IfStmt &node) { } void IRBuilder::visit(SyntaxTree::WhileStmt &node) { - auto curFunc = dynamic_pointer_cast(scope.find(curFuncName, true)); + 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; builder->create_br(condBB); @@ -353,15 +396,18 @@ void IRBuilder::visit(SyntaxTree::WhileStmt &node) { builder->create_br(condBB); builder->set_insert_point(afterBB); + + return ; } void IRBuilder::visit(SyntaxTree::BreakStmt &node) { - + builder->create_br(curAfterBB); + return ; } void IRBuilder::visit(SyntaxTree::ContinueStmt &node) { - + builder->create_br(curCondBB); + return ; } - } } \ No newline at end of file