|
|
|
@ -17,18 +17,12 @@ namespace IR
|
|
|
|
|
std::vector<Ptr<Type>> funcFParam;
|
|
|
|
|
|
|
|
|
|
struct WhileBlock {
|
|
|
|
|
BasicBlock *condBB;
|
|
|
|
|
BasicBlock *innerBB;
|
|
|
|
|
BasicBlock *exitBB;
|
|
|
|
|
Ptr<BasicBlock> condBB;
|
|
|
|
|
Ptr<BasicBlock> bodyBB;
|
|
|
|
|
Ptr<BasicBlock> afterBB;
|
|
|
|
|
};
|
|
|
|
|
auto curWhileBlock = WhileBlock{nullptr, nullptr, nullptr};
|
|
|
|
|
|
|
|
|
|
struct CondBlock {
|
|
|
|
|
BasicBlock *trueBB;
|
|
|
|
|
BasicBlock *falseBB;
|
|
|
|
|
};
|
|
|
|
|
auto curCondStruct = CondBlock{nullptr, nullptr};
|
|
|
|
|
|
|
|
|
|
Ptr<BasicBlock> retBB;
|
|
|
|
|
Ptr<Value> retAlloca;
|
|
|
|
|
|
|
|
|
@ -91,14 +85,24 @@ void IRBuilder::TypeConvert(Ptr<Value> origin, Ptr<Type> 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<ConstantInt>(origin);
|
|
|
|
|
auto tmpFloat = dynamic_pointer_cast<ConstantFloat>(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<ConstantInt>(tmpInst);
|
|
|
|
|
auto constFloat = dynamic_pointer_cast<ConstantFloat>(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<Function>(scope.find(name, true));
|
|
|
|
|
std::vector<Ptr<Value>> 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 ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|