Finish some functions, need check

main
Odeinjul 12 months ago
parent 17934edfb9
commit 12e012dd6b
No known key found for this signature in database
GPG Key ID: E384228B2B38FFBB

@ -10,10 +10,14 @@ namespace IR
// You can define global variables here // You can define global variables here
// to store state // to store state
std::vector<SysYF::Ptr<Type>> funcParam;
int exprRes = 0;
// store temporary value // store temporary value
Ptr<Value> tmp_val = nullptr; Ptr<Value> tmp_val = nullptr;
std::vector<SysYF::Ptr<Type>> funcFParam;
int exprRes = 0;
std::string curFuncName = "";
Ptr<SysYF::IR::Instruction> tmpInst;
bool isFloat = false;
// types // types
Ptr<Type> VOID_T; Ptr<Type> VOID_T;
@ -61,13 +65,13 @@ void IRBuilder::visit(SyntaxTree::InitVal &node) {
void IRBuilder::visit(SyntaxTree::FuncDef &node) { void IRBuilder::visit(SyntaxTree::FuncDef &node) {
node.param_list->accept(*this); node.param_list->accept(*this);
auto funcType = FunctionType::create(GetType(node.ret_type), funcParam); auto funcType = FunctionType::create(GetType(node.ret_type), funcFParam);
auto createFunc = Function::create(funcType, node.name, module); auto createFunc = Function::create(funcType, node.name, module);
node.body->accept(*this); node.body->accept(*this);
} }
void IRBuilder::visit(SyntaxTree::FuncFParamList &node) { void IRBuilder::visit(SyntaxTree::FuncFParamList &node) {
funcParam.clear(); funcFParam.clear();
for (const auto &para : node.params) { for (const auto &para : node.params) {
para->accept(*this); para->accept(*this);
} }
@ -77,30 +81,30 @@ void IRBuilder::visit(SyntaxTree::FuncParam &node) {
case SyntaxTree::Type::INT: case SyntaxTree::Type::INT:
if (!node.array_index.empty()) { if (!node.array_index.empty()) {
// TODO high dim array // TODO high dim array
funcParam.push_back(INT32PTR_T); funcFParam.push_back(INT32PTR_T);
} }
else else
funcParam.push_back(INT32_T); funcFParam.push_back(INT32_T);
break; break;
case SyntaxTree::Type::FLOAT: case SyntaxTree::Type::FLOAT:
if (!node.array_index.empty()) { if (!node.array_index.empty()) {
// TODO high dim array // TODO high dim array
funcParam.push_back(FLOATPTR_T); funcFParam.push_back(FLOATPTR_T);
} }
else else
funcParam.push_back(FLOAT_T); funcFParam.push_back(FLOAT_T);
break; break;
case SyntaxTree::Type::VOID: case SyntaxTree::Type::VOID:
funcParam.push_back(VOID_T); funcFParam.push_back(VOID_T);
break; break;
case SyntaxTree::Type::STRING: case SyntaxTree::Type::STRING:
funcParam.push_back(INT32PTR_T); funcFParam.push_back(INT32PTR_T);
break; break;
case SyntaxTree::Type::BOOL: case SyntaxTree::Type::BOOL:
funcParam.push_back(INT1_T); funcFParam.push_back(INT1_T);
break; break;
default: default:
funcParam.push_back(INT32_T); funcFParam.push_back(INT32_T);
break; break;
} }
} }
@ -110,47 +114,207 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
} }
void IRBuilder::visit(SyntaxTree::LVal &node) { void IRBuilder::visit(SyntaxTree::LVal &node) {
auto ident = scope.find(node.name, false);
if (!node.array_index.empty()) {
//TODO: high dim array
node.array_index[0]->accept(*this);
auto index = tmpInst;
tmpInst = builder->create_gep(ident, {CONST_INT(0), index});
}
else {
tmpInst = dynamic_pointer_cast<Instruction>(ident);
}
} }
void IRBuilder::visit(SyntaxTree::AssignStmt &node) { void IRBuilder::visit(SyntaxTree::AssignStmt &node) {
node.target->accept(*this);
auto target = tmpInst;
node.value->accept(*this);
auto value = tmpInst;
builder->create_store(value, target);
} }
void IRBuilder::visit(SyntaxTree::Literal &node) { void IRBuilder::visit(SyntaxTree::Literal &node) {
/*
switch(node.literal_type) {
case SyntaxTree::Type::INT:
tmp_val = CONST_INT(node.int_val);
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);
break;
default:
tmp_val = CONST_INT(0);
break;
}
*/
} }
void IRBuilder::visit(SyntaxTree::ReturnStmt &node) { void IRBuilder::visit(SyntaxTree::ReturnStmt &node) {
node.ret->accept(*this);
builder->create_ret(tmpInst);
return ;
} }
void IRBuilder::visit(SyntaxTree::BlockStmt &node) { void IRBuilder::visit(SyntaxTree::BlockStmt &node) {
for (const auto &stmt : node.body) {
stmt->accept(*this);
}
return ;
} }
void IRBuilder::visit(SyntaxTree::EmptyStmt &node) { void IRBuilder::visit(SyntaxTree::EmptyStmt &node) {
return ;
} }
void IRBuilder::visit(SyntaxTree::ExprStmt &node) { void IRBuilder::visit(SyntaxTree::ExprStmt &node) {
node.exp->accept(*this);
return ;
} }
void IRBuilder::visit(SyntaxTree::UnaryCondExpr &node) { void IRBuilder::visit(SyntaxTree::UnaryCondExpr &node) {
node.rhs->accept(*this);
switch (node.op) {
case SyntaxTree::UnaryCondOp::NOT:
if(isFloat){
tmpInst = builder->create_fcmp_eq(tmpInst, CONST_FLOAT(0.0));
}
else
tmpInst = builder->create_icmp_eq(tmpInst, CONST_INT(0));
default:
break;
}
} }
void IRBuilder::visit(SyntaxTree::BinaryCondExpr &node) { void IRBuilder::visit(SyntaxTree::BinaryCondExpr &node) {
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;
case SyntaxTree::BinaryCondOp::LAND:
//TODO: and
break;
case SyntaxTree::BinaryCondOp::LOR:
//TODO: or
break;
}
} }
void IRBuilder::visit(SyntaxTree::BinaryExpr &node) { void IRBuilder::visit(SyntaxTree::BinaryExpr &node) {
node.lhs->accept(*this);
auto lhs = tmpInst;
node.rhs->accept(*this);
auto rhs = tmpInst;
switch (node.op) {
case SyntaxTree::BinOp::PLUS:
if(isFloat){
tmpInst = builder->create_fadd(lhs, rhs);
}
else
tmpInst = builder->create_iadd(lhs, rhs);
break;
case SyntaxTree::BinOp::MINUS:
if(isFloat){
tmpInst = builder->create_fsub(lhs, rhs);
}
else
tmpInst = builder->create_isub(lhs, rhs);
break;
case SyntaxTree::BinOp::MULTIPLY:
if(isFloat){
tmpInst = builder->create_fmul(lhs, rhs);
}
else
tmpInst = builder->create_imul(lhs, rhs);
break;
case SyntaxTree::BinOp::DIVIDE:
if(isFloat){
tmpInst = builder->create_fdiv(lhs, rhs);
} else {
tmpInst = builder->create_isdiv(lhs, rhs);
}
break;
case SyntaxTree::BinOp::MODULO:
if(isFloat){
// not support
} else {
tmpInst = builder->create_isrem(lhs, rhs);
}
break;
}
} }
void IRBuilder::visit(SyntaxTree::UnaryExpr &node) { 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);
}
else
tmpInst = builder->create_isub(CONST_INT(0), tmpInst);
break;
default:
break;
}
} }
void IRBuilder::visit(SyntaxTree::FuncCallStmt &node) { void IRBuilder::visit(SyntaxTree::FuncCallStmt &node) {
@ -158,11 +322,37 @@ void IRBuilder::visit(SyntaxTree::FuncCallStmt &node) {
} }
void IRBuilder::visit(SyntaxTree::IfStmt &node) { void IRBuilder::visit(SyntaxTree::IfStmt &node) {
auto curFunc = dynamic_pointer_cast<Function>(scope.find(curFuncName, true));
node.cond_exp->accept(*this);
auto cond = tmp_val;
auto trueBB = BasicBlock::create(module, "trueBB_if", curFunc);
auto falseBB = BasicBlock::create(module, "falseBB_if", curFunc);
builder->create_cond_br(cond, trueBB, falseBB);
builder->set_insert_point(trueBB);
node.if_statement->accept(*this);
builder->set_insert_point(falseBB);
node.else_statement->accept(*this);
} }
void IRBuilder::visit(SyntaxTree::WhileStmt &node) { void IRBuilder::visit(SyntaxTree::WhileStmt &node) {
auto curFunc = dynamic_pointer_cast<Function>(scope.find(curFuncName, true));
auto condBB = BasicBlock::create(module, "condBB_while", curFunc);
auto bodyBB = BasicBlock::create(module, "bodyBB_while", curFunc);
auto afterBB = BasicBlock::create(module, "afterBB_while", curFunc);
builder->create_br(condBB);
builder->set_insert_point(condBB);
node.cond_exp->accept(*this);
auto cond = tmp_val;
builder->create_cond_br(cond, bodyBB, afterBB);
builder->set_insert_point(bodyBB);
node.statement->accept(*this);
builder->create_br(condBB);
builder->set_insert_point(afterBB);
} }
void IRBuilder::visit(SyntaxTree::BreakStmt &node) { void IRBuilder::visit(SyntaxTree::BreakStmt &node) {

Loading…
Cancel
Save