add task3 correct file

main
stivenkingsberg 1 year ago
parent 7f12bcaf02
commit b919258ffc

@ -17,7 +17,7 @@ namespace SysYF
BOOL,
FLOAT
};
std::vector<BasicBlock *> tmp_condbb_while;
std::vector<BasicBlock *> tmp_falsebb_while;
std::vector<BasicBlock *> tmp_truebb;
@ -25,7 +25,8 @@ namespace SysYF
std::map<SyntaxTree::Type, Ptr<Type>> type_map; // 把类型转换成类型指针
// store temporary value
Ptr<Value> tmp_val = nullptr;
vector<Ptr<Value>> init_list;
vector<SysYF::Ptr<Constant>> init_list;
Ptr<Type> array_init_type;
// types
Ptr<Type> VOID_T;
Ptr<Type> INT1_T;
@ -33,11 +34,52 @@ namespace SysYF
Ptr<Type> FLOAT_T;
Ptr<Type> INT32PTR_T;
Ptr<Type> FLOATPTR_T;
#define get_true_type(left_type, right) \
if (!scope.in_global()) \
{ \
if (left_type == INT32_T && right->get_type() == FLOAT_T) \
{ \
right = builder->create_fptosi(right, INT32_T); \
} \
else if (left_type == INT32_T && right->get_type() == INT1_T) \
{ \
right = builder->create_zext(right, INT32_T); \
} \
else if (left_type == INT1_T && right->get_type() == FLOAT_T) \
{ \
right = builder->create_fcmp_ne(right, CONST_FLOAT(0)); \
} \
else if (left_type == INT1_T && right->get_type() == INT32_T) \
{ \
right = builder->create_icmp_ne(right, CONST_INT(0)); \
} \
else if (left_type == FLOAT_T && right->get_type() == INT32_T) \
{ \
right = builder->create_sitofp(right, FLOAT_T); \
} \
else if (left_type == FLOAT_T && right->get_type() == INT1_T) \
{ \
right = builder->create_zext(right, FLOAT_T); \
} \
} \
else \
{ \
if (left_type == FLOAT_T && right->get_type() != FLOAT_T) \
{ \
right = CONST_FLOAT(static_cast<float>(dynamic_pointer_cast<ConstantInt>(right)->get_value())); \
} \
else if (left_type == INT32_T && right->get_type() != INT32_T) \
{ \
right = CONST_INT(static_cast<int>(dynamic_pointer_cast<ConstantFloat>(right)->get_value())); \
} \
}
#define LVal_to_RVal(lval) \
if(lval->get_type()==INT32PTR_T || lval->get_type()==FLOATPTR_T){\
lval=builder->create_load(lval);\
}
#define LVal_to_RVal(lval) \
if (lval->get_type() == INT32PTR_T || lval->get_type() == FLOATPTR_T) \
{ \
auto middle = lval; \
lval = builder->create_load(middle); \
}
void IRBuilder::visit(SyntaxTree::Assembly &node)
{
@ -72,9 +114,18 @@ namespace SysYF
}
else // is exp, values are in node.expr
{
node.expr->accept(*this); // 有可能是计算表达式,也有可能是赋值语句
node.expr->accept(*this); // 有可能是计算表达式,也有可能是赋值语句
LVal_to_RVal(tmp_val);
init_list.push_back(tmp_val); // 把tmp_val放到init_list里面
get_true_type(array_init_type, tmp_val);
// 把tmp_val放到init_list里面
if (array_init_type == INT32_T)
{
init_list.push_back(dynamic_pointer_cast<ConstantInt>(tmp_val));
}
else
{
init_list.push_back(dynamic_pointer_cast<ConstantFloat>(tmp_val));
}
}
} // init values
@ -123,11 +174,20 @@ namespace SysYF
switch (node.ret_type)
{
case SyntaxTree::Type::VOID:
{
builder->create_void_ret();
break;
}
case SyntaxTree::Type::INT:
{
builder->create_ret(CONST_INT(0));
break;
}
case SyntaxTree::Type::FLOAT:
{
builder->create_ret(CONST_FLOAT(0));
break;
}
default:
break;
}
@ -183,16 +243,51 @@ namespace SysYF
{
if (scope.in_global()) // 如果是全局变量
{
auto global_var = GlobalVariable::create(var_name, module, var_type, is_const, ConstantZero::create(var_type, module));
if (is_initialized)
if (is_const)
{
init_val->accept(*this);
LVal_to_RVal(tmp_val);
builder->create_store(tmp_val, global_var);
if (is_initialized)
{
init_val->accept(*this);
LVal_to_RVal(tmp_val);
get_true_type(var_type, tmp_val);
if (var_type == INT32_T)
{
auto global_var = GlobalVariable::create(var_name, module, var_type, true, dynamic_pointer_cast<ConstantInt>(tmp_val));
scope.push(var_name, global_var);
}
else
{
auto global_var = GlobalVariable::create(var_name, module, var_type, true, dynamic_pointer_cast<ConstantFloat>(tmp_val));
scope.push(var_name, global_var);
}
}
else
cout << "const variable must be initialized" << endl;
}
else
{
if (is_initialized)
{
init_val->accept(*this);
LVal_to_RVal(tmp_val);
get_true_type(var_type, tmp_val);
if (var_type == INT32_T)
{
auto global_var = GlobalVariable::create(var_name, module, var_type, false, dynamic_pointer_cast<ConstantInt>(tmp_val));
scope.push(var_name, global_var);
}
else
{
auto global_var = GlobalVariable::create(var_name, module, var_type, false, dynamic_pointer_cast<ConstantFloat>(tmp_val));
scope.push(var_name, global_var);
}
}
else
{
auto global_var = GlobalVariable::create(var_name, module, var_type, false, ConstantZero::create(var_type, module));
scope.push(var_name, global_var);
}
}
else if (is_const) // 说明是const但是没有初始化
cout << "const variable must be initialized" << endl;
scope.push(var_name, global_var);
}
else // 如果是局部变量
{
@ -201,7 +296,8 @@ namespace SysYF
{
init_val->accept(*this);
LVal_to_RVal(tmp_val);
builder->create_store(tmp_val , var);
get_true_type(var_type, tmp_val);
builder->create_store(tmp_val, var);
}
else if (is_const) // 说明是const但是没有初始化
cout << "const variable must be initialized" << endl;
@ -210,31 +306,58 @@ namespace SysYF
}
else // 数组
{
auto arrayType = ArrayType::get(var_type, length.size());
for (const auto &exp : length)
{
exp->accept(*this);
}
auto array_len = dynamic_pointer_cast<ConstantInt>(tmp_val)->get_value();
auto arrayType = ArrayType::get(var_type, array_len);
array_init_type = var_type;
if (scope.in_global()) // 如果是全局变量
{
auto global_array = GlobalVariable::create(var_name, module, arrayType, is_const, ConstantZero::create(var_type, module));
if (is_initialized)
if (is_const)
{
init_list.clear(); // 清空init_list
init_val->accept(*this); // 把init_val里面的值放到init_list里面
while (init_list.size() < length.size()) // 如果init_list的长度小于length的长度就把init_list其他的值补上0
if (is_initialized)
{
init_list.push_back(ConstantZero::create(type_map[node.btype], module));
init_list.clear(); // 清空init_list
init_val->accept(*this); // 把init_val里面的值放到init_list里面
while (static_cast<int>(init_list.size()) < array_len) // 如果init_list的长度小于length的长度就把init_list其他的值补上0
{
init_list.push_back(ConstantZero::create(type_map[node.btype], module));
}
auto array_initializer = ConstantArray::create(arrayType, init_list);
auto global_var = GlobalVariable::create(var_name, module, arrayType, true, array_initializer);
scope.push(var_name, global_var);
}
// initilize
for (auto i = 0; i < static_cast<int>(init_list.size()); i++)
else
cout << "const variable must be initialized" << endl;
}
else
{
if (is_initialized)
{
auto GEP = builder->create_gep(global_array, {CONST_INT(0), CONST_INT(i)});
builder->create_store(init_list[i], GEP);
init_list.clear(); // 清空init_list
init_val->accept(*this); // 把init_val里面的值放到init_list里面
while (static_cast<int>(init_list.size()) < array_len) // 如果init_list的长度小于length的长度就把init_list其他的值补上0
{
init_list.push_back(ConstantZero::create(type_map[node.btype], module));
}
auto array_initializer = ConstantArray::create(arrayType, init_list);
auto global_var = GlobalVariable::create(var_name, module, arrayType, false, array_initializer);
scope.push(var_name, global_var);
}
else
{
init_list.clear();
while (init_list.size() < length.size()) // 如果init_list的长度小于length的长度就把init_list其他的值补上0
{
init_list.push_back(ConstantZero::create(type_map[node.btype], module));
}
auto array_initializer = ConstantArray::create(arrayType, init_list);
auto global_var = GlobalVariable::create(var_name, module, arrayType, false, array_initializer);
scope.push(var_name, global_var);
}
}
else if (is_const) // 说明是const但是没有初始化
cout << "const variable must be initialized" << endl;
scope.push(var_name, global_array);
}
else
{
@ -262,7 +385,8 @@ namespace SysYF
}
}
}
// int c;
// c = 1.8;
void IRBuilder::visit(SyntaxTree::LVal &node)
{
auto name = node.name;
@ -270,19 +394,58 @@ namespace SysYF
auto lval = scope.find(name, false);
if (lval)
{
if (!index.empty())
if (scope.in_global())
{
for (const auto &exp : index)
auto global_var = dynamic_pointer_cast<GlobalVariable>(lval);
if (global_var->is_const())
{
exp->accept(*this);
auto tmp = tmp_val;
auto GEP = builder->create_gep(lval, {tmp});
lval = GEP;
if (index.empty()) //
{
tmp_val = global_var->get_init();
}
else
{
for (const auto &exp : index)
{
exp->accept(*this);
}
auto GEP = dynamic_pointer_cast<ConstantInt>(tmp_val);
tmp_val = dynamic_pointer_cast<ConstantArray>(global_var->get_init())->get_element_value(GEP->get_value());
}
}
else
{
if (index.empty())
{
tmp_val = global_var->get_init();
}
else
{
for (const auto &exp : index)
{
exp->accept(*this);
}
auto GEP = dynamic_pointer_cast<ConstantInt>(tmp_val);
tmp_val = dynamic_pointer_cast<ConstantArray>(global_var->get_init())->get_element_value(GEP->get_value());
}
}
}
else
{ // 从符号表中取出的是字面值
tmp_val = lval;
{
if (!index.empty())
{
for (const auto &exp : index)
{
exp->accept(*this);
}
auto tmp = tmp_val;
auto GEP = builder->create_gep(lval, {CONST_INT(0), tmp});
tmp_val = (GEP);
}
else
{ // 从符号表中取出的是字面值
tmp_val = (lval);
}
}
}
else
@ -294,12 +457,11 @@ namespace SysYF
void IRBuilder::visit(SyntaxTree::AssignStmt &node)
{
node.target->accept(*this);
auto target = builder->create_load(tmp_val);//?
auto name = target->get_name();
node.value->accept(*this);//?
auto target = tmp_val; //?Const_int(1).get_type() == INT32_T
node.value->accept(*this); //?
LVal_to_RVal(tmp_val);
auto value = tmp_val;
get_true_type(target->get_type(), value);
builder->create_store(value, target);
}
@ -309,9 +471,15 @@ namespace SysYF
switch (type)
{
case SyntaxTree::Type::INT:
{
tmp_val = CONST_INT(node.int_const);
break;
}
case SyntaxTree::Type::FLOAT:
{
tmp_val = CONST_FLOAT(node.float_const);
break;
}
default:
break;
}
@ -327,11 +495,11 @@ namespace SysYF
auto value_type = tmp_val->get_type();
auto ret_type = module->get_functions().back()->get_return_type();
// 类型检查
if(ret_type == INT32_T)
if (ret_type == INT32_T)
{
if(value_type == FLOAT_T)
if (value_type == FLOAT_T)
tmp_val = builder->create_fptosi(tmp_val, INT32_T);
else if(value_type == INT1_T)
else if (value_type == INT1_T)
tmp_val = builder->create_zext(tmp_val, INT32_T);
}
auto value = tmp_val;
@ -359,7 +527,6 @@ namespace SysYF
void IRBuilder::visit(SyntaxTree::EmptyStmt &node)
{
node.accept(*this);
}
void IRBuilder::visit(SyntaxTree::ExprStmt &node)
@ -375,13 +542,13 @@ namespace SysYF
// 整数
if (rhs->get_type() == INT32_T)
{
auto UnaryCondExpr = builder->create_icmp_eq(rhs, CONST_INT(0));
scope.push("CondExpr", UnaryCondExpr);
tmp_val = builder->create_icmp_eq(rhs, CONST_INT(0));
// scope.push("CondExpr", UnaryCondExpr);
}
else
{
auto UnaryCondExpr = builder->create_fcmp_eq(rhs, CONST_FLOAT(0));
scope.push("CondExpr", UnaryCondExpr);
tmp_val = builder->create_fcmp_eq(rhs, CONST_FLOAT(0));
// scope.push("CondExpr", UnaryCondExpr);
}
}
@ -448,32 +615,32 @@ namespace SysYF
if (lhs_type == INT1_T && rhs_type == INT32_T)
{
lhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_zext(lhs, INT32_T));
lhs = builder->create_zext(lhs, INT32_T);
}
else if (lhs_type == INT1_T && rhs_type == FLOAT_T)
{
lhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_zext(lhs, FLOAT_T));
lhs = (builder->create_zext(lhs, FLOAT_T));
}
else if (lhs_type == INT32_T && rhs_type == INT1_T)
{
rhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_zext(rhs, INT32_T));
rhs = (builder->create_zext(rhs, INT32_T));
}
else if (lhs_type == FLOAT_T && rhs_type == INT1_T)
{
rhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_zext(rhs, FLOAT_T));
rhs = (builder->create_zext(rhs, FLOAT_T));
}
else if (lhs_type == FLOAT_T && rhs_type == INT32_T)
{
rhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_sitofp(rhs, FLOAT_T));
rhs = (builder->create_sitofp(rhs, FLOAT_T));
}
else if (lhs_type == INT32_T && rhs_type == FLOAT_T)
{
lhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_sitofp(lhs, FLOAT_T));
lhs = (builder->create_sitofp(lhs, FLOAT_T));
}
else if (lhs_type == INT1_T && rhs_type == INT1_T)
{
lhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_zext(lhs, INT32_T));
rhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_zext(rhs, INT32_T));
lhs = (builder->create_zext(lhs, INT32_T));
rhs = (builder->create_zext(rhs, INT32_T));
}
// 整数
if (rhs->get_type() == INT32_T)
@ -506,6 +673,12 @@ namespace SysYF
case SysYF::SyntaxTree::BinaryCondOp::EQ:
{
tmp_val = builder->create_icmp_eq(lhs, rhs);
break;
}
case SysYF::SyntaxTree::BinaryCondOp::NEQ:
{
tmp_val = builder->create_icmp_ne(lhs, rhs);
break;
}
default:
break;
@ -541,6 +714,12 @@ namespace SysYF
case SysYF::SyntaxTree::BinaryCondOp::EQ:
{
tmp_val = builder->create_fcmp_eq(lhs, rhs);
break;
}
case SysYF::SyntaxTree::BinaryCondOp::NEQ:
{
tmp_val = builder->create_icmp_ne(lhs, rhs);
break;
}
default:
break;
@ -553,25 +732,26 @@ namespace SysYF
{
// 整数
node.rhs->accept(*this);
LVal_to_RVal(tmp_val);
auto rhs = tmp_val;
LVal_to_RVal(rhs);
auto rhs_type = rhs->get_type();
node.lhs->accept(*this);
LVal_to_RVal(tmp_val);
auto lhs = tmp_val;
LVal_to_RVal(lhs);
auto lhs_type = lhs->get_type();
if (lhs_type == FLOAT_T && rhs_type == INT32_T)
{
rhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_sitofp(rhs, FLOAT_T));
rhs = builder->create_sitofp(rhs, FLOAT_T);
}
else if (lhs_type == INT32_T && rhs_type == FLOAT_T)
{
lhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_sitofp(lhs, FLOAT_T));
lhs = builder->create_sitofp(lhs, FLOAT_T);
}
auto expr_type = lhs->get_type();
// 计算出可以直接计算的值
if ((dynamic_pointer_cast<ConstantFloat>(lhs) || dynamic_pointer_cast<ConstantFloat>(lhs)) && (dynamic_pointer_cast<ConstantFloat>(rhs) || dynamic_pointer_cast<ConstantFloat>(rhs)))
if (((dynamic_pointer_cast<ConstantFloat>(lhs) || dynamic_pointer_cast<ConstantFloat>(lhs)) && (dynamic_pointer_cast<ConstantFloat>(rhs) || dynamic_pointer_cast<ConstantFloat>(rhs))) || scope.in_global())
{ // 简单字面量计算
int lhs_int;
int rhs_int;
@ -643,60 +823,60 @@ namespace SysYF
}
return;
}
if (lhs_type == INT32_T)
else if (expr_type == INT32_T)
{
switch (node.op)
{
case SyntaxTree::BinOp::PLUS:
{
builder->create_iadd(lhs, rhs);
tmp_val = builder->create_iadd(lhs, rhs);
break;
}
case SyntaxTree::BinOp::MINUS:
{
builder->create_isub(lhs, rhs);
tmp_val = builder->create_isub(lhs, rhs);
break;
}
case SyntaxTree::BinOp::MULTIPLY:
{
builder->create_imul(lhs, rhs);
tmp_val = builder->create_imul(lhs, rhs);
break;
}
case SyntaxTree::BinOp::DIVIDE:
{
builder->create_isdiv(lhs, rhs);
tmp_val = builder->create_isdiv(lhs, rhs);
break;
}
case SyntaxTree::BinOp::MODULO:
{
builder->create_isrem(lhs, rhs);
tmp_val = builder->create_isrem(lhs, rhs);
break;
}
}
}
else if (lhs_type == FLOAT_T)
else if (expr_type == FLOAT_T)
{
switch (node.op)
{
case SyntaxTree::BinOp::PLUS:
{
builder->create_fadd(lhs, rhs);
tmp_val = builder->create_fadd(lhs, rhs);
break;
}
case SyntaxTree::BinOp::MINUS:
{
builder->create_fsub(lhs, rhs);
tmp_val = builder->create_fsub(lhs, rhs);
break;
}
case SyntaxTree::BinOp::MULTIPLY:
{
builder->create_fmul(lhs, rhs);
tmp_val = builder->create_fmul(lhs, rhs);
break;
}
case SyntaxTree::BinOp::DIVIDE:
{
builder->create_fdiv(lhs, rhs);
tmp_val = builder->create_fdiv(lhs, rhs);
break;
}
case SyntaxTree::BinOp::MODULO:
@ -760,12 +940,12 @@ namespace SysYF
{
case SyntaxTree::UnaryOp::PLUS:
{
builder->create_iadd(rhs, CONST_INT(0));
tmp_val = builder->create_iadd(rhs, CONST_INT(0));
break;
}
case SyntaxTree::UnaryOp::MINUS:
{
builder->create_isub(CONST_INT(0), rhs);
tmp_val = builder->create_isub(CONST_INT(0), rhs);
break;
}
}
@ -776,12 +956,12 @@ namespace SysYF
{
case SyntaxTree::UnaryOp::PLUS:
{
builder->create_fadd(rhs, CONST_FLOAT(0));
tmp_val = builder->create_fadd(rhs, CONST_FLOAT(0));
break;
}
case SyntaxTree::UnaryOp::MINUS:
{
builder->create_fsub(CONST_FLOAT(0), rhs);
tmp_val = builder->create_fsub(CONST_FLOAT(0), rhs);
break;
}
}
@ -826,12 +1006,16 @@ namespace SysYF
{
tmp_val = builder->create_fptosi(value, INT32_T);
}
else
{
tmp_val = value;
}
}
args.push_back(tmp_val);
}
builder->create_call(func, args);
tmp_val = builder->create_call(func, args);
}
}
@ -873,31 +1057,38 @@ namespace SysYF
auto falseBB = BasicBlock::create(module, "falseBB_while",
module->get_functions().back());
scope.push("condBB", condBB);
scope.push("trueBB", trueBB);
scope.push("falseBB", falseBB);
scope.push("condBB_while", condBB);
scope.push("trueBB_while", trueBB);
scope.push("falseBB_while", falseBB);
builder->create_br(condBB);
builder->set_insert_point(condBB);
node.cond_exp->accept(*this);
LVal_to_RVal(tmp_val);
auto cond = tmp_val;
builder->create_cond_br(cond, trueBB, falseBB);
auto cond_val = tmp_val;
builder->set_insert_point(trueBB);
node.statement->accept(*this);
builder->create_br(condBB);
builder->set_insert_point(falseBB);
// auto cond_val = tmp_val;
scope.exit();
}
void IRBuilder::visit(SyntaxTree::BreakStmt &node)
{
node.accept(*this);
auto falseBB = scope.find("falseBB", 0);
auto falseBB = scope.find("falseBB_while", 0);
builder->create_br(dynamic_pointer_cast<SysYF::IR::BasicBlock>(falseBB));
}
void IRBuilder::visit(SyntaxTree::ContinueStmt &node)
{
node.accept(*this);
auto condBB = scope.find("condBB", 0);
auto condBB = scope.find("condBB_while", 0);
builder->create_br(dynamic_pointer_cast<SysYF::IR::BasicBlock>(condBB));
}
}

Loading…
Cancel
Save