// Assuming the type of e1 is untested and e2 has floating point // type, convert to the most precise floating point type. Expr_pair convert_to_common_float(Context& cxt, Expr& e1, Expr& e2) { Float_type& f2 = cast<Float_type>(e2.type()); // If e1 has float type, convert to the most precise type. if (has_floating_point_type(e1)) { Float_type& f1 = cast<Float_type>(e1.type()); if (f1.precision() < f2.precision()) { Expr& c = convert_to_wider_float(cxt, e1, f2); return {c, e2}; } if (f2.precision() < f1.precision()) { Expr& c = convert_to_wider_float(cxt, e2, f1); return {e1, c}; } lingo_unreachable(); } // If e1 has integer type, convert to e2. if (has_integer_type(e1)) { Expr& c = convert_integer_to_float(cxt, e1, f2); return {c, e2}; } error(cxt, "no floating point conversions for '{}' and '{}'", e1, e2); throw Type_error(); }
// Try a floating point conversion. Expr& convert_to_float(Expr& e, Float_type& t) { if (is<Float_type>(&e.type())) return convert_to_wider_float(e, t); if (is<Integer_type>(&e.type())) return convert_integer_to_float(e, t); return e; }
// Assuming the type of e1 is untested and e2 has floating point // type, convert to the most precise floating point type. Expr_pair convert_to_common_float(Expr& e1, Expr& e2) { Float_type& f2 = cast<Float_type>(e2.type()); // If e1 has float type, convert to the most precise. if (has_floating_point_type(e1)) { Float_type& f1 = cast<Float_type>(e1.type()); if (f1.precision() < f2.precision()) return {convert_to_wider_float(e1, f2), e2}; if (f2.precision() < f1.precision()) return {e1, convert_to_wider_float(e2, f1)}; } // If e1 has integer type, convert to e2. if (has_integer_type(e1)) { return {convert_integer_to_float(e1, f2), e2}; } throw std::runtime_error("incompatible types"); }