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

all: new string interpolation in pure V (#10181)

This commit is contained in:
penguindark
2021-05-24 04:20:45 +02:00
committed by GitHub
parent 603e57745f
commit d8d05e0106
28 changed files with 2624 additions and 640 deletions

View File

@@ -81,7 +81,9 @@ fn get_string_special(neg bool, expZero bool, mantZero bool) string {
32 bit functions
*/
fn decimal_len_32(u u32) int {
// decimal_len_32 return the number of decimal digits of the input
[deprecated]
pub fn decimal_len_32(u u32) int {
// Function precondition: u is not a 10-digit number.
// (9 digits are sufficient for round-tripping.)
// This benchmarked faster than the log2 approach used for u64.
@@ -172,7 +174,9 @@ fn pow5_bits(e int) int {
64 bit functions
*/
fn decimal_len_64(u u64) int {
[deprecated]
// decimal_len_64 return the number of decimal digits of the input
pub fn decimal_len_64(u u64) int {
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
log2 := 64 - bits.leading_zeros_64(u) - 1
t := (log2 + 1) * 1233 >> 12
@@ -227,15 +231,44 @@ f64 to string with string format
*/
// TODO: Investigate precision issues
// f32_to_str_l return a string with the f32 converted in a string in decimal notation
pub fn f32_to_str_l(f f64) string {
return f64_to_str_l(f32(f))
[manualfree]
pub fn f32_to_str_l(f f32) string {
s := f32_to_str(f,6)
res := fxx_to_str_l_parse(s)
unsafe{s.free()}
return res
}
// f64_to_str_l return a string with the f64 converted in a string in decimal notation
[manualfree]
pub fn f32_to_str_l_no_dot(f f32) string {
s := f32_to_str(f,6)
res := fxx_to_str_l_parse_no_dot(s)
unsafe{s.free()}
return res
}
[manualfree]
pub fn f64_to_str_l(f f64) string {
s := f64_to_str(f,18)
res := fxx_to_str_l_parse(s)
unsafe{s.free()}
return res
}
[manualfree]
pub fn f64_to_str_l_no_dot(f f64) string {
s := f64_to_str(f,18)
res := fxx_to_str_l_parse_no_dot(s)
unsafe{s.free()}
return res
}
// f64_to_str_l return a string with the f64 converted in a string in decimal notation
[manualfree]
pub fn fxx_to_str_l_parse(s string) string {
// check for +inf -inf Nan
if s.len > 2 && (s[0] == `n` || s[1] == `i`) {
return s
@@ -287,8 +320,11 @@ pub fn f64_to_str_l(f f64) string {
exp_sgn = 1
i++
}
for c in s[i..] {
exp = exp * 10 + int(c-`0`)
mut c := i
for c < s.len {
exp = exp * 10 + int(s[c]-`0`)
c++
}
// allocate exp+32 chars for the return string
@@ -296,7 +332,7 @@ pub fn f64_to_str_l(f f64) string {
mut r_i := 0 // result string buffer index
//println("s:${sgn} b:${b[0]} es:${exp_sgn} exp:${exp}")
if sgn == 1 {
if m_sgn_flag {
res[r_i] = `+`
@@ -344,6 +380,136 @@ pub fn f64_to_str_l(f f64) string {
i++
}
}
/*
// remove the dot form the numbers like 2.
if r_i > 1 && res[r_i-1] == `.` {
r_i--
}
*/
res[r_i] = 0
return unsafe { tos(res.data,r_i) }
}
// f64_to_str_l return a string with the f64 converted in a string in decimal notation
[manualfree]
pub fn fxx_to_str_l_parse_no_dot(s string) string {
// check for +inf -inf Nan
if s.len > 2 && (s[0] == `n` || s[1] == `i`) {
return s
}
m_sgn_flag := false
mut sgn := 1
mut b := [26]byte{}
mut d_pos := 1
mut i := 0
mut i1 := 0
mut exp := 0
mut exp_sgn := 1
// get sign and decimal parts
for c in s {
if c == `-` {
sgn = -1
i++
} else if c == `+` {
sgn = 1
i++
}
else if c >= `0` && c <= `9` {
b[i1] = c
i1++
i++
} else if c == `.` {
if sgn > 0 {
d_pos = i
} else {
d_pos = i-1
}
i++
} else if c == `e` {
i++
break
} else {
return "Float conversion error!!"
}
}
b[i1] = 0
// get exponent
if s[i] == `-` {
exp_sgn = -1
i++
} else if s[i] == `+` {
exp_sgn = 1
i++
}
mut c := i
for c < s.len {
exp = exp * 10 + int(s[c]-`0`)
c++
}
// allocate exp+32 chars for the return string
mut res := []byte{len: exp+32, init: 0}
mut r_i := 0 // result string buffer index
//println("s:${sgn} b:${b[0]} es:${exp_sgn} exp:${exp}")
if sgn == 1 {
if m_sgn_flag {
res[r_i] = `+`
r_i++
}
} else {
res[r_i] = `-`
r_i++
}
i = 0
if exp_sgn >= 0 {
for b[i] != 0 {
res[r_i] = b[i]
r_i++
i++
if i >= d_pos && exp >= 0 {
if exp == 0 {
res[r_i] = `.`
r_i++
}
exp--
}
}
for exp >= 0 {
res[r_i] = `0`
r_i++
exp--
}
} else {
mut dot_p := true
for exp > 0 {
res[r_i] = `0`
r_i++
exp--
if dot_p {
res[r_i] = `.`
r_i++
dot_p = false
}
}
for b[i] != 0 {
res[r_i] = b[i]
r_i++
i++
}
}
// remove the dot form the numbers like 2.
if r_i > 1 && res[r_i-1] == `.` {
r_i--
}
res[r_i] = 0
return unsafe { tos(res.data,r_i) }
}