|
|
|
@ -114,27 +114,32 @@ void IRBuilder::BinaryExprGen(Ptr<Value> lhs, Ptr<Value> rhs, SyntaxTree::BinOp
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (lhs->get_type()->is_pointer_type()) {
|
|
|
|
|
if (dynamic_pointer_cast<Constant>(lhs) == nullptr && lhs->get_type()->is_pointer_type()) {
|
|
|
|
|
std::cout << 2<<std::endl;
|
|
|
|
|
lhs = builder->create_load(lhs);
|
|
|
|
|
}
|
|
|
|
|
if (rhs->get_type()->is_pointer_type()) {
|
|
|
|
|
if (dynamic_pointer_cast<Constant>(rhs) == nullptr && rhs->get_type()->is_pointer_type()) {
|
|
|
|
|
std::cout << 3<<std::endl;
|
|
|
|
|
rhs = builder->create_load(rhs);
|
|
|
|
|
}
|
|
|
|
|
if (lhs->get_type()->is_float_type() &&
|
|
|
|
|
rhs->get_type()->is_integer_type()) {
|
|
|
|
|
auto lhsFloat = (dynamic_pointer_cast<Constant>(lhs) == nullptr && lhs->get_type()->is_float_type()) || dynamic_pointer_cast<ConstantFloat>(lhs);
|
|
|
|
|
auto rhsFloat = (dynamic_pointer_cast<Constant>(rhs) == nullptr && rhs->get_type()->is_float_type()) || dynamic_pointer_cast<ConstantFloat>(rhs);
|
|
|
|
|
if (lhsFloat && !rhsFloat) {
|
|
|
|
|
rhs = builder->create_sitofp(rhs, FLOAT_T);
|
|
|
|
|
}
|
|
|
|
|
if (lhs->get_type()->is_integer_type() &&
|
|
|
|
|
rhs->get_type()->is_float_type()) {
|
|
|
|
|
if (!lhsFloat && rhsFloat) {
|
|
|
|
|
lhs = builder->create_sitofp(lhs, FLOAT_T);
|
|
|
|
|
}
|
|
|
|
|
isFloat = lhs->get_type()->is_float_type();
|
|
|
|
|
isFloat = lhsFloat || rhsFloat;
|
|
|
|
|
switch (op) {
|
|
|
|
|
case SyntaxTree::BinOp::PLUS:
|
|
|
|
|
if (isFloat) {
|
|
|
|
|
std::cout << 1<<std::endl;
|
|
|
|
|
tmpInst = builder->create_fadd(lhs, rhs);
|
|
|
|
|
} else
|
|
|
|
|
std::cout << 2 <<std::endl;
|
|
|
|
|
} else {
|
|
|
|
|
tmpInst = builder->create_iadd(lhs, rhs);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SyntaxTree::BinOp::MINUS:
|
|
|
|
|
if (isFloat) {
|
|
|
|
@ -233,21 +238,24 @@ void IRBuilder::BinaryCondExprGen(Ptr<Value> lhs, Ptr<Value> rhs, SyntaxTree::Bi
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (lhs->get_type()->is_pointer_type()) {
|
|
|
|
|
if (dynamic_pointer_cast<Constant>(lhs) == nullptr &&lhs->get_type()->is_pointer_type()) {
|
|
|
|
|
lhs = builder->create_load(lhs);
|
|
|
|
|
}
|
|
|
|
|
if (rhs->get_type()->is_pointer_type()) {
|
|
|
|
|
std::cout << (dynamic_pointer_cast<Constant>(rhs)) <<std::endl;
|
|
|
|
|
std::cout << 2<<std::endl;
|
|
|
|
|
if (dynamic_pointer_cast<Constant>(rhs) == nullptr && rhs->get_type()->is_pointer_type()) {
|
|
|
|
|
rhs = builder->create_load(rhs);
|
|
|
|
|
}
|
|
|
|
|
if (lhs->get_type()->is_float_type() &&
|
|
|
|
|
rhs->get_type()->is_integer_type()) {
|
|
|
|
|
std::cout << 2<<std::endl;
|
|
|
|
|
auto lhsFloat = (dynamic_pointer_cast<Constant>(lhs) == nullptr && lhs->get_type()->is_float_type()) || dynamic_pointer_cast<ConstantFloat>(lhs);
|
|
|
|
|
auto rhsFloat = (dynamic_pointer_cast<Constant>(rhs) == nullptr && rhs->get_type()->is_float_type()) || dynamic_pointer_cast<ConstantFloat>(rhs);
|
|
|
|
|
if (lhsFloat && !rhsFloat) {
|
|
|
|
|
rhs = builder->create_sitofp(rhs, FLOAT_T);
|
|
|
|
|
}
|
|
|
|
|
if (lhs->get_type()->is_integer_type() &&
|
|
|
|
|
rhs->get_type()->is_float_type()) {
|
|
|
|
|
if (!lhsFloat && rhsFloat) {
|
|
|
|
|
lhs = builder->create_sitofp(lhs, FLOAT_T);
|
|
|
|
|
}
|
|
|
|
|
isFloat = lhs->get_type()->is_float_type();
|
|
|
|
|
isFloat = lhsFloat && rhsFloat;
|
|
|
|
|
switch (op) {
|
|
|
|
|
case SyntaxTree::BinaryCondOp::LT:
|
|
|
|
|
if (isFloat) {
|
|
|
|
@ -312,6 +320,7 @@ void IRBuilder::TypeConvert(Ptr<Value> origin, Ptr<Type> expected) {
|
|
|
|
|
if (type->is_pointer_type()) {
|
|
|
|
|
type = type->get_pointer_element_type();
|
|
|
|
|
origin = builder->create_load(origin);
|
|
|
|
|
tmpInst = origin;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (type == INT32_T && expected == INT1_T) {
|
|
|
|
@ -322,7 +331,6 @@ void IRBuilder::TypeConvert(Ptr<Value> origin, Ptr<Type> expected) {
|
|
|
|
|
tmpInst = builder->create_fcmp_ne(origin, CONST_FLOAT(0));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (type == INT32_T && expected == FLOAT_T) {
|
|
|
|
|
tmpInst = builder->create_sitofp(origin, expected);
|
|
|
|
|
return;
|
|
|
|
@ -331,7 +339,6 @@ void IRBuilder::TypeConvert(Ptr<Value> origin, Ptr<Type> expected) {
|
|
|
|
|
tmpInst = builder->create_fptosi(origin, expected);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
auto tmpInt = dynamic_pointer_cast<ConstantInt>(origin);
|
|
|
|
|
auto tmpFloat = dynamic_pointer_cast<ConstantFloat>(origin);
|
|
|
|
@ -375,6 +382,7 @@ void IRBuilder::visit(SyntaxTree::InitVal &node) {
|
|
|
|
|
|
|
|
|
|
// FINISH
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::FuncDef &node) {
|
|
|
|
|
|
|
|
|
|
auto funcRetType = GetParamType(node.ret_type);
|
|
|
|
|
node.param_list->accept(*this);
|
|
|
|
|
auto funcType = FunctionType::create(funcRetType, funcFParam);
|
|
|
|
@ -393,7 +401,6 @@ void IRBuilder::visit(SyntaxTree::FuncDef &node) {
|
|
|
|
|
for (const auto &arg : funcArgs) {
|
|
|
|
|
if(para == para_end)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
auto name = (*para)->name;
|
|
|
|
|
auto argAlloca = builder->create_alloca(arg->get_type());
|
|
|
|
|
builder->create_store(arg, argAlloca);
|
|
|
|
@ -406,6 +413,7 @@ void IRBuilder::visit(SyntaxTree::FuncDef &node) {
|
|
|
|
|
retAlloca = builder->create_alloca(funcRetType);
|
|
|
|
|
}
|
|
|
|
|
node.body->accept(*this);
|
|
|
|
|
|
|
|
|
|
if (builder->get_insert_block()->get_terminator() == nullptr) {
|
|
|
|
|
if (funcRetType == INT32_T) {
|
|
|
|
|
builder->create_store(CONST_INT(0), retAlloca);
|
|
|
|
@ -414,7 +422,6 @@ void IRBuilder::visit(SyntaxTree::FuncDef &node) {
|
|
|
|
|
}
|
|
|
|
|
builder->create_br(retBB);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
builder->set_insert_point(retBB);
|
|
|
|
|
if (funcRetType == VOID_T) {
|
|
|
|
|
builder->create_void_ret();
|
|
|
|
@ -455,8 +462,11 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
|
|
|
|
|
if (scope.in_global()) {
|
|
|
|
|
if (!node.is_inited || (!node.array_length.empty() && node.initializers->elementList.empty())) {
|
|
|
|
|
auto zeroInit = ConstantZero::create(varType, module);
|
|
|
|
|
if (node.array_length.empty()) {
|
|
|
|
|
identAlloca = GlobalVariable::create(node.name, module, varType, false, zeroInit);
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
identAlloca = GlobalVariable::create(node.name, module, arrayType, false, zeroInit);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (!node.array_length.empty()) {
|
|
|
|
|
std::vector<Ptr<Constant>> varInit;
|
|
|
|
@ -472,20 +482,17 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
|
|
|
|
|
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
|
|
|
|
|
}
|
|
|
|
|
auto zeroInit = ConstantZero::create(varType, module);
|
|
|
|
|
identAlloca = GlobalVariable::create(node.name, module, arrayType, false, zeroInit);
|
|
|
|
|
for (int i = 0; i < varInit.size(); i++) {
|
|
|
|
|
auto index = CONST_INT(i);
|
|
|
|
|
auto ptr = builder->create_gep(identAlloca, {CONST_INT(0), index});
|
|
|
|
|
builder->create_store(varInit[i], ptr);
|
|
|
|
|
}
|
|
|
|
|
//alter
|
|
|
|
|
//auto tmpInit = ConstantArray::create(static_pointer_cast<ArrayType>(varType), varInit);
|
|
|
|
|
//identAlloca = GlobalVariable::create(node.name, module, varType, false, tmpInit);
|
|
|
|
|
auto tmpInit = ConstantArray::create(static_pointer_cast<ArrayType>(varType), varInit);
|
|
|
|
|
identAlloca = GlobalVariable::create(node.name, module, varType, node.is_constant, tmpInit);
|
|
|
|
|
//std::cout <<"VarDef1"<<std::endl;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
//std::cout <<"VarDef2"<<std::endl;
|
|
|
|
|
if (node.is_constant) {
|
|
|
|
|
node.initializers->expr->accept(*this);
|
|
|
|
|
TypeConvert(tmpInst, varType);
|
|
|
|
|
identAlloca = tmpInst;
|
|
|
|
|
auto tmpInit = dynamic_pointer_cast<Constant>(tmpInst);
|
|
|
|
|
identAlloca = tmpInit;
|
|
|
|
|
} else {
|
|
|
|
|
node.initializers->expr->accept(*this);
|
|
|
|
|
TypeConvert(tmpInst, varType);
|
|
|
|
@ -539,12 +546,12 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
|
|
|
|
|
// FINISH
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::LVal &node) {
|
|
|
|
|
auto ident = scope.find(node.name, false);
|
|
|
|
|
|
|
|
|
|
if (!node.array_index.empty()) {
|
|
|
|
|
node.array_index[0]->accept(*this);
|
|
|
|
|
auto constIndex = dynamic_pointer_cast<ConstantInt>(tmpInst);
|
|
|
|
|
auto globalIdent = dynamic_pointer_cast<GlobalVariable>(ident);
|
|
|
|
|
if(globalIdent != nullptr && globalIdent->is_const() && constIndex == nullptr) {
|
|
|
|
|
if(globalIdent != nullptr && globalIdent->is_const() && constIndex != nullptr) {
|
|
|
|
|
std::cout << "Const LVal "<<std::endl;
|
|
|
|
|
auto arrayInit = dynamic_pointer_cast<ConstantArray>(globalIdent->get_init());
|
|
|
|
|
tmpInst = arrayInit->get_element_value(constIndex->get_value());
|
|
|
|
|
} else {
|
|
|
|
@ -594,8 +601,9 @@ void IRBuilder::visit(SyntaxTree::ReturnStmt &node) {
|
|
|
|
|
auto expectRetType =
|
|
|
|
|
builder->get_insert_block()->get_parent()->get_return_type();
|
|
|
|
|
TypeConvert(tmpInst, expectRetType);
|
|
|
|
|
auto retValue = tmpInst;
|
|
|
|
|
builder->create_store(retValue, retAlloca);
|
|
|
|
|
std::cout << "RET" <<std::endl;
|
|
|
|
|
builder->create_store(tmpInst, retAlloca);
|
|
|
|
|
std::cout << "RET" <<std::endl;
|
|
|
|
|
}
|
|
|
|
|
// every ret stmt only store the value and jump to the retBB
|
|
|
|
|
builder->create_br(retBB);
|
|
|
|
@ -606,6 +614,7 @@ void IRBuilder::visit(SyntaxTree::ReturnStmt &node) {
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::BlockStmt &node) {
|
|
|
|
|
scope.enter();
|
|
|
|
|
for (const auto &stmt : node.body) {
|
|
|
|
|
std::cout << "Block" <<std::endl;
|
|
|
|
|
stmt->accept(*this);
|
|
|
|
|
}
|
|
|
|
|
scope.exit();
|
|
|
|
|