Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 142 additions & 10 deletions vlib/builtin/wasm/wasi/int_notd_no_imports.v
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@ module builtin

pub type byte = u8

// type i32 = int
// str returns the string equivalent of x.
pub fn (x isize) str() string {
return i64(x).str()
}

// str returns the string equivalent of x.
pub fn (x usize) str() string {
return u64(x).str()
}

// digit pairs in reverse order
const digit_pairs = '00102030405060708090011121314151617181910212223242526272829203132333435363738393041424344454647484940515253545556575859506162636465666768696071727374757677787970818283848586878889809192939495969798999'
Expand All @@ -22,8 +30,8 @@ pub const max_i32 = i32(2147483647)
pub const min_i64 = i64(-9223372036854775807 - 1)
pub const max_i64 = i64(9223372036854775807)

pub const min_int = int(min_i32)
pub const max_int = int(max_i32)
pub const min_int = $if new_int ? && x64 { int(min_i64) } $else { int(min_i32) }
pub const max_int = $if new_int ? && x64 { int(max_i64) } $else { int(max_i32) }

pub const min_u8 = u8(0)
pub const max_u8 = u8(255)
Expand Down Expand Up @@ -111,6 +119,10 @@ pub fn (n u16) str() string {
return int(n).str_l(7)
}

pub fn (n i32) str() string {
return int(n).str_l(12)
}

// str returns the value of the `int` as a `string`.
// Example: assert int(-2020).str() == '-2020'
pub fn (n int) str() string {
Expand Down Expand Up @@ -150,28 +162,30 @@ pub fn (nn u32) str() string {
diff := max - index
vmemmove(buf, voidptr(buf + index), diff + 1)
return tos(buf, diff)

// return tos(memdup(&buf[0] + index, (max - index)), (max - index))
}
}

// str returns the value of the `int_literal` as a `string`.
@[inline]
pub fn (n int_literal) str() string {
return i64(n).str()
return impl_i64_to_string(n)
}

// str returns the value of the `i64` as a `string`.
// Example: assert i64(-200000).str() == '-200000'
@[direct_array_access; inline]
@[inline]
pub fn (nn i64) str() string {
return impl_i64_to_string(nn)
}

@[direct_array_access]
fn impl_i64_to_string(nn i64) string {
unsafe {
mut n := nn
mut d := i64(0)
if n == 0 {
return '0'
} else if n == min_i64 {
// math.min_i64
return '-9223372036854775808'
}
max := 20
Expand Down Expand Up @@ -207,7 +221,6 @@ pub fn (nn i64) str() string {
diff := max - index
vmemmove(buf, voidptr(buf + index), diff + 1)
return tos(buf, diff)
// return tos(memdup(&buf[0] + index, (max - index)), (max - index))
}
}

Expand Down Expand Up @@ -244,7 +257,6 @@ pub fn (nn u64) str() string {
diff := max - index
vmemmove(buf, voidptr(buf + index), diff + 1)
return tos(buf, diff)
// return tos(memdup(&buf[0] + index, (max - index)), (max - index))
}
}

Expand All @@ -256,3 +268,123 @@ pub fn (b bool) str() string {
}
return 'false'
}

pub fn (p voidptr) str() string {
return u64(p).str()
}

pub fn (x f32) str() string {
return f64(x).str()
}

pub fn (x f64) str() string {
// Format f64 as string similar to the native C version
// Maximum 6 significant decimal places
unsafe {
if x != x {
return 'nan'
}
if x > 1.7976931348623157e+308 {
return 'inf'
}
if x < -1.7976931348623157e+308 {
return '-inf'
}

mut is_neg := false
mut val := x
if val < 0 {
is_neg = true
val = -val
}

// Round to 6 decimal places to handle floating point precision
val = (val * 1000000.0 + 0.5) / 1000000.0

mut int_part := i64(val)
mut frac_part := val - f64(int_part)

// If no fractional part or very close to zero, return just the integer
if frac_part < 1e-10 {
result := int_part.str()
if is_neg {
// Prepend negative sign manually
mut buf := malloc(result.len + 2)
buf[0] = `-`
vmemcpy(buf + 1, result.str, result.len)
buf[result.len + 1] = 0
return tos(buf, result.len + 1)
}
return result
}

// Build fractional part - up to 6 decimal places
mut frac_digits := u64(0)
mut frac_count := 0
mut temp_frac := frac_part

for frac_count < 6 {
temp_frac *= 10.0
digit := u64(temp_frac)
frac_digits = frac_digits * 10 + digit
temp_frac -= f64(digit)
frac_count++
if temp_frac < 1e-10 {
break
}
}

// Remove trailing zeros
for frac_count > 0 && frac_digits % 10 == 0 {
frac_digits /= 10
frac_count--
}

if frac_count == 0 {
result := int_part.str()
if is_neg {
// Prepend negative sign manually
mut buf := malloc(result.len + 2)
buf[0] = `-`
vmemcpy(buf + 1, result.str, result.len)
buf[result.len + 1] = 0
return tos(buf, result.len + 1)
}
return result
}

// Allocate string buffer: worst case is "-123456789012345.123456"
max_len := 30
buf := malloc(max_len + 1)
mut pos := 0

// Copy negative sign if needed
if is_neg {
buf[pos] = `-`
pos++
}

// Copy integer part using tos to get the string bytes
int_str := int_part.str()
vmemcpy(buf + pos, int_str.str, int_str.len)
pos += int_str.len

// Add decimal point
buf[pos] = `.`
pos++

// Format fractional digits
frac_str := frac_digits.str()
// Pad with leading zeros if needed
for _ in 0 .. (frac_count - frac_str.len) {
buf[pos] = `0`
pos++
}
// Copy fractional string bytes
vmemcpy(buf + pos, frac_str.str, frac_str.len)
pos += frac_str.len

buf[pos] = 0
return tos(buf, pos)
}
}
Loading
Loading