1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: restrict numeric promotions to cases where no data is lost

This commit is contained in:
Uwe Krüger
2020-05-27 05:42:48 +02:00
committed by GitHub
parent fc67046bac
commit 013fdb8a4b
81 changed files with 510 additions and 247 deletions

View File

@@ -360,9 +360,9 @@ pub fn (b []byte) hex() string {
mut dst_i := 0
for i in b {
n0 := i >> 4
hex[dst_i++] = if n0 < 10 { n0 + `0` } else { n0 + 87 }
hex[dst_i++] = if n0 < 10 { n0 + `0` } else { n0 + byte(87) }
n1 := i & 0xF
hex[dst_i++] = if n1 < 10 { n1 + `0` } else { n1 + 87 }
hex[dst_i++] = if n1 < 10 { n1 + `0` } else { n1 + byte(87) }
}
hex[dst_i] = `\0`
return tos(hex,dst_i)

View File

@@ -468,6 +468,10 @@ fn test_in() {
assert !(0 in a)
assert 0 !in a
assert 4 !in a
b := [1, 4, 0]
c := [3, 6, 2, 0]
assert 0 in b
assert 0 in c
}
fn sum(prev int, curr int) int {
@@ -557,7 +561,7 @@ fn test_map() {
assert strs.map(it.to_upper()) == ['V', 'IS', 'AWESOME']
assert strs.map(it == 'awesome') == [false, false, true]
assert strs.map(it.len in nums) == [true, true, false]
assert strs.map(7) == [7, 7, 7]
assert strs.map(int(7)) == [7, 7, 7]
// external func
assert nums.map(map_test_helper_1(it)) == [1, 4, 9, 16, 25, 36]
@@ -568,9 +572,9 @@ fn test_map() {
assert []int{len:0}.map(it * 2) == []
// nested maps (where it is of same type)
assert nums.map( strs.map(7) == [7, 7, 7] ) == [true, true, true, true, true, true]
assert nums.map( strs.map(int(7)) == [7, 7, 7] ) == [true, true, true, true, true, true]
assert nums.map( '$it' + strs.map('a')[0] ) == ['1a', '2a', '3a', '4a', '5a', '6a']
assert nums.map( it + strs.map(7)[0] ) == [8, 9, 10, 11, 12, 13]
assert nums.map( it + strs.map(int(7))[0] ) == [8, 9, 10, 11, 12, 13]
assert nums.map( it + strs.map(it.len)[0] ) == [2, 3, 4, 5, 6, 7]
assert strs.map( it.len + strs.map(it.len)[0] ) == [2, 3, 8]

View File

@@ -13,6 +13,17 @@ pub fn (d f64) str() string {
return ftoa.ftoa_64(d)
}
[inline]
pub fn (d any_float) str() string {
x := f64(d)
abs_x := f64_abs(x)
if abs_x >= 0.01 && abs_x < 1.0e16 {
return ftoa.f64_to_str_l(x)
} else {
return ftoa.ftoa_64(x)
}
}
// return a string of the input f64 in scientific notation with digit_num deciamals displayed, max 17 digits
[inline]
pub fn (x f64) strsci(digit_num int) string {
@@ -84,7 +95,7 @@ pub fn (a f64) eq(b f64) bool {
[inline]
pub fn (a f32) eq(b f32) bool {
return f32_abs(a - b) <= C.FLT_EPSILON
return f32_abs(a - b) <= f32(C.FLT_EPSILON)
}
pub fn (a f64) eqbit(b f64) bool {

View File

@@ -144,6 +144,11 @@ pub fn (nn u32) str() string {
//return tos(buf + index, (max-index))
}
[inline]
pub fn (n any_int) str() string {
return i64(n).str()
}
pub fn (nn i64) str() string {
mut n := nn
mut d := i64(0)
@@ -188,7 +193,7 @@ pub fn (nn i64) str() string {
pub fn (nn u64) str() string {
mut n := nn
mut d := 0
mut d := u64(0)
if n == 0 {
return '0'
}
@@ -274,7 +279,7 @@ pub fn (nn u16) hex() string {
mut index := max
buf[index--] = `\0`
for n > 0 {
d := n & 0xF
d := byte(n & 0xF)
n = n >> 4
buf[index--] = if d < 10 { d + `0` } else { d + 87 }
}
@@ -301,7 +306,7 @@ pub fn (nn u32) hex() string {
mut index := max
buf[index--] = `\0`
for n > 0 {
d := n & 0xF
d := byte(n & 0xF)
n = n >> 4
buf[index--] = if d < 10 { d + `0` } else { d + 87 }
}
@@ -328,7 +333,7 @@ pub fn (nn u64) hex() string {
mut index := max
buf[index--] = `\0`
for n > 0 {
d := n & 0xF
d := byte(n & 0xF)
n = n >> 4
buf[index--] = if d < 10 { d + `0` } else { d + 87 }
}
@@ -345,6 +350,10 @@ pub fn (nn i64) hex() string {
return u64(nn).hex()
}
pub fn (nn any_int) hex() string {
return u64(nn).hex()
}
pub fn (nn voidptr) str() string {
return u64(nn).hex()
}

View File

@@ -214,7 +214,7 @@ fn test_int_to_hex() {
assert u32(c0).hex() == 'c'
assert 2147483647.hex() == '7fffffff'
assert u32(2147483647).hex() == '7fffffff'
assert (-1).hex() == 'ffffffff'
assert (-1).hex() == 'ffffffffffffffff'
assert u32(4294967295).hex() == 'ffffffff'
// 64 bit
assert u64(0).hex() == '0'

View File

@@ -123,22 +123,22 @@ fn (mut d DenseArray) push(key string, value voidptr) u32 {
if d.cap == d.size {
d.cap += d.cap >> 3
d.keys = &string(C.realloc(d.keys, sizeof(string) * d.cap))
d.values = C.realloc(d.values, d.value_bytes * d.cap)
d.values = C.realloc(d.values, u32(d.value_bytes) * d.cap)
}
push_index := d.size
d.keys[push_index] = key
C.memcpy(d.values + push_index * d.value_bytes, value, d.value_bytes)
C.memcpy(d.values + push_index * u32(d.value_bytes), value, d.value_bytes)
d.size++
return push_index
}
fn (d DenseArray) get(i int) voidptr {
$if !no_bounds_checking? {
if i < 0 || i >= d.size {
if i < 0 || i >= int(d.size) {
panic('DenseArray.get: index out of range (i == $i, d.len == $d.size)')
}
}
return byteptr(d.keys) + i * sizeof(string)
return byteptr(d.keys) + i * int(sizeof(string))
}
// Move all zeros to the end of the array
@@ -153,8 +153,8 @@ fn (mut d DenseArray) zeros_to_end() {
d.keys[count] = d.keys[i]
d.keys[i] = tmp_key
// swap values (TODO: optimize)
C.memcpy(tmp_value, d.values + count * d.value_bytes, d.value_bytes)
C.memcpy(d.values + count * d.value_bytes, d.values + i * d.value_bytes, d.value_bytes)
C.memcpy(tmp_value, d.values + count * u32(d.value_bytes), d.value_bytes)
C.memcpy(d.values + count * u32(d.value_bytes), d.values + i * d.value_bytes, d.value_bytes)
C.memcpy(d.values + i * d.value_bytes, tmp_value, d.value_bytes)
count++
}
@@ -164,7 +164,7 @@ fn (mut d DenseArray) zeros_to_end() {
d.size = count
d.cap = if count < 8 { u32(8) } else { count }
d.keys = &string(C.realloc(d.keys, sizeof(string) * d.cap))
d.values = C.realloc(d.values, d.value_bytes * d.cap)
d.values = C.realloc(d.values, u32(d.value_bytes) * d.cap)
}
pub struct map {
@@ -280,7 +280,7 @@ fn (mut m map) set(k string, value voidptr) {
for meta == m.metas[index] {
kv_index := m.metas[index + 1]
if fast_string_eq(key, m.key_values.keys[kv_index]) {
C.memcpy(m.key_values.values + kv_index * m.value_bytes , value, m.value_bytes)
C.memcpy(m.key_values.values + kv_index * u32(m.value_bytes), value, m.value_bytes)
return
}
index += 2
@@ -349,7 +349,7 @@ fn (m map) get3(key string, zero voidptr) voidptr {
if meta == m.metas[index] {
kv_index := m.metas[index + 1]
if fast_string_eq(key, m.key_values.keys[kv_index]) {
return voidptr(m.key_values.values + kv_index * m.value_bytes)
return voidptr(m.key_values.values + kv_index * u32(m.value_bytes))
}
}
index += 2
@@ -431,10 +431,10 @@ pub fn (d DenseArray) clone() DenseArray {
size: d.size
deletes: d.deletes
keys: &string(malloc(d.cap * sizeof(string)))
values: byteptr(malloc(d.cap * d.value_bytes))
values: byteptr(malloc(d.cap * u32(d.value_bytes)))
}
C.memcpy(res.keys, d.keys, d.cap * sizeof(string))
C.memcpy(res.values, d.values, d.cap * d.value_bytes)
C.memcpy(res.values, d.values, d.cap * u32(d.value_bytes))
return res
}

View File

@@ -750,7 +750,7 @@ pub fn (s string) ends_with(p string) bool {
pub fn (s string) to_lower() string {
mut b := malloc(s.len + 1)
for i in 0..s.len {
b[i] = C.tolower(s.str[i])
b[i] = byte(C.tolower(s.str[i]))
}
return tos(b, s.len)
}
@@ -767,7 +767,7 @@ pub fn (s string) is_lower() bool {
pub fn (s string) to_upper() string {
mut b := malloc(s.len + 1)
for i in 0..s.len {
b[i] = C.toupper(s.str[i])
b[i] = byte(C.toupper(s.str[i]))
}
return tos(b, s.len)
}

View File

@@ -13,33 +13,33 @@ pub fn utf32_to_str(code u32) string {
icode := int(code) // Prevents doing casts everywhere
mut buffer := malloc(5)
if icode <= 127/* 0x7F */ {
buffer[0] = icode
buffer[0] = byte(icode)
return tos(buffer, 1)
}
if icode <= 2047/* 0x7FF */ {
buffer[0] = 192/*0xC0*/ | (icode>>6)/* 110xxxxx */
buffer[0] = 192/*0xC0*/ | byte(icode>>6)/* 110xxxxx */
buffer[1] = 128/*0x80*/ | (icode & 63/*0x3F*/)/* 10xxxxxx */
buffer[1] = 128/*0x80*/ | byte(icode & 63/*0x3F*/)/* 10xxxxxx */
return tos(buffer, 2)
}
if icode <= 65535/* 0xFFFF */ {
buffer[0] = 224/*0xE0*/ | (icode>>12)/* 1110xxxx */
buffer[0] = 224/*0xE0*/ | byte(icode>>12)/* 1110xxxx */
buffer[1] = 128/*0x80*/ | ((icode>>6) & 63/*0x3F*/)/* 10xxxxxx */
buffer[1] = 128/*0x80*/ | (byte(icode>>6) & 63/*0x3F*/)/* 10xxxxxx */
buffer[2] = 128/*0x80*/ | (icode & 63/*0x3F*/)/* 10xxxxxx */
buffer[2] = 128/*0x80*/ | byte(icode & 63/*0x3F*/)/* 10xxxxxx */
return tos(buffer, 3)
}
if icode <= 1114111/* 0x10FFFF */ {
buffer[0] = 240/*0xF0*/ | (icode>>18)/* 11110xxx */
buffer[0] = 240/*0xF0*/ | byte(icode>>18)/* 11110xxx */
buffer[1] = 128/*0x80*/ | ((icode>>12) & 63/*0x3F*/)/* 10xxxxxx */
buffer[1] = 128/*0x80*/ | (byte(icode>>12) & 63/*0x3F*/)/* 10xxxxxx */
buffer[2] = 128/*0x80*/ | ((icode>>6) & 63/*0x3F*/)/* 10xxxxxx */
buffer[2] = 128/*0x80*/ | (byte(icode>>6) & 63/*0x3F*/)/* 10xxxxxx */
buffer[3] = 128/*0x80*/ | (icode & 63/*0x3F*/)/* 10xxxxxx */
buffer[3] = 128/*0x80*/ | byte(icode & 63/*0x3F*/)/* 10xxxxxx */
return tos(buffer, 4)
}
@@ -51,33 +51,33 @@ pub fn utf32_to_str_no_malloc(code u32, buf voidptr) string {
icode := int(code) // Prevents doing casts everywhere
mut buffer := byteptr(buf)
if icode <= 127/* 0x7F */ {
buffer[0] = icode
buffer[0] = byte(icode)
return tos(buffer, 1)
}
if icode <= 2047/* 0x7FF */ {
buffer[0] = 192/*0xC0*/ | (icode>>6)/* 110xxxxx */
buffer[0] = 192/*0xC0*/ | byte(icode>>6)/* 110xxxxx */
buffer[1] = 128/*0x80*/ | (icode & 63/*0x3F*/)/* 10xxxxxx */
buffer[1] = 128/*0x80*/ | byte(icode & 63/*0x3F*/)/* 10xxxxxx */
return tos(buffer, 2)
}
if icode <= 65535/* 0xFFFF */ {
buffer[0] = 224/*0xE0*/ | (icode>>12)/* 1110xxxx */
buffer[0] = 224/*0xE0*/ | byte(icode>>12)/* 1110xxxx */
buffer[1] = 128/*0x80*/ | ((icode>>6) & 63/*0x3F*/)/* 10xxxxxx */
buffer[1] = 128/*0x80*/ | (byte(icode>>6) & 63/*0x3F*/)/* 10xxxxxx */
buffer[2] = 128/*0x80*/ | (icode & 63/*0x3F*/)/* 10xxxxxx */
buffer[2] = 128/*0x80*/ | byte(icode & 63/*0x3F*/)/* 10xxxxxx */
return tos(buffer, 3)
}
if icode <= 1114111/* 0x10FFFF */ {
buffer[0] = 240/*0xF0*/ | (icode>>18)/* 11110xxx */
buffer[0] = 240/*0xF0*/ | byte(icode>>18)/* 11110xxx */
buffer[1] = 128/*0x80*/ | ((icode>>12) & 63/*0x3F*/)/* 10xxxxxx */
buffer[1] = 128/*0x80*/ | (byte(icode>>12) & 63/*0x3F*/)/* 10xxxxxx */
buffer[2] = 128/*0x80*/ | ((icode>>6) & 63/*0x3F*/)/* 10xxxxxx */
buffer[2] = 128/*0x80*/ | (byte(icode>>6) & 63/*0x3F*/)/* 10xxxxxx */
buffer[3] = 128/*0x80*/ | (icode & 63/*0x3F*/)/* 10xxxxxx */
buffer[3] = 128/*0x80*/ | byte(icode & 63/*0x3F*/)/* 10xxxxxx */
return tos(buffer, 4)
}