|
|
|
@ -29,15 +29,6 @@ Ptr<Value> retAlloca;
|
|
|
|
|
Ptr<Value> tmpInst;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int tmpConstVal = 0;
|
|
|
|
|
Ptr<Value> tmpVal = nullptr;
|
|
|
|
|
std::vector<Ptr<Value>> arrayInitializer;
|
|
|
|
|
std::string curFuncName = "";
|
|
|
|
|
bool isFloat = false;
|
|
|
|
|
bool isAddr = false;
|
|
|
|
|
Ptr<BasicBlock> curCondBB;
|
|
|
|
|
Ptr<BasicBlock> curAfterBB;
|
|
|
|
|
|
|
|
|
|
// types
|
|
|
|
|
Ptr<Type> VOID_T;
|
|
|
|
|
Ptr<Type> INT1_T;
|
|
|
|
@ -371,7 +362,6 @@ void IRBuilder::visit(SyntaxTree::Assembly &node) {
|
|
|
|
|
INT32PTR_T = Type::get_int32_ptr_type(module);
|
|
|
|
|
FLOATPTR_T = Type::get_float_ptr_type(module);
|
|
|
|
|
for (const auto &def : node.global_defs) {
|
|
|
|
|
//std::cout << "4" << std::endl;
|
|
|
|
|
def->accept(*this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -399,26 +389,23 @@ void IRBuilder::visit(SyntaxTree::FuncDef &node) {
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
auto funcArgs = func->get_args();
|
|
|
|
|
for (const auto &arg : funcArgs) {
|
|
|
|
|
if(para == para_end)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto name = (*para)->name;
|
|
|
|
|
auto val = (*arg);
|
|
|
|
|
auto argAlloca = builder->create_alloca(val->get_type());
|
|
|
|
|
builder->create_store(val, argAlloca);
|
|
|
|
|
auto argAlloca = builder->create_alloca(arg->get_type());
|
|
|
|
|
builder->create_store(arg, argAlloca);
|
|
|
|
|
scope.push(name, argAlloca);
|
|
|
|
|
para++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (funcRetType == VOID_T) {
|
|
|
|
|
;
|
|
|
|
|
} else {
|
|
|
|
|
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);
|
|
|
|
@ -435,7 +422,6 @@ void IRBuilder::visit(SyntaxTree::FuncDef &node) {
|
|
|
|
|
auto ret_val = builder->create_load(retAlloca);
|
|
|
|
|
builder->create_ret(ret_val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
scope.exit();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -449,141 +435,105 @@ void IRBuilder::visit(SyntaxTree::FuncFParamList &node) {
|
|
|
|
|
|
|
|
|
|
// FINISH
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::FuncParam &node) {
|
|
|
|
|
auto tmpType = GetParamType(node.param_type, node.array_index[0] != nullptr);
|
|
|
|
|
auto tmpType = GetParamType(node.param_type, node.array_index.empty());
|
|
|
|
|
funcFParam.push_back(tmpType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
|
// FINISH
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::VarDef &node) {
|
|
|
|
|
int arrayLength;
|
|
|
|
|
Ptr<Value> initVal;
|
|
|
|
|
if (node.is_constant) {
|
|
|
|
|
assert(node.is_inited);
|
|
|
|
|
switch (node.btype) {
|
|
|
|
|
case (SyntaxTree::Type::INT):
|
|
|
|
|
if (!node.array_length.empty()) {
|
|
|
|
|
node.array_length[0]->accept(*this);
|
|
|
|
|
// expr need to return ConstVal if possible
|
|
|
|
|
arrayLength = tmpConstVal;
|
|
|
|
|
auto arrayType = ArrayType::get(INT32_T, arrayLength);
|
|
|
|
|
auto alloca = builder->create_alloca(arrayType);
|
|
|
|
|
arrayInitializer.clear();
|
|
|
|
|
// const int a[] = {};
|
|
|
|
|
int i = 0;
|
|
|
|
|
for ( const auto &expr : node.initializers->elementList) {
|
|
|
|
|
expr->accept(*this);
|
|
|
|
|
auto tmpInit = tmpInst;
|
|
|
|
|
tmpInst = builder->create_gep(alloca, {CONST_INT(0), CONST_INT(i)});
|
|
|
|
|
builder->create_store(tmpInit, tmpInst);
|
|
|
|
|
i ++;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// const int a = 1;
|
|
|
|
|
auto alloca = builder->create_alloca(INT32_T);
|
|
|
|
|
// type
|
|
|
|
|
auto varType = GetBaseType(node.btype);
|
|
|
|
|
Ptr<ArrayType> arrayType;
|
|
|
|
|
if (!node.array_length.empty()) {
|
|
|
|
|
node.array_length[0]->accept(*this);
|
|
|
|
|
auto constInt = dynamic_pointer_cast<ConstantInt>(tmpInst);
|
|
|
|
|
arrayType = ArrayType::create(varType, constInt->get_value());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ptr<Value> identAlloca;
|
|
|
|
|
if (scope.in_global()) {
|
|
|
|
|
if (!node.is_inited || (!node.array_length.empty() && node.initializers->elementList.empty())) {
|
|
|
|
|
auto zeroInit = ConstantZero::create(varType, module);
|
|
|
|
|
identAlloca = GlobalVariable::create(node.name, module, varType, false, zeroInit);
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
if (!node.array_length.empty()) {
|
|
|
|
|
std::vector<Ptr<Constant>> varInit;
|
|
|
|
|
for (const auto &init : node.initializers->elementList) {
|
|
|
|
|
init->accept(*this);
|
|
|
|
|
TypeConvert(tmpInst, varType);
|
|
|
|
|
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
|
|
|
|
|
}
|
|
|
|
|
auto otherLen = arrayType->get_num_of_elements() - node.initializers->elementList.size();
|
|
|
|
|
auto tmpZero = CONST_INT(0);
|
|
|
|
|
TypeConvert(tmpZero, varType);
|
|
|
|
|
for (int i = 0; i < otherLen; i++) {
|
|
|
|
|
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);
|
|
|
|
|
} else {
|
|
|
|
|
if (node.is_constant) {
|
|
|
|
|
node.initializers->expr->accept(*this);
|
|
|
|
|
initVal = tmpInst;
|
|
|
|
|
builder->create_store(initVal, alloca);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case (SyntaxTree::Type::FLOAT):
|
|
|
|
|
if (!node.array_length.empty()) {
|
|
|
|
|
node.array_length[0]->accept(*this);
|
|
|
|
|
// expr need to return ConstVal if possible
|
|
|
|
|
arrayLength = tmpConstVal;
|
|
|
|
|
auto arrayType = ArrayType::get(FLOAT_T, arrayLength);
|
|
|
|
|
auto alloca = builder->create_alloca(arrayType);
|
|
|
|
|
arrayInitializer.clear();
|
|
|
|
|
// const int a[] = {};
|
|
|
|
|
int i = 0;
|
|
|
|
|
for ( const auto &expr : node.initializers->elementList) {
|
|
|
|
|
expr->accept(*this);
|
|
|
|
|
auto tmpInit = tmpInst;
|
|
|
|
|
tmpInst = builder->create_gep(alloca, {CONST_INT(0), CONST_INT(i)});
|
|
|
|
|
builder->create_store(tmpInit, tmpInst);
|
|
|
|
|
i ++;
|
|
|
|
|
}
|
|
|
|
|
TypeConvert(tmpInst, varType);
|
|
|
|
|
identAlloca = tmpInst;
|
|
|
|
|
} else {
|
|
|
|
|
// const float a = 1.0;
|
|
|
|
|
auto alloca = builder->create_alloca(FLOAT_T);
|
|
|
|
|
node.initializers->expr->accept(*this);
|
|
|
|
|
initVal = tmpInst;
|
|
|
|
|
builder->create_store(initVal, alloca);
|
|
|
|
|
TypeConvert(tmpInst, varType);
|
|
|
|
|
auto constInit = dynamic_pointer_cast<Constant>(tmpInst);
|
|
|
|
|
identAlloca = GlobalVariable::create(node.name, module, varType,
|
|
|
|
|
false, constInit);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
scope.push(node.name, identAlloca);
|
|
|
|
|
} else {
|
|
|
|
|
switch (node.btype) {
|
|
|
|
|
case (SyntaxTree::Type::INT):
|
|
|
|
|
if (!node.array_length.empty()) {
|
|
|
|
|
node.array_length[0]->accept(*this);
|
|
|
|
|
// expr need to return ConstVal if possible
|
|
|
|
|
arrayLength = tmpConstVal;
|
|
|
|
|
auto arrayType = ArrayType::get(INT32_T, arrayLength);
|
|
|
|
|
auto alloca = builder->create_alloca(arrayType);
|
|
|
|
|
if (node.is_inited) {
|
|
|
|
|
int i = 0;
|
|
|
|
|
for ( const auto &expr : node.initializers->elementList) {
|
|
|
|
|
expr->accept(*this);
|
|
|
|
|
auto tmpInit = tmpInst;
|
|
|
|
|
tmpInst = builder->create_gep(alloca, {CONST_INT(0), CONST_INT(i)});
|
|
|
|
|
builder->create_store(tmpInit, tmpInst);
|
|
|
|
|
i ++;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
auto alloca = builder->create_alloca(INT32_T);
|
|
|
|
|
if (node.is_inited) {
|
|
|
|
|
node.initializers->expr->accept(*this);
|
|
|
|
|
initVal = tmpInst;
|
|
|
|
|
builder->create_store(initVal, alloca);
|
|
|
|
|
} else {
|
|
|
|
|
builder->create_store(CONST_INT(0), alloca);
|
|
|
|
|
scope.push(node.name, alloca);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case (SyntaxTree::Type::FLOAT):
|
|
|
|
|
if (!node.array_length.empty()) {
|
|
|
|
|
node.array_length[0]->accept(*this);
|
|
|
|
|
// expr need to return ConstVal if possible
|
|
|
|
|
arrayLength = tmpConstVal;
|
|
|
|
|
auto arrayType = ArrayType::get(FLOAT_T, arrayLength);
|
|
|
|
|
auto alloca = builder->create_alloca(arrayType);
|
|
|
|
|
if (node.is_inited) {
|
|
|
|
|
int i = 0;
|
|
|
|
|
for ( const auto &expr : node.initializers->elementList) {
|
|
|
|
|
expr->accept(*this);
|
|
|
|
|
auto tmpInit = tmpInst;
|
|
|
|
|
tmpInst = builder->create_gep(alloca, {CONST_INT(0), CONST_INT(i)});
|
|
|
|
|
builder->create_store(tmpInit, tmpInst);
|
|
|
|
|
i ++;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
auto alloca = builder->create_alloca(FLOAT_T);
|
|
|
|
|
if (node.is_inited) {
|
|
|
|
|
node.initializers->expr->accept(*this);
|
|
|
|
|
initVal = tmpInst;
|
|
|
|
|
builder->create_store(initVal, alloca);
|
|
|
|
|
} else {
|
|
|
|
|
builder->create_store(CONST_FLOAT(0.0), alloca);
|
|
|
|
|
scope.push(node.name, alloca);
|
|
|
|
|
}
|
|
|
|
|
if (node.is_constant && node.array_length.empty()) {
|
|
|
|
|
node.initializers->expr->accept(*this);
|
|
|
|
|
TypeConvert(tmpInst, varType);
|
|
|
|
|
identAlloca = tmpInst;
|
|
|
|
|
scope.push(node.name, identAlloca);
|
|
|
|
|
return ;
|
|
|
|
|
} else {
|
|
|
|
|
identAlloca = builder->create_alloca(varType);
|
|
|
|
|
scope.push(node.name, identAlloca);
|
|
|
|
|
if (node.array_length.empty()) {
|
|
|
|
|
node.initializers->expr->accept(*this);
|
|
|
|
|
TypeConvert(tmpInst, varType);
|
|
|
|
|
builder->create_store(tmpInst, identAlloca);
|
|
|
|
|
return ;
|
|
|
|
|
} else {
|
|
|
|
|
std::vector<Ptr<Constant>> varInit;
|
|
|
|
|
for (const auto &init : node.initializers->elementList) {
|
|
|
|
|
init->accept(*this);
|
|
|
|
|
TypeConvert(tmpInst, varType);
|
|
|
|
|
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
|
|
|
|
|
}
|
|
|
|
|
auto otherLen = arrayType->get_num_of_elements() - node.initializers->elementList.size();
|
|
|
|
|
auto tmpZero = CONST_INT(0);
|
|
|
|
|
TypeConvert(tmpZero, varType);
|
|
|
|
|
for (int i = 0; i < otherLen; i++) {
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FINISH
|
|
|
|
@ -626,13 +576,13 @@ void IRBuilder::visit(SyntaxTree::AssignStmt &node) {
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::Literal &node) {
|
|
|
|
|
switch(node.literal_type) {
|
|
|
|
|
case SyntaxTree::Type::INT:
|
|
|
|
|
tmpVal = CONST_INT(node.int_const);
|
|
|
|
|
tmpInst = CONST_INT(node.int_const);
|
|
|
|
|
break;
|
|
|
|
|
case SyntaxTree::Type::FLOAT:
|
|
|
|
|
tmpVal = CONST_FLOAT(node.float_const);
|
|
|
|
|
tmpInst = CONST_FLOAT(node.float_const);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
tmpVal = CONST_INT(0);
|
|
|
|
|
tmpInst = CONST_INT(0);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -746,12 +696,14 @@ void IRBuilder::visit(SyntaxTree::BinaryExpr &node) {
|
|
|
|
|
// FINISH
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::UnaryExpr &node) {
|
|
|
|
|
node.rhs->accept(*this);
|
|
|
|
|
Ptr<ConstantInt> constInt;
|
|
|
|
|
Ptr<ConstantFloat> constFloat;
|
|
|
|
|
switch (node.op) {
|
|
|
|
|
case SyntaxTree::UnaryOp::PLUS:
|
|
|
|
|
break;
|
|
|
|
|
case SyntaxTree::UnaryOp::MINUS:
|
|
|
|
|
auto constInt = dynamic_pointer_cast<ConstantInt>(tmpInst);
|
|
|
|
|
auto constFloat = dynamic_pointer_cast<ConstantFloat>(tmpInst);
|
|
|
|
|
constInt = dynamic_pointer_cast<ConstantInt>(tmpInst);
|
|
|
|
|
constFloat = dynamic_pointer_cast<ConstantFloat>(tmpInst);
|
|
|
|
|
if (constInt != nullptr) {
|
|
|
|
|
tmpInst = CONST_INT(-constInt->get_value());
|
|
|
|
|
} else if (constFloat != nullptr) {
|
|
|
|
|