From e3d98b1b281c63026bf0a4adc0c96c68113678b1 Mon Sep 17 00:00:00 2001 From: playX Date: Sun, 14 Nov 2021 22:06:58 +0300 Subject: [PATCH] js,strconv: port some functions to JS backend, improve `rune.str()` (#12460) --- vlib/builtin/js/rune.js.v | 4 +- vlib/strconv/format_mem.js.v | 103 ++++++++++++++++++++++++++++++++++ vlib/strconv/utilities.c.v | 79 -------------------------- vlib/strconv/utilities.v | 79 ++++++++++++++++++++++++++ vlib/v/gen/js/builtin_types.v | 2 +- 5 files changed, 185 insertions(+), 82 deletions(-) create mode 100644 vlib/strconv/format_mem.js.v diff --git a/vlib/builtin/js/rune.js.v b/vlib/builtin/js/rune.js.v index 4fa51e12c2..22dc3d2fdc 100644 --- a/vlib/builtin/js/rune.js.v +++ b/vlib/builtin/js/rune.js.v @@ -18,14 +18,14 @@ pub fn (c rune) repeat(count int) string { return c.str() } res := '' - #res.str = String.fromCharCode(c.val) + #res.str = String.fromCharCode(Number(c.val)) return res.repeat(count) } pub fn (c rune) str() string { res := '' - #res.str = String.fromCharCode(c.val) + #res.str = String.fromCharCode(Number(c.val)) return res } diff --git a/vlib/strconv/format_mem.js.v b/vlib/strconv/format_mem.js.v new file mode 100644 index 0000000000..658fe66174 --- /dev/null +++ b/vlib/strconv/format_mem.js.v @@ -0,0 +1,103 @@ +module strconv + +import strings + +pub fn format_str_sb(s string, p BF_param, mut sb strings.Builder) { + if p.len0 <= 0 { + sb.write_string(s) + return + } + + dif := p.len0 - utf8_str_visible_length(s) + + if dif <= 0 { + sb.write_string(s) + return + } + + if p.allign == .right { + for i1 := 0; i1 < dif; i1++ { + sb.write_b(p.pad_ch) + } + } + + sb.write_string(s) + + if p.allign == .left { + for i1 := 0; i1 < dif; i1++ { + sb.write_b(p.pad_ch) + } + } +} + +const ( + max_size_f64_char = 32 // the f64 max representation is -36,028,797,018,963,968e1023, 21 chars, 32 is faster for the memory manger + // digit pairs in reverse order + digit_pairs = '00102030405060708090011121314151617181910212223242526272829203132333435363738393041424344454647484940515253545556575859506162636465666768696071727374757677787970818283848586878889809192939495969798999' +) + +// format_dec_sb format a u64 +[direct_array_access] +pub fn format_dec_sb(d u64, p BF_param, mut res strings.Builder) { + mut n_char := dec_digits(d) + sign_len := if !p.positive || p.sign_flag { 1 } else { 0 } + number_len := sign_len + n_char + dif := p.len0 - number_len + mut sign_written := false + + if p.allign == .right { + if p.pad_ch == `0` { + if p.positive { + if p.sign_flag { + res.write_b(`+`) + sign_written = true + } + } else { + res.write_b(`-`) + sign_written = true + } + } + // write the pad chars + for i1 := 0; i1 < dif; i1++ { + res.write_b(p.pad_ch) + } + } + + if !sign_written { + // no pad char, write the sign before the number + if p.positive { + if p.sign_flag { + res.write_b(`+`) + } + } else { + res.write_b(`-`) + } + } + + // Legacy version + // max u64 18446744073709551615 => 20 byte + mut buf := [32]byte{} + mut i := 20 + mut d1 := d + for i >= (21 - n_char) { + buf[i] = byte(d1 % 10) + `0` + + d1 = d1 / 10 + i-- + } + + for j in 0 .. n_char { + i++ + res.write_b(buf[i]) + } + i++ + + //=========================================== + + if p.allign == .left { + for i1 := 0; i1 < dif; i1++ { + res.write_b(p.pad_ch) + } + } + return +} diff --git a/vlib/strconv/utilities.c.v b/vlib/strconv/utilities.c.v index 1eb520fa93..e99e16167f 100644 --- a/vlib/strconv/utilities.c.v +++ b/vlib/strconv/utilities.c.v @@ -303,82 +303,3 @@ pub fn fxx_to_str_l_parse_no_dot(s string) string { res[r_i] = 0 return unsafe { tos(res.data, r_i) } } - -// dec_digits return the number of decimal digit of an u64 -pub fn dec_digits(n u64) int { - if n <= 9_999_999_999 { // 1-10 - if n <= 99_999 { // 5 - if n <= 99 { // 2 - if n <= 9 { // 1 - return 1 - } else { - return 2 - } - } else { - if n <= 999 { // 3 - return 3 - } else { - if n <= 9999 { // 4 - return 4 - } else { - return 5 - } - } - } - } else { - if n <= 9_999_999 { // 7 - if n <= 999_999 { // 6 - return 6 - } else { - return 7 - } - } else { - if n <= 99_999_999 { // 8 - return 8 - } else { - if n <= 999_999_999 { // 9 - return 9 - } - return 10 - } - } - } - } else { - if n <= 999_999_999_999_999 { // 5 - if n <= 999_999_999_999 { // 2 - if n <= 99_999_999_999 { // 1 - return 11 - } else { - return 12 - } - } else { - if n <= 9_999_999_999_999 { // 3 - return 13 - } else { - if n <= 99_999_999_999_999 { // 4 - return 14 - } else { - return 15 - } - } - } - } else { - if n <= 99_999_999_999_999_999 { // 7 - if n <= 9_999_999_999_999_999 { // 6 - return 16 - } else { - return 17 - } - } else { - if n <= 999_999_999_999_999_999 { // 8 - return 18 - } else { - if n <= 9_999_999_999_999_999_999 { // 9 - return 19 - } - return 20 - } - } - } - } -} diff --git a/vlib/strconv/utilities.v b/vlib/strconv/utilities.v index f60a1a1c62..e6e9b0056d 100644 --- a/vlib/strconv/utilities.v +++ b/vlib/strconv/utilities.v @@ -174,3 +174,82 @@ fn multiple_of_power_of_five_64(v u64, p u32) bool { fn multiple_of_power_of_two_64(v u64, p u32) bool { return u32(bits.trailing_zeros_64(v)) >= p } + +// dec_digits return the number of decimal digit of an u64 +pub fn dec_digits(n u64) int { + if n <= 9_999_999_999 { // 1-10 + if n <= 99_999 { // 5 + if n <= 99 { // 2 + if n <= 9 { // 1 + return 1 + } else { + return 2 + } + } else { + if n <= 999 { // 3 + return 3 + } else { + if n <= 9999 { // 4 + return 4 + } else { + return 5 + } + } + } + } else { + if n <= 9_999_999 { // 7 + if n <= 999_999 { // 6 + return 6 + } else { + return 7 + } + } else { + if n <= 99_999_999 { // 8 + return 8 + } else { + if n <= 999_999_999 { // 9 + return 9 + } + return 10 + } + } + } + } else { + if n <= 999_999_999_999_999 { // 5 + if n <= 999_999_999_999 { // 2 + if n <= 99_999_999_999 { // 1 + return 11 + } else { + return 12 + } + } else { + if n <= 9_999_999_999_999 { // 3 + return 13 + } else { + if n <= 99_999_999_999_999 { // 4 + return 14 + } else { + return 15 + } + } + } + } else { + if n <= 99_999_999_999_999_999 { // 7 + if n <= 9_999_999_999_999_999 { // 6 + return 16 + } else { + return 17 + } + } else { + if n <= 999_999_999_999_999_999 { // 8 + return 18 + } else { + if n <= 9_999_999_999_999_999_999 { // 9 + return 19 + } + return 20 + } + } + } + } +} diff --git a/vlib/v/gen/js/builtin_types.v b/vlib/v/gen/js/builtin_types.v index e9f4ee2354..d378e36377 100644 --- a/vlib/v/gen/js/builtin_types.v +++ b/vlib/v/gen/js/builtin_types.v @@ -366,7 +366,7 @@ fn (mut g JsGen) gen_builtin_type_defs() { g.gen_builtin_prototype( typ_name: typ_name default_value: 'new Number(0)' - constructor: 'if (typeof(val) == "string") { this.val = val.charCodeAt() } else if (val instanceof string) { this.val = val.str.charCodeAt(); } else { this.val = Math.round(val) }' + constructor: 'if (typeof(val) == "string") { this.val = val.charCodeAt() } else if (val instanceof string) { this.val = val.str.charCodeAt(); } else { this.val = Math.round(Number(val)) }' value_of: 'this.val | 0' to_string: 'new string(this.val + "")' eq: 'new bool(self.valueOf() === other.valueOf())'