|
|
|
@ -18,6 +18,9 @@ int exprRes = 0;
|
|
|
|
|
std::string curFuncName = "";
|
|
|
|
|
Ptr<SysYF::IR::Instruction> tmpInst;
|
|
|
|
|
bool isFloat = false;
|
|
|
|
|
bool isAddr = false;
|
|
|
|
|
Ptr<BasicBlock> curCondBB;
|
|
|
|
|
Ptr<BasicBlock> curAfterBB;
|
|
|
|
|
|
|
|
|
|
// types
|
|
|
|
|
Ptr<Type> VOID_T;
|
|
|
|
@ -35,10 +38,6 @@ Ptr<Type> 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<Instruction>(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> value;
|
|
|
|
|
if (isAddr) {
|
|
|
|
|
value = builder->create_load(tmpInst);
|
|
|
|
|
isAddr = false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
value = dynamic_pointer_cast<Value>(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<Instruction> 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<Ptr<Value>> 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<Function>(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<Function>(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 ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|