diff --git a/Reports/3-ir-gen/report.md b/Reports/3-ir-gen/report.md index e68bd7df033e5164485185d1f1e555a296b19c60..e84fed427cbd1f89777b472f3bd193fff83d34e2 100644 --- a/Reports/3-ir-gen/report.md +++ b/Reports/3-ir-gen/report.md @@ -63,6 +63,12 @@ PB20111654 李晓奇 - 在传递给函数时,只能传递数组,但是传递为指针。 +6. 记录遇到的坑 + + - 形如这种产生式子`term→term mulop factor ∣ factor`,我为了图方便先求了`factor`,在根据`term`的有调用`accept()`,但是这样会导致左右操作数颠倒。 + - 我对于类型转换的控制比较严格,没考虑到的一率abort,因此很快发现了漏掉了bool类型的转换。 + - 接上条,一些类型转换的bug:`i32`到`i1`也是需要转换的,开始做的时候还没意识到这些(主要是没意识到`i1`的存在)。 + ## 实验设计 请写明为了顺利完成本次实验,加入了哪些亮点设计,并对这些设计进行解释。 diff --git a/src/cminusfc/cminusf_builder.cpp b/src/cminusfc/cminusf_builder.cpp index f7e1a6ea712381b78b29c0249a7ad2057f256ae1..15e5e7fe9bc728f1745923b04a31965a102fa579 100644 --- a/src/cminusfc/cminusf_builder.cpp +++ b/src/cminusfc/cminusf_builder.cpp @@ -48,13 +48,20 @@ 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 - if (Type::is_eq_type(lvalue->get_type(), INT32_T) and Type::is_eq_type(rvalue->get_type(), FLOAT_T)) + if (lvalue->get_type()->is_integer_type() and rvalue->get_type()->is_float_type()) 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)) + 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 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) { @@ -302,7 +309,7 @@ void CminusfBuilder::visit(ASTReturnStmt &node) { // type cast // return type can only be int, float or void if (not Type::is_eq_type(cur_fun->get_return_type(), cur_value->get_type())) { - if (not cur_value->get_type()->is_integer_type() or not cur_value->get_type()->is_float_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()) cur_value = builder->create_sitofp(cur_value, FLOAT_T); @@ -524,15 +531,18 @@ void CminusfBuilder::visit(ASTCall &node) { cur_value = builder->create_gep(cur_value, {0, 0}); } else if (param_type->is_integer_type() or param_type->is_float_type()) { // need type cast between int and float - if (Type::is_eq_type(cur_value->get_type(), INT32_T)) + if (not cur_value->get_type()->is_integer_type() and not cur_value->get_type()->is_float_type()) + error_exit("unexpected type cast!"); + + if (param_type->is_float_type()) cur_value = builder->create_sitofp(cur_value, FLOAT_T); - else if (Type::is_eq_type(cur_value->get_type(), FLOAT_T)) + else if (param_type->is_integer_type()) cur_value = builder->create_fptosi(cur_value, INT32_T); else error_exit("unexpected type cast!"); } else - error_exit("unexpected case when casting arguments for function call" + node.id); + error_exit("unexpected case when casting arguments for function call " + node.id); } // now cur_value fits the param type