Commit 1b66a604 authored by 李晓奇's avatar 李晓奇

36.....

parent f78cd05a
......@@ -68,6 +68,7 @@ PB20111654 李晓奇
- 形如这种产生式子`term→term mulop factor ∣ factor`,我为了图方便先求了`factor`,在根据`term`的有调用`accept()`,但是这样会导致左右操作数颠倒。
- 我对于类型转换的控制比较严格,没考虑到的一率abort,因此很快发现了漏掉了bool类型的转换。
- 接上条,一些类型转换的bug:`i32``i1`也是需要转换的,开始做的时候还没意识到这些(主要是没意识到`i1`的存在)。
- 接上条,关于
## 实验设计
......
......@@ -43,25 +43,26 @@ void error_exit(std::string s) {
// This function makes sure that
// 1. 2 values have same type
// 2. type is either int or float
// 2. type is either i32 or float
void CminusfBuilder::type_cast(Value *&lvalue, Value *&rvalue, std::string util) {
assert(not Type::is_eq_type(lvalue->get_type(), rvalue->get_type()));
// only support cast between int and float
// only support cast between int and float: i32, i1, float
//
// case that integer and float is mixed, directly cast integer to float
if (lvalue->get_type()->is_integer_type() and rvalue->get_type()->is_float_type())
lvalue = builder->create_sitofp(lvalue, FLOAT_T);
else if (lvalue->get_type()->is_float_type() and rvalue->get_type()->is_integer_type())
rvalue = builder->create_sitofp(rvalue, FLOAT_T);
else { // but we only support computing between int and float
else if (lvalue->get_type()->is_integer_type() and rvalue->get_type()->is_integer_type()) {
// case that I32 and I1 mixed
if (Type::is_eq_type(lvalue->get_type(), INT1_T))
lvalue = builder->create_zext(lvalue, INT32_T);
else
rvalue = builder->create_zext(rvalue, INT32_T);
} else { // we only support computing among i1, i32 and float
error_exit("not supported type cast for " + util);
}
/* if (Type::is_eq_type(lvalue->get_type(), INT32_T) and Type::is_eq_type(rvalue->get_type(), FLOAT_T))
* lvalue = builder->create_sitofp(lvalue, FLOAT_T);
* else if (Type::is_eq_type(lvalue->get_type(), FLOAT_T) and Type::is_eq_type(rvalue->get_type(), INT32_T))
* rvalue = builder->create_sitofp(rvalue, FLOAT_T);
* else { // but we only support computing between int and float
* error_exit("not supported type cast for " + util);
* } */
}
void CminusfBuilder::visit(ASTProgram &node) {
......@@ -311,10 +312,12 @@ void CminusfBuilder::visit(ASTReturnStmt &node) {
if (not Type::is_eq_type(cur_fun->get_return_type(), cur_value->get_type())) {
if (not cur_value->get_type()->is_integer_type() and not cur_value->get_type()->is_float_type())
error_exit("unsupported return type");
if (cur_value->get_type()->is_integer_type())
if (cur_value->get_type()->is_float_type())
cur_value = builder->create_fptosi(cur_value, INT32_T);
else if (cur_fun->get_return_type()->is_float_type())
cur_value = builder->create_sitofp(cur_value, FLOAT_T);
else
cur_value = builder->create_fptosi(cur_value, INT32_T);
cur_value = builder->create_zext(cur_value, INT32_T);
}
builder->create_ret(cur_value);
......@@ -361,13 +364,15 @@ void CminusfBuilder::visit(ASTAssignExpression &node) {
auto left = cur_value;
node.expression->accept(*this);
assert(cur_value->get_type()->get_pointer_element_type() != nullptr);
// type cast
if (not Type::is_eq_type(cur_value->get_type()->get_pointer_element_type(), cur_value->get_type())) {
if (cur_value->get_type()->is_integer_type())
cur_value = builder->create_sitofp(cur_value, FLOAT_T);
else if (cur_value->get_type()->is_float_type())
assert(left->get_type()->get_pointer_element_type() != nullptr);
// type cast: left is a pointer type, pointed to i32 or float
if (not Type::is_eq_type(left->get_type()->get_pointer_element_type(), cur_value->get_type())) {
if (cur_value->get_type()->is_float_type())
cur_value = builder->create_fptosi(cur_value, INT32_T);
else if (left->get_type()->get_pointer_element_type()->is_float_type())
cur_value = builder->create_sitofp(cur_value, FLOAT_T);
else if (Type::is_eq_type(cur_value->get_type(), INT1_T))
cur_value = builder->create_zext(cur_value, INT32_T);
else
error_exit("bad type for assignment");
}
......@@ -537,7 +542,10 @@ void CminusfBuilder::visit(ASTCall &node) {
if (param_type->is_float_type())
cur_value = builder->create_sitofp(cur_value, FLOAT_T);
else if (param_type->is_integer_type())
cur_value = builder->create_fptosi(cur_value, INT32_T);
if (cur_value->get_type()->is_integer_type())
cur_value = builder->create_zext(cur_value, INT32_T);
else
cur_value = builder->create_fptosi(cur_value, INT32_T);
else
error_exit("unexpected type cast!");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment