js: initial work on porting rand module to JS backend (#11188)
							parent
							
								
									6ee77724e8
								
							
						
					
					
						commit
						659f823c5c
					
				| 
						 | 
					@ -21,3 +21,13 @@ pub fn wyhash_c(key &byte, len u64, seed u64) u64 {
 | 
				
			||||||
pub fn wyhash64_c(a u64, b u64) u64 {
 | 
					pub fn wyhash64_c(a u64, b u64) u64 {
 | 
				
			||||||
	return C.wyhash64(a, b)
 | 
						return C.wyhash64(a, b)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[inline]
 | 
				
			||||||
 | 
					pub fn sum64_string(key string, seed u64) u64 {
 | 
				
			||||||
 | 
						return wyhash_c(key.str, u64(key.len), seed)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[inline]
 | 
				
			||||||
 | 
					pub fn sum64(key []byte, seed u64) u64 {
 | 
				
			||||||
 | 
						return wyhash_c(&byte(key.data), u64(key.len), seed)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					module hash
 | 
				
			||||||
| 
						 | 
					@ -23,16 +23,6 @@ const (
 | 
				
			||||||
	wyp4 = u64(0x1d8e4e27c47d124f)
 | 
						wyp4 = u64(0x1d8e4e27c47d124f)
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[inline]
 | 
					 | 
				
			||||||
pub fn sum64_string(key string, seed u64) u64 {
 | 
					 | 
				
			||||||
	return wyhash_c(key.str, u64(key.len), seed)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[inline]
 | 
					 | 
				
			||||||
pub fn sum64(key []byte, seed u64) u64 {
 | 
					 | 
				
			||||||
	return wyhash_c(&byte(key.data), u64(key.len), seed)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[inline]
 | 
					[inline]
 | 
				
			||||||
fn wyrotr(v u64, k u32) u64 {
 | 
					fn wyrotr(v u64, k u32) u64 {
 | 
				
			||||||
	return (v >> k) | (v << (64 - k))
 | 
						return (v >> k) | (v << (64 - k))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,127 @@
 | 
				
			||||||
 | 
					module rand
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					// uuid_v4 generates a random (v4) UUID
 | 
				
			||||||
 | 
					// See https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn uuid_v4() string {
 | 
				
			||||||
 | 
						buflen := 36
 | 
				
			||||||
 | 
						mut buf := unsafe { malloc_noscan(37) }
 | 
				
			||||||
 | 
						mut i_buf := 0
 | 
				
			||||||
 | 
						mut x := u64(0)
 | 
				
			||||||
 | 
						mut d := byte(0)
 | 
				
			||||||
 | 
						for i_buf < buflen {
 | 
				
			||||||
 | 
							mut c := 0
 | 
				
			||||||
 | 
							x = default_rng.u64()
 | 
				
			||||||
 | 
							// do most of the bit manipulation at once:
 | 
				
			||||||
 | 
							x &= 0x0F0F0F0F0F0F0F0F
 | 
				
			||||||
 | 
							x += 0x3030303030303030
 | 
				
			||||||
 | 
							// write the ASCII codes to the buffer:
 | 
				
			||||||
 | 
							for c < 8 && i_buf < buflen {
 | 
				
			||||||
 | 
								d = byte(x)
 | 
				
			||||||
 | 
								unsafe {
 | 
				
			||||||
 | 
									buf[i_buf] = if d > 0x39 { d + 0x27 } else { d }
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								i_buf++
 | 
				
			||||||
 | 
								c++
 | 
				
			||||||
 | 
								x = x >> 8
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// there are still some random bits in x:
 | 
				
			||||||
 | 
						x = x >> 8
 | 
				
			||||||
 | 
						d = byte(x)
 | 
				
			||||||
 | 
						unsafe {
 | 
				
			||||||
 | 
							buf[19] = if d > 0x39 { d + 0x27 } else { d }
 | 
				
			||||||
 | 
							buf[8] = `-`
 | 
				
			||||||
 | 
							buf[13] = `-`
 | 
				
			||||||
 | 
							buf[18] = `-`
 | 
				
			||||||
 | 
							buf[23] = `-`
 | 
				
			||||||
 | 
							buf[14] = `4`
 | 
				
			||||||
 | 
							buf[buflen] = 0
 | 
				
			||||||
 | 
							return buf.vstring_with_len(buflen)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						ulid_encoding = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ulid generates an Unique Lexicographically sortable IDentifier.
 | 
				
			||||||
 | 
					// See https://github.com/ulid/spec .
 | 
				
			||||||
 | 
					// NB: ULIDs can leak timing information, if you make them public, because
 | 
				
			||||||
 | 
					// you can infer the rate at which some resource is being created, like
 | 
				
			||||||
 | 
					// users or business transactions.
 | 
				
			||||||
 | 
					// (https://news.ycombinator.com/item?id=14526173)
 | 
				
			||||||
 | 
					pub fn ulid() string {
 | 
				
			||||||
 | 
						return ulid_at_millisecond(u64(time.utc().unix_time_milli()))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ulid_at_millisecond does the same as `ulid` but takes a custom Unix millisecond timestamp via `unix_time_milli`.
 | 
				
			||||||
 | 
					pub fn ulid_at_millisecond(unix_time_milli u64) string {
 | 
				
			||||||
 | 
						buflen := 26
 | 
				
			||||||
 | 
						mut buf := unsafe { malloc_noscan(27) }
 | 
				
			||||||
 | 
						mut t := unix_time_milli
 | 
				
			||||||
 | 
						mut i := 9
 | 
				
			||||||
 | 
						for i >= 0 {
 | 
				
			||||||
 | 
							unsafe {
 | 
				
			||||||
 | 
								buf[i] = rand.ulid_encoding[t & 0x1F]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							t = t >> 5
 | 
				
			||||||
 | 
							i--
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// first rand set
 | 
				
			||||||
 | 
						mut x := default_rng.u64()
 | 
				
			||||||
 | 
						i = 10
 | 
				
			||||||
 | 
						for i < 19 {
 | 
				
			||||||
 | 
							unsafe {
 | 
				
			||||||
 | 
								buf[i] = rand.ulid_encoding[x & 0x1F]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							x = x >> 5
 | 
				
			||||||
 | 
							i++
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// second rand set
 | 
				
			||||||
 | 
						x = default_rng.u64()
 | 
				
			||||||
 | 
						for i < 26 {
 | 
				
			||||||
 | 
							unsafe {
 | 
				
			||||||
 | 
								buf[i] = rand.ulid_encoding[x & 0x1F]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							x = x >> 5
 | 
				
			||||||
 | 
							i++
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						unsafe {
 | 
				
			||||||
 | 
							buf[26] = 0
 | 
				
			||||||
 | 
							return buf.vstring_with_len(buflen)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// string_from_set returns a string of length `len` containing random characters sampled from the given `charset`
 | 
				
			||||||
 | 
					pub fn string_from_set(charset string, len int) string {
 | 
				
			||||||
 | 
						if len == 0 {
 | 
				
			||||||
 | 
							return ''
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						mut buf := unsafe { malloc_noscan(len + 1) }
 | 
				
			||||||
 | 
						for i in 0 .. len {
 | 
				
			||||||
 | 
							unsafe {
 | 
				
			||||||
 | 
								buf[i] = charset[intn(charset.len)]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						unsafe {
 | 
				
			||||||
 | 
							buf[len] = 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return unsafe { buf.vstring_with_len(len) }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// string returns a string of length `len` containing random characters in range `[a-zA-Z]`.
 | 
				
			||||||
 | 
					pub fn string(len int) string {
 | 
				
			||||||
 | 
						return string_from_set(english_letters, len)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// hex returns a hexadecimal number of length `len` containing random characters in range `[a-f0-9]`.
 | 
				
			||||||
 | 
					pub fn hex(len int) string {
 | 
				
			||||||
 | 
						return string_from_set(hex_chars, len)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ascii returns a random string of the printable ASCII characters with length `len`.
 | 
				
			||||||
 | 
					pub fn ascii(len int) string {
 | 
				
			||||||
 | 
						return string_from_set(ascii_chars, len)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										129
									
								
								vlib/rand/rand.v
								
								
								
								
							
							
						
						
									
										129
									
								
								vlib/rand/rand.v
								
								
								
								
							| 
						 | 
					@ -5,7 +5,6 @@ module rand
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import rand.seed
 | 
					import rand.seed
 | 
				
			||||||
import rand.wyrand
 | 
					import rand.wyrand
 | 
				
			||||||
import time
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PRNGConfigStruct is a configuration struct for creating a new instance of the default RNG.
 | 
					// PRNGConfigStruct is a configuration struct for creating a new instance of the default RNG.
 | 
				
			||||||
// Note that the RNGs may have a different number of u32s required for seeding. The default
 | 
					// Note that the RNGs may have a different number of u32s required for seeding. The default
 | 
				
			||||||
| 
						 | 
					@ -13,7 +12,7 @@ import time
 | 
				
			||||||
// uses a different number of u32s, use the `seed.time_seed_array()` method with the correct
 | 
					// uses a different number of u32s, use the `seed.time_seed_array()` method with the correct
 | 
				
			||||||
// number of u32s.
 | 
					// number of u32s.
 | 
				
			||||||
pub struct PRNGConfigStruct {
 | 
					pub struct PRNGConfigStruct {
 | 
				
			||||||
	seed []u32 = seed.time_seed_array(2)
 | 
						seed_ []u32 = seed.time_seed_array(2)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PRNG is a common interface for all PRNGs that can be used seamlessly with the rand
 | 
					// PRNG is a common interface for all PRNGs that can be used seamlessly with the rand
 | 
				
			||||||
| 
						 | 
					@ -55,7 +54,7 @@ fn init() {
 | 
				
			||||||
// new_default returns a new instance of the default RNG. If the seed is not provided, the current time will be used to seed the instance.
 | 
					// new_default returns a new instance of the default RNG. If the seed is not provided, the current time will be used to seed the instance.
 | 
				
			||||||
pub fn new_default(config PRNGConfigStruct) &PRNG {
 | 
					pub fn new_default(config PRNGConfigStruct) &PRNG {
 | 
				
			||||||
	mut rng := &wyrand.WyRandRNG{}
 | 
						mut rng := &wyrand.WyRandRNG{}
 | 
				
			||||||
	rng.seed(config.seed)
 | 
						rng.seed(config.seed_)
 | 
				
			||||||
	return rng
 | 
						return rng
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -191,127 +190,3 @@ const (
 | 
				
			||||||
	hex_chars       = 'abcdef0123456789'
 | 
						hex_chars       = 'abcdef0123456789'
 | 
				
			||||||
	ascii_chars     = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\^_`abcdefghijklmnopqrstuvwxyz{|}~'
 | 
						ascii_chars     = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\^_`abcdefghijklmnopqrstuvwxyz{|}~'
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					 | 
				
			||||||
// string_from_set returns a string of length `len` containing random characters sampled from the given `charset`
 | 
					 | 
				
			||||||
pub fn string_from_set(charset string, len int) string {
 | 
					 | 
				
			||||||
	if len == 0 {
 | 
					 | 
				
			||||||
		return ''
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	mut buf := unsafe { malloc_noscan(len + 1) }
 | 
					 | 
				
			||||||
	for i in 0 .. len {
 | 
					 | 
				
			||||||
		unsafe {
 | 
					 | 
				
			||||||
			buf[i] = charset[intn(charset.len)]
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	unsafe {
 | 
					 | 
				
			||||||
		buf[len] = 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return unsafe { buf.vstring_with_len(len) }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// string returns a string of length `len` containing random characters in range `[a-zA-Z]`.
 | 
					 | 
				
			||||||
pub fn string(len int) string {
 | 
					 | 
				
			||||||
	return string_from_set(rand.english_letters, len)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// hex returns a hexadecimal number of length `len` containing random characters in range `[a-f0-9]`.
 | 
					 | 
				
			||||||
pub fn hex(len int) string {
 | 
					 | 
				
			||||||
	return string_from_set(rand.hex_chars, len)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ascii returns a random string of the printable ASCII characters with length `len`.
 | 
					 | 
				
			||||||
pub fn ascii(len int) string {
 | 
					 | 
				
			||||||
	return string_from_set(rand.ascii_chars, len)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// uuid_v4 generates a random (v4) UUID
 | 
					 | 
				
			||||||
// See https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
 | 
					 | 
				
			||||||
pub fn uuid_v4() string {
 | 
					 | 
				
			||||||
	buflen := 36
 | 
					 | 
				
			||||||
	mut buf := unsafe { malloc_noscan(37) }
 | 
					 | 
				
			||||||
	mut i_buf := 0
 | 
					 | 
				
			||||||
	mut x := u64(0)
 | 
					 | 
				
			||||||
	mut d := byte(0)
 | 
					 | 
				
			||||||
	for i_buf < buflen {
 | 
					 | 
				
			||||||
		mut c := 0
 | 
					 | 
				
			||||||
		x = default_rng.u64()
 | 
					 | 
				
			||||||
		// do most of the bit manipulation at once:
 | 
					 | 
				
			||||||
		x &= 0x0F0F0F0F0F0F0F0F
 | 
					 | 
				
			||||||
		x += 0x3030303030303030
 | 
					 | 
				
			||||||
		// write the ASCII codes to the buffer:
 | 
					 | 
				
			||||||
		for c < 8 && i_buf < buflen {
 | 
					 | 
				
			||||||
			d = byte(x)
 | 
					 | 
				
			||||||
			unsafe {
 | 
					 | 
				
			||||||
				buf[i_buf] = if d > 0x39 { d + 0x27 } else { d }
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			i_buf++
 | 
					 | 
				
			||||||
			c++
 | 
					 | 
				
			||||||
			x = x >> 8
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// there are still some random bits in x:
 | 
					 | 
				
			||||||
	x = x >> 8
 | 
					 | 
				
			||||||
	d = byte(x)
 | 
					 | 
				
			||||||
	unsafe {
 | 
					 | 
				
			||||||
		buf[19] = if d > 0x39 { d + 0x27 } else { d }
 | 
					 | 
				
			||||||
		buf[8] = `-`
 | 
					 | 
				
			||||||
		buf[13] = `-`
 | 
					 | 
				
			||||||
		buf[18] = `-`
 | 
					 | 
				
			||||||
		buf[23] = `-`
 | 
					 | 
				
			||||||
		buf[14] = `4`
 | 
					 | 
				
			||||||
		buf[buflen] = 0
 | 
					 | 
				
			||||||
		return buf.vstring_with_len(buflen)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	ulid_encoding = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ulid generates an Unique Lexicographically sortable IDentifier.
 | 
					 | 
				
			||||||
// See https://github.com/ulid/spec .
 | 
					 | 
				
			||||||
// NB: ULIDs can leak timing information, if you make them public, because
 | 
					 | 
				
			||||||
// you can infer the rate at which some resource is being created, like
 | 
					 | 
				
			||||||
// users or business transactions.
 | 
					 | 
				
			||||||
// (https://news.ycombinator.com/item?id=14526173)
 | 
					 | 
				
			||||||
pub fn ulid() string {
 | 
					 | 
				
			||||||
	return ulid_at_millisecond(u64(time.utc().unix_time_milli()))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ulid_at_millisecond does the same as `ulid` but takes a custom Unix millisecond timestamp via `unix_time_milli`.
 | 
					 | 
				
			||||||
pub fn ulid_at_millisecond(unix_time_milli u64) string {
 | 
					 | 
				
			||||||
	buflen := 26
 | 
					 | 
				
			||||||
	mut buf := unsafe { malloc_noscan(27) }
 | 
					 | 
				
			||||||
	mut t := unix_time_milli
 | 
					 | 
				
			||||||
	mut i := 9
 | 
					 | 
				
			||||||
	for i >= 0 {
 | 
					 | 
				
			||||||
		unsafe {
 | 
					 | 
				
			||||||
			buf[i] = rand.ulid_encoding[t & 0x1F]
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		t = t >> 5
 | 
					 | 
				
			||||||
		i--
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// first rand set
 | 
					 | 
				
			||||||
	mut x := default_rng.u64()
 | 
					 | 
				
			||||||
	i = 10
 | 
					 | 
				
			||||||
	for i < 19 {
 | 
					 | 
				
			||||||
		unsafe {
 | 
					 | 
				
			||||||
			buf[i] = rand.ulid_encoding[x & 0x1F]
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		x = x >> 5
 | 
					 | 
				
			||||||
		i++
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// second rand set
 | 
					 | 
				
			||||||
	x = default_rng.u64()
 | 
					 | 
				
			||||||
	for i < 26 {
 | 
					 | 
				
			||||||
		unsafe {
 | 
					 | 
				
			||||||
			buf[i] = rand.ulid_encoding[x & 0x1F]
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		x = x >> 5
 | 
					 | 
				
			||||||
		i++
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	unsafe {
 | 
					 | 
				
			||||||
		buf[26] = 0
 | 
					 | 
				
			||||||
		return buf.vstring_with_len(buflen)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ fn (mut g JsGen) to_js_typ_def_val(s string) string {
 | 
				
			||||||
fn (mut g JsGen) to_js_typ_val(t ast.Type) string {
 | 
					fn (mut g JsGen) to_js_typ_val(t ast.Type) string {
 | 
				
			||||||
	sym := g.table.get_type_symbol(t)
 | 
						sym := g.table.get_type_symbol(t)
 | 
				
			||||||
	mut styp := ''
 | 
						mut styp := ''
 | 
				
			||||||
	mut prefix := if g.file.mod.name == 'builtin' { 'new ' } else { '' }
 | 
						mut prefix := if g.file.mod.name == 'builtin' { 'new  ' } else { 'new builtin.' }
 | 
				
			||||||
	match sym.kind {
 | 
						match sym.kind {
 | 
				
			||||||
		.i8, .i16, .int, .i64, .byte, .u8, .u16, .u32, .u64, .f32, .f64, .int_literal,
 | 
							.i8, .i16, .int, .i64, .byte, .u8, .u16, .u32, .u64, .f32, .f64, .int_literal,
 | 
				
			||||||
		.float_literal, .size_t {
 | 
							.float_literal, .size_t {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -135,6 +135,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		g.stmts(file.stmts)
 | 
							g.stmts(file.stmts)
 | 
				
			||||||
 | 
							g.writeln('try { init() } catch (_) {}')
 | 
				
			||||||
		// store the current namespace
 | 
							// store the current namespace
 | 
				
			||||||
		g.escape_namespace()
 | 
							g.escape_namespace()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -502,6 +503,24 @@ fn (mut g JsGen) gen_global_decl(node ast.GlobalDecl) {
 | 
				
			||||||
			); // global')
 | 
								); // global')
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			// TODO(playXE): Initialize with default value of type
 | 
								// TODO(playXE): Initialize with default value of type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if field.typ.is_ptr() {
 | 
				
			||||||
 | 
									g.writeln('Object.defineProperty(\$global,"$field.name", {
 | 
				
			||||||
 | 
										configurable: false,
 | 
				
			||||||
 | 
										$mod ,
 | 
				
			||||||
 | 
										writable: true,
 | 
				
			||||||
 | 
										value: new \$ref({})
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									); // global')
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									g.writeln('Object.defineProperty(\$global,"$field.name", {
 | 
				
			||||||
 | 
										configurable: false,
 | 
				
			||||||
 | 
										$mod ,
 | 
				
			||||||
 | 
										writable: true,
 | 
				
			||||||
 | 
										value: {}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									); // global')
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -961,8 +980,9 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if should_cast {
 | 
									if should_cast {
 | 
				
			||||||
					g.cast_stack << stmt.left_types.first()
 | 
										g.cast_stack << stmt.left_types.first()
 | 
				
			||||||
					if g.file.mod.name == 'builtin' {
 | 
										g.write('new ')
 | 
				
			||||||
						g.write('new ')
 | 
										if g.file.mod.name != 'builtin' {
 | 
				
			||||||
 | 
											g.write('builtin.')
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					g.write('${g.typ(stmt.left_types.first())}(')
 | 
										g.write('${g.typ(stmt.left_types.first())}(')
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
| 
						 | 
					@ -1770,13 +1790,15 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) {
 | 
				
			||||||
	if is_not {
 | 
						if is_not {
 | 
				
			||||||
		g.write('!(')
 | 
							g.write('!(')
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	is_arithmetic := it.op in [token.Kind.plus, .minus, .mul, .div, .mod]
 | 
						is_arithmetic := it.op in [token.Kind.plus, .minus, .mul, .div, .mod, .right_shift, .left_shift,
 | 
				
			||||||
 | 
							.amp, .pipe, .xor]
 | 
				
			||||||
	if is_arithmetic && ((l_sym.kind == .i64 || l_sym.kind == .u64)
 | 
						if is_arithmetic && ((l_sym.kind == .i64 || l_sym.kind == .u64)
 | 
				
			||||||
		|| (r_sym.kind == .i64 || r_sym.kind == .u64)) {
 | 
							|| (r_sym.kind == .i64 || r_sym.kind == .u64)) {
 | 
				
			||||||
		// if left or right is i64 or u64 we convert them to bigint to perform operation.
 | 
							// if left or right is i64 or u64 we convert them to bigint to perform operation.
 | 
				
			||||||
		greater_typ := g.greater_typ(it.left_type, it.right_type)
 | 
							greater_typ := g.greater_typ(it.left_type, it.right_type)
 | 
				
			||||||
		if g.ns.name == 'builtin' {
 | 
							g.write('new ')
 | 
				
			||||||
			g.write('new ')
 | 
							if g.ns.name != 'builtin' {
 | 
				
			||||||
 | 
								g.write('builtin.')
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		g.write('${g.typ(greater_typ)}(')
 | 
							g.write('${g.typ(greater_typ)}(')
 | 
				
			||||||
		g.cast_stack << greater_typ
 | 
							g.cast_stack << greater_typ
 | 
				
			||||||
| 
						 | 
					@ -2125,8 +2147,9 @@ fn (mut g JsGen) gen_type_cast_expr(it ast.CastExpr) {
 | 
				
			||||||
	// Skip cast if type is the same as the parrent caster
 | 
						// Skip cast if type is the same as the parrent caster
 | 
				
			||||||
	tsym := g.table.get_type_symbol(it.typ)
 | 
						tsym := g.table.get_type_symbol(it.typ)
 | 
				
			||||||
	if it.expr is ast.IntegerLiteral && (tsym.kind == .i64 || tsym.kind == .u64) {
 | 
						if it.expr is ast.IntegerLiteral && (tsym.kind == .i64 || tsym.kind == .u64) {
 | 
				
			||||||
		if g.ns.name == 'builtin' {
 | 
							g.write('new ')
 | 
				
			||||||
			g.write('new ')
 | 
							if g.ns.name != 'builtin' {
 | 
				
			||||||
 | 
								g.write('builtin.')
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		g.write(tsym.kind.str())
 | 
							g.write(tsym.kind.str())
 | 
				
			||||||
		g.write('(BigInt(')
 | 
							g.write('(BigInt(')
 | 
				
			||||||
| 
						 | 
					@ -2180,13 +2203,17 @@ fn (mut g JsGen) gen_integer_literal_expr(it ast.IntegerLiteral) {
 | 
				
			||||||
	// Skip cast if type is the same as the parrent caster
 | 
						// Skip cast if type is the same as the parrent caster
 | 
				
			||||||
	if g.cast_stack.len > 0 {
 | 
						if g.cast_stack.len > 0 {
 | 
				
			||||||
		if g.cast_stack[g.cast_stack.len - 1] in ast.integer_type_idxs {
 | 
							if g.cast_stack[g.cast_stack.len - 1] in ast.integer_type_idxs {
 | 
				
			||||||
			g.write('new int($it.val)')
 | 
								g.write('new ')
 | 
				
			||||||
 | 
								if g.ns.name != 'builtin' {
 | 
				
			||||||
 | 
									g.write('builtin.')
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								g.write('int($it.val)')
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						g.write('new ')
 | 
				
			||||||
	if g.ns.name == 'builtin' {
 | 
						if g.ns.name != 'builtin' {
 | 
				
			||||||
		g.write('new ')
 | 
							g.write('builtin.')
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	g.write('${g.typ(typ)}($it.val)')
 | 
						g.write('${g.typ(typ)}($it.val)')
 | 
				
			||||||
| 
						 | 
					@ -2225,9 +2252,9 @@ fn (mut g JsGen) gen_float_literal_expr(it ast.FloatLiteral) {
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						g.write('new ')
 | 
				
			||||||
	if g.ns.name == 'builtin' {
 | 
						if g.ns.name != 'builtin' {
 | 
				
			||||||
		g.write('new ')
 | 
							g.write('builtin.')
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	g.write('${g.typ(typ)}($it.val)')
 | 
						g.write('${g.typ(typ)}($it.val)')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue