checker: permit int -> f32, int64 -> f64 and similar promotions again

pull/5179/head
Uwe Krüger 2020-06-02 17:00:14 +02:00 committed by GitHub
parent 640688d8cf
commit b0f66a4e05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 11 deletions

View File

@ -292,15 +292,14 @@ Please note that unlike C and Go, `int` is always a 32 bit integer.
There is an exceptions to the rule that all operators
in V must have values of the same type on both sides. A small primitive type
on one side can be automatically promoted if it fits
completely into the data range of the type on the other side, i.e. when
the promotion does not result in any data loss.
completely into the data range of the type on the other side.
These are the allowed possibilities:
```
i8 → i16 → int → i64
↘ ↘
f32 → f64
↗ ↗
↘ ↘
f32 → f64
↗ ↗
byte → u16 → u32 → u64 ⬎
↘ ↘ ↘ ptr
i8 → i16 → int → i64 ⬏

View File

@ -183,17 +183,13 @@ fn (c &Checker) promote_num(left_type, right_type table.Type) table.Type {
}
} else if type_hi.is_float() {
if idx_hi == table.f32_type_idx {
if idx_lo in [table.int_type_idx, table.i64_type_idx, table.u32_type_idx, table.u64_type_idx] {
return table.void_type
} else {
return type_hi
}
} else { // f64, any_flt
if idx_lo in [table.i64_type_idx, table.u64_type_idx] {
return table.void_type
} else {
return type_hi
}
} else { // f64, any_flt
return type_hi
}
} else if idx_lo >= table.byte_type_idx { // both operands are unsigned
return type_hi

View File

@ -67,3 +67,16 @@ fn test_struct_init_ref_return() {
assert fabs(fabs(x.get()) - 3.890949634755863) < 1.e-6
}
fn test_f32_int() {
x := f32(15.25)
y := -3
assert x + y == 12.25
assert y + x == 12.25
a := u32(34)
assert a + x == 49.25
b := i64(-17)
c := 16.75
assert c + b == -0.25
d := u64(300)
assert d + c == 316.75
}