|
|
@ -13,9 +13,10 @@ namespace IR
|
|
|
|
// to store state
|
|
|
|
// to store state
|
|
|
|
|
|
|
|
|
|
|
|
// store temporary value
|
|
|
|
// store temporary value
|
|
|
|
Ptr<Value> tmp_val = nullptr;
|
|
|
|
int tmpConstVal = 0;
|
|
|
|
std::vector<SysYF::Ptr<Type>> funcFParam;
|
|
|
|
Ptr<Value> tmpVal = nullptr;
|
|
|
|
int exprRes = 0;
|
|
|
|
std::vector<Ptr<Type>> funcFParam;
|
|
|
|
|
|
|
|
std::vector<Ptr<Value>> arrayInitializer;
|
|
|
|
std::string curFuncName = "";
|
|
|
|
std::string curFuncName = "";
|
|
|
|
Ptr<SysYF::IR::Instruction> tmpInst;
|
|
|
|
Ptr<SysYF::IR::Instruction> tmpInst;
|
|
|
|
bool isFloat = false;
|
|
|
|
bool isFloat = false;
|
|
|
@ -102,23 +103,59 @@ void IRBuilder::visit(SyntaxTree::FuncParam &node) {
|
|
|
|
|
|
|
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::VarDef &node) {
|
|
|
|
void IRBuilder::visit(SyntaxTree::VarDef &node) {
|
|
|
|
// TODO: high dim array (not now)
|
|
|
|
// TODO: high dim array (not now)
|
|
|
|
Ptr<Value> arrayLength;
|
|
|
|
int arrayLength;
|
|
|
|
Ptr<Value> initVal;
|
|
|
|
Ptr<Value> initVal;
|
|
|
|
if (node.is_constant) {
|
|
|
|
if (node.is_constant) {
|
|
|
|
assert(node.is_inited);
|
|
|
|
assert(node.is_inited);
|
|
|
|
switch (node.btype) {
|
|
|
|
switch (node.btype) {
|
|
|
|
case (SyntaxTree::Type::INT):
|
|
|
|
case (SyntaxTree::Type::INT):
|
|
|
|
if (!node.array_length.empty()) {
|
|
|
|
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 {
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// const int a = 1;
|
|
|
|
|
|
|
|
auto alloca = builder->create_alloca(INT32_T);
|
|
|
|
|
|
|
|
node.initializers->expr->accept(*this);
|
|
|
|
|
|
|
|
initVal = tmpInst;
|
|
|
|
|
|
|
|
builder->create_store(initVal, alloca);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case (SyntaxTree::Type::FLOAT):
|
|
|
|
case (SyntaxTree::Type::FLOAT):
|
|
|
|
if (!node.array_length.empty()) {
|
|
|
|
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 ++;
|
|
|
|
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
default:
|
|
|
@ -128,12 +165,28 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
|
|
|
|
switch (node.btype) {
|
|
|
|
switch (node.btype) {
|
|
|
|
case (SyntaxTree::Type::INT):
|
|
|
|
case (SyntaxTree::Type::INT):
|
|
|
|
if (!node.array_length.empty()) {
|
|
|
|
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 {
|
|
|
|
} else {
|
|
|
|
auto alloca = builder->create_alloca(INT32_T);
|
|
|
|
auto alloca = builder->create_alloca(INT32_T);
|
|
|
|
if (node.is_inited) {
|
|
|
|
if (node.is_inited) {
|
|
|
|
|
|
|
|
node.initializers->expr->accept(*this);
|
|
|
|
|
|
|
|
initVal = tmpInst;
|
|
|
|
builder->create_store(initVal, alloca);
|
|
|
|
builder->create_store(initVal, alloca);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
builder->create_store(CONST_INT(0), alloca);
|
|
|
|
builder->create_store(CONST_INT(0), alloca);
|
|
|
@ -143,15 +196,32 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case (SyntaxTree::Type::FLOAT):
|
|
|
|
case (SyntaxTree::Type::FLOAT):
|
|
|
|
if (!node.array_length.empty()) {
|
|
|
|
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 {
|
|
|
|
} else {
|
|
|
|
auto alloca = builder->create_alloca(FLOAT_T);
|
|
|
|
auto alloca = builder->create_alloca(FLOAT_T);
|
|
|
|
if (node.is_inited) {
|
|
|
|
if (node.is_inited) {
|
|
|
|
|
|
|
|
node.initializers->expr->accept(*this);
|
|
|
|
|
|
|
|
initVal = tmpInst;
|
|
|
|
builder->create_store(initVal, alloca);
|
|
|
|
builder->create_store(initVal, alloca);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
builder->create_store(CONST_FLOAT(0), alloca);
|
|
|
|
builder->create_store(CONST_FLOAT(0.0), alloca);
|
|
|
|
scope.push(node.name, alloca);
|
|
|
|
scope.push(node.name, alloca);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -194,22 +264,22 @@ void IRBuilder::visit(SyntaxTree::AssignStmt &node) {
|
|
|
|
void IRBuilder::visit(SyntaxTree::Literal &node) {
|
|
|
|
void IRBuilder::visit(SyntaxTree::Literal &node) {
|
|
|
|
switch(node.literal_type) {
|
|
|
|
switch(node.literal_type) {
|
|
|
|
case SyntaxTree::Type::INT:
|
|
|
|
case SyntaxTree::Type::INT:
|
|
|
|
tmp_val = CONST_INT(node.int_const);
|
|
|
|
tmpVal = CONST_INT(node.int_const);
|
|
|
|
isFloat = false;
|
|
|
|
isFloat = false;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case SyntaxTree::Type::FLOAT:
|
|
|
|
case SyntaxTree::Type::FLOAT:
|
|
|
|
tmp_val = CONST_FLOAT(node.float_const);
|
|
|
|
tmpVal = CONST_FLOAT(node.float_const);
|
|
|
|
isFloat = true;
|
|
|
|
isFloat = true;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
tmp_val = CONST_INT(0);
|
|
|
|
tmpVal = CONST_INT(0);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::ReturnStmt &node) {
|
|
|
|
void IRBuilder::visit(SyntaxTree::ReturnStmt &node) {
|
|
|
|
node.ret->accept(*this);
|
|
|
|
node.ret->accept(*this);
|
|
|
|
builder->create_ret(tmp_val);
|
|
|
|
builder->create_ret(tmpVal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::BlockStmt &node) {
|
|
|
|
void IRBuilder::visit(SyntaxTree::BlockStmt &node) {
|
|
|
@ -417,7 +487,7 @@ void IRBuilder::visit(SyntaxTree::FuncCallStmt &node) {
|
|
|
|
std::vector<Ptr<Value>> funcRParam;
|
|
|
|
std::vector<Ptr<Value>> funcRParam;
|
|
|
|
for (const auto ¶m : node.params) {
|
|
|
|
for (const auto ¶m : node.params) {
|
|
|
|
param->accept(*this);
|
|
|
|
param->accept(*this);
|
|
|
|
funcRParam.push_back(tmp_val);
|
|
|
|
funcRParam.push_back(tmpVal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
builder->create_call(curFunc, funcRParam);
|
|
|
|
builder->create_call(curFunc, funcRParam);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -425,7 +495,7 @@ void IRBuilder::visit(SyntaxTree::FuncCallStmt &node) {
|
|
|
|
void IRBuilder::visit(SyntaxTree::IfStmt &node) {
|
|
|
|
void IRBuilder::visit(SyntaxTree::IfStmt &node) {
|
|
|
|
auto curFunc = builder->get_insert_block()->get_parent();
|
|
|
|
auto curFunc = builder->get_insert_block()->get_parent();
|
|
|
|
node.cond_exp->accept(*this);
|
|
|
|
node.cond_exp->accept(*this);
|
|
|
|
auto cond = tmp_val;
|
|
|
|
auto cond = tmpVal;
|
|
|
|
auto trueBB = BasicBlock::create(module, "trueBB_if", curFunc);
|
|
|
|
auto trueBB = BasicBlock::create(module, "trueBB_if", curFunc);
|
|
|
|
auto falseBB = BasicBlock::create(module, "falseBB_if", curFunc);
|
|
|
|
auto falseBB = BasicBlock::create(module, "falseBB_if", curFunc);
|
|
|
|
builder->create_cond_br(cond, trueBB, falseBB);
|
|
|
|
builder->create_cond_br(cond, trueBB, falseBB);
|
|
|
@ -447,7 +517,7 @@ void IRBuilder::visit(SyntaxTree::WhileStmt &node) {
|
|
|
|
|
|
|
|
|
|
|
|
builder->set_insert_point(condBB);
|
|
|
|
builder->set_insert_point(condBB);
|
|
|
|
node.cond_exp->accept(*this);
|
|
|
|
node.cond_exp->accept(*this);
|
|
|
|
auto cond = tmp_val;
|
|
|
|
auto cond = tmpVal;
|
|
|
|
|
|
|
|
|
|
|
|
builder->create_cond_br(cond, bodyBB, afterBB);
|
|
|
|
builder->create_cond_br(cond, bodyBB, afterBB);
|
|
|
|
|
|
|
|
|
|
|
|