checker: apply stricter type checks to function args and return types
							parent
							
								
									a7c84834f4
								
							
						
					
					
						commit
						076089d3c5
					
				| 
						 | 
				
			
			@ -84,7 +84,7 @@ pub fn (instance BitField) get_bit(bitnr int) int {
 | 
			
		|||
	if bitnr >= instance.size {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	return (instance.field[bitslot(bitnr)] >> (bitnr % slot_size)) & u32(1)
 | 
			
		||||
	return int((instance.field[bitslot(bitnr)] >> (bitnr % slot_size)) & u32(1))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// set_bit sets bit number 'bit_nr' to 1 (count from 0).
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ fn test_bf_set_clear_toggle_get() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn test_bf_and_not_or_xor() {
 | 
			
		||||
	rand.seed(time.now().unix)
 | 
			
		||||
	rand.seed(int(time.now().unix))
 | 
			
		||||
	len := 80
 | 
			
		||||
	mut input1 := bitfield.new(len)
 | 
			
		||||
	mut input2 := bitfield.new(len)
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ fn test_bf_and_not_or_xor() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn test_clone_cmp() {
 | 
			
		||||
	rand.seed(time.now().unix)
 | 
			
		||||
	rand.seed(int(time.now().unix))
 | 
			
		||||
	len := 80
 | 
			
		||||
	mut input := bitfield.new(len)
 | 
			
		||||
	for i in 0..len {
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +60,7 @@ fn test_clone_cmp() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn test_slice_join() {
 | 
			
		||||
	rand.seed(time.now().unix)
 | 
			
		||||
	rand.seed(int(time.now().unix))
 | 
			
		||||
	len := 80
 | 
			
		||||
	mut input := bitfield.new(len)
 | 
			
		||||
	for i in 0..len {
 | 
			
		||||
| 
						 | 
				
			
			@ -83,7 +83,7 @@ fn test_slice_join() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn test_pop_count() {
 | 
			
		||||
	rand.seed(time.now().unix)
 | 
			
		||||
	rand.seed(int(time.now().unix))
 | 
			
		||||
	len := 80
 | 
			
		||||
	mut count0 := 0
 | 
			
		||||
	mut input := bitfield.new(len)
 | 
			
		||||
| 
						 | 
				
			
			@ -98,7 +98,7 @@ fn test_pop_count() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn test_hamming() {
 | 
			
		||||
	rand.seed(time.now().unix)
 | 
			
		||||
	rand.seed(int(time.now().unix))
 | 
			
		||||
	len := 80
 | 
			
		||||
	mut count := 0
 | 
			
		||||
	mut input1 := bitfield.new(len)
 | 
			
		||||
| 
						 | 
				
			
			@ -138,7 +138,7 @@ fn test_bf_from_bytes() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn test_bf_from_str() {
 | 
			
		||||
	rand.seed(time.now().unix)
 | 
			
		||||
	rand.seed(int(time.now().unix))
 | 
			
		||||
	len := 80
 | 
			
		||||
	mut input := ''
 | 
			
		||||
	for _ in 0..len {
 | 
			
		||||
| 
						 | 
				
			
			@ -160,7 +160,7 @@ fn test_bf_from_str() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn test_bf_bf2str() {
 | 
			
		||||
	rand.seed(time.now().unix)
 | 
			
		||||
	rand.seed(int(time.now().unix))
 | 
			
		||||
	len := 80
 | 
			
		||||
	mut input := bitfield.new(len)
 | 
			
		||||
	for i in 0..len {
 | 
			
		||||
| 
						 | 
				
			
			@ -188,7 +188,7 @@ fn test_bf_bf2str() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn test_bf_set_all() {
 | 
			
		||||
	rand.seed(time.now().unix)
 | 
			
		||||
	rand.seed(int(time.now().unix))
 | 
			
		||||
	len := 80
 | 
			
		||||
	mut input := bitfield.new(len)
 | 
			
		||||
	input.set_all()
 | 
			
		||||
| 
						 | 
				
			
			@ -202,7 +202,7 @@ fn test_bf_set_all() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn test_bf_clear_all() {
 | 
			
		||||
	rand.seed(time.now().unix)
 | 
			
		||||
	rand.seed(int(time.now().unix))
 | 
			
		||||
	len := 80
 | 
			
		||||
	mut input := bitfield.new(len)
 | 
			
		||||
	for i in 0..len {
 | 
			
		||||
| 
						 | 
				
			
			@ -221,7 +221,7 @@ fn test_bf_clear_all() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn test_bf_reverse() {
 | 
			
		||||
	rand.seed(time.now().unix)
 | 
			
		||||
	rand.seed(int(time.now().unix))
 | 
			
		||||
	len := 80
 | 
			
		||||
	mut input := bitfield.new(len)
 | 
			
		||||
	for i in 0..len {
 | 
			
		||||
| 
						 | 
				
			
			@ -241,7 +241,7 @@ fn test_bf_reverse() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn test_bf_resize() {
 | 
			
		||||
	rand.seed(time.now().unix)
 | 
			
		||||
	rand.seed(int(time.now().unix))
 | 
			
		||||
	len := 80
 | 
			
		||||
	mut input := bitfield.new(rand.next(len) + 1)
 | 
			
		||||
	for _ in 0..100 {
 | 
			
		||||
| 
						 | 
				
			
			@ -259,7 +259,7 @@ fn test_bf_pos() {
 | 
			
		|||
	 * all haystacks here contain exactly one instanse of needle,
 | 
			
		||||
	 * so search should return non-negative-values
 | 
			
		||||
	**/
 | 
			
		||||
	rand.seed(time.now().unix)
 | 
			
		||||
	rand.seed(int(time.now().unix))
 | 
			
		||||
	len := 80
 | 
			
		||||
	mut result := 1
 | 
			
		||||
	for i := 1; i < len; i++ {	// needle size
 | 
			
		||||
| 
						 | 
				
			
			@ -322,7 +322,7 @@ fn test_bf_rotate() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn test_bf_printing(){
 | 
			
		||||
	rand.seed(time.now().unix)
 | 
			
		||||
	rand.seed(int(time.now().unix))
 | 
			
		||||
	len := 80
 | 
			
		||||
	mut input := bitfield.new(len)
 | 
			
		||||
	for i in 0..len {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -111,7 +111,7 @@ fn new_dense_array(value_bytes int) DenseArray {
 | 
			
		|||
		cap: 8
 | 
			
		||||
		size: 0
 | 
			
		||||
		deletes: 0
 | 
			
		||||
		keys: &string(malloc(8 * sizeof(string)))
 | 
			
		||||
		keys: &string(malloc(int(8 * sizeof(string))))
 | 
			
		||||
		values: malloc(8 * value_bytes)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -198,7 +198,7 @@ fn new_map_1(value_bytes int) map {
 | 
			
		|||
		cached_hashbits: max_cached_hashbits
 | 
			
		||||
		shift: init_log_capicity
 | 
			
		||||
		key_values: new_dense_array(value_bytes)
 | 
			
		||||
		metas: &u32(vcalloc(sizeof(u32) * (init_capicity + extra_metas_inc)))
 | 
			
		||||
		metas: &u32(vcalloc(int(sizeof(u32) * (init_capicity + extra_metas_inc))))
 | 
			
		||||
		extra_metas: extra_metas_inc
 | 
			
		||||
		size: 0
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -323,7 +323,7 @@ fn (mut m map) rehash() {
 | 
			
		|||
 | 
			
		||||
fn (mut m map) cached_rehash(old_cap u32) {
 | 
			
		||||
	old_metas := m.metas
 | 
			
		||||
	m.metas = &u32(vcalloc(sizeof(u32) * (m.cap + 2 + m.extra_metas)))
 | 
			
		||||
	m.metas = &u32(vcalloc(int(sizeof(u32) * (m.cap + 2 + m.extra_metas))))
 | 
			
		||||
	old_extra_metas := m.extra_metas
 | 
			
		||||
	for i := u32(0); i <= old_cap + old_extra_metas; i += 2 {
 | 
			
		||||
		if old_metas[i] == 0 {
 | 
			
		||||
| 
						 | 
				
			
			@ -430,8 +430,8 @@ pub fn (d DenseArray) clone() DenseArray {
 | 
			
		|||
		cap:         d.cap
 | 
			
		||||
		size:        d.size
 | 
			
		||||
		deletes:     d.deletes
 | 
			
		||||
		keys:        &string(malloc(d.cap * sizeof(string)))
 | 
			
		||||
		values:      byteptr(malloc(d.cap * u32(d.value_bytes)))
 | 
			
		||||
		keys:        &string(malloc(int(d.cap * sizeof(string))))
 | 
			
		||||
		values:      byteptr(malloc(int(d.cap * u32(d.value_bytes))))
 | 
			
		||||
	}
 | 
			
		||||
	C.memcpy(res.keys, d.keys, d.cap * sizeof(string))
 | 
			
		||||
	C.memcpy(res.values, d.values, d.cap * u32(d.value_bytes))
 | 
			
		||||
| 
						 | 
				
			
			@ -447,7 +447,7 @@ pub fn (m map) clone() map {
 | 
			
		|||
		cached_hashbits: m.cached_hashbits
 | 
			
		||||
		shift:           m.shift
 | 
			
		||||
		key_values:      m.key_values.clone()
 | 
			
		||||
		metas:           &u32(malloc(metas_size))
 | 
			
		||||
		metas:           &u32(malloc(int(metas_size)))
 | 
			
		||||
		extra_metas:     m.extra_metas
 | 
			
		||||
		size:            m.size
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -121,13 +121,13 @@ fn (mut n mapnode) split_child(child_index int, y mut mapnode) {
 | 
			
		|||
		z.values[j] = y.values[j + degree]
 | 
			
		||||
	}
 | 
			
		||||
	if !isnil(y.children) {
 | 
			
		||||
		z.children = &voidptr(malloc(children_bytes))
 | 
			
		||||
		z.children = &voidptr(malloc(int(children_bytes)))
 | 
			
		||||
		for jj := degree - 1; jj >= 0; jj-- {
 | 
			
		||||
			z.children[jj] = y.children[jj + degree]
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if isnil(n.children) {
 | 
			
		||||
		n.children = &voidptr(malloc(children_bytes))
 | 
			
		||||
		n.children = &voidptr(malloc(int(children_bytes)))
 | 
			
		||||
	}
 | 
			
		||||
	n.children[n.size + 1] = n.children[n.size]
 | 
			
		||||
	for j := n.size; j > child_index; j-- {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -982,7 +982,7 @@ pub fn (s string) ustring() ustring {
 | 
			
		|||
		// runes will have at least s.len elements, save reallocations
 | 
			
		||||
		// TODO use VLA for small strings?
 | 
			
		||||
 | 
			
		||||
		runes: __new_array(0, s.len, sizeof(int))
 | 
			
		||||
		runes: __new_array(0, s.len, int(sizeof(int)))
 | 
			
		||||
	}
 | 
			
		||||
	for i := 0; i < s.len; i++ {
 | 
			
		||||
		char_len := utf8_char_len(s.str[i])
 | 
			
		||||
| 
						 | 
				
			
			@ -1000,7 +1000,7 @@ __global g_ustring_runes []int
 | 
			
		|||
 | 
			
		||||
pub fn (s string) ustring_tmp() ustring {
 | 
			
		||||
	if g_ustring_runes.len == 0 {
 | 
			
		||||
		g_ustring_runes = __new_array(0, 128, sizeof(int))
 | 
			
		||||
		g_ustring_runes = __new_array(0, 128, int(sizeof(int)))
 | 
			
		||||
	}
 | 
			
		||||
	mut res := ustring{
 | 
			
		||||
		s: s
 | 
			
		||||
| 
						 | 
				
			
			@ -1048,7 +1048,7 @@ fn (u ustring) ge(a ustring) bool {
 | 
			
		|||
pub fn (u ustring) add(a ustring) ustring {
 | 
			
		||||
	mut res := ustring{
 | 
			
		||||
		s: u.s + a.s
 | 
			
		||||
		runes: __new_array(0, u.s.len + a.s.len, sizeof(int))
 | 
			
		||||
		runes: __new_array(0, u.s.len + a.s.len, int(sizeof(int)))
 | 
			
		||||
	}
 | 
			
		||||
	mut j := 0
 | 
			
		||||
	for i := 0; i < u.s.len; i++ {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -227,7 +227,7 @@ fn utf8_str_visible_length(s string) int {
 | 
			
		|||
// Reads an utf8 character from standard input
 | 
			
		||||
pub fn utf8_getchar() int {
 | 
			
		||||
	c := C.getchar()
 | 
			
		||||
	len := utf8_len(~c)
 | 
			
		||||
	len := utf8_len(byte(~c))
 | 
			
		||||
	if c < 0 {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -183,7 +183,7 @@ pub fn new_context(cfg gg.Cfg) &FreeType {
 | 
			
		|||
	C.glBlendFunc(C.GL_SRC_ALPHA, C.GL_ONE_MINUS_SRC_ALPHA)
 | 
			
		||||
	shader := gl.new_shader('text')
 | 
			
		||||
	shader.use()
 | 
			
		||||
	projection := glm.ortho(0, width, 0, height) // 0 at BOT
 | 
			
		||||
	projection := glm.ortho(0, f32(width), 0, f32(height)) // 0 at BOT
 | 
			
		||||
	shader.set_mat4('projection', projection)
 | 
			
		||||
	// FREETYPE
 | 
			
		||||
	ft := C.FT_Library{}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,7 +100,7 @@ pub fn new_context(cfg Cfg) &GG {
 | 
			
		|||
	shader := gl.new_shader('simple')
 | 
			
		||||
	shader.use()
 | 
			
		||||
	if cfg.use_ortho {
 | 
			
		||||
		projection := glm.ortho(0, cfg.width, cfg.height, 0)
 | 
			
		||||
		projection := glm.ortho(0, f32(cfg.width), f32(cfg.height), 0)
 | 
			
		||||
		shader.set_mat4('projection', projection)
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
| 
						 | 
				
			
			@ -304,7 +304,7 @@ fn todo_remove_me(cfg Cfg, scale int) {
 | 
			
		|||
	//# glBlendFunc(C.GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 | 
			
		||||
	shader := gl.new_shader('text')
 | 
			
		||||
	shader.use()
 | 
			
		||||
	projection := glm.ortho(0, width, 0, height)// 0 at BOT
 | 
			
		||||
	projection := glm.ortho(0, f32(width), 0, f32(height))// 0 at BOT
 | 
			
		||||
	// projection_new := ortho(0, width, 0, height)// 0 at BOT
 | 
			
		||||
	// projection := gl.ortho(0, width,height,0)  // 0 at TOP
 | 
			
		||||
	shader.set_mat4('projection', projection)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -398,7 +398,7 @@ fn ortho_js(left, right, bottom, top f32) &f32 {
 | 
			
		|||
	bt := 1.0 / (bottom - top)
 | 
			
		||||
	nf := f32(1.0) / 1.0// (mynear -myfar)
 | 
			
		||||
	mut out := &f32(0)
 | 
			
		||||
	unsafe { out = &f32( malloc (sizeof(f32) * 16)) }
 | 
			
		||||
	unsafe { out = &f32( malloc (int(sizeof(f32) * 16))) }
 | 
			
		||||
	out[0] = -2.0 * lr
 | 
			
		||||
	out[1] = 0
 | 
			
		||||
	out[2] = 0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,6 +58,6 @@ pub fn new(poly int) &Crc32 {
 | 
			
		|||
 | 
			
		||||
// calculate crc32 using ieee
 | 
			
		||||
pub fn sum(b []byte) u32 {
 | 
			
		||||
	c := new(ieee)
 | 
			
		||||
	c := new(int(ieee))
 | 
			
		||||
	return c.sum32(b)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,7 @@ fn test_hash_crc32() {
 | 
			
		|||
	assert sum1.hex() == '483f8cf0'
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	c := crc32.new(crc32.ieee)
 | 
			
		||||
	c := crc32.new(int(crc32.ieee))
 | 
			
		||||
	b2 := 'testing crc32 again'.bytes()
 | 
			
		||||
	sum2 := c.checksum(b2)
 | 
			
		||||
	assert sum2 == u32(1420327025)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -208,7 +208,7 @@ pub fn reverse_32(x u32) u32 {
 | 
			
		|||
	mut y := ((x>>u32(1) & (m0 & max_u32)) | ((x & (m0 & max_u32))<<1))
 | 
			
		||||
	y = ((y>>u32(2) & (m1 & max_u32)) | ((y & (m1 & max_u32))<<u32(2)))
 | 
			
		||||
	y = ((y>>u32(4) & (m2 & max_u32)) | ((y & (m2 & max_u32))<<u32(4)))
 | 
			
		||||
	return reverse_bytes_32(y)
 | 
			
		||||
	return reverse_bytes_32(u32(y))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// reverse_64 returns the value of x with its bits in reversed order.
 | 
			
		||||
| 
						 | 
				
			
			@ -236,7 +236,7 @@ pub fn reverse_bytes_16(x u16) u16 {
 | 
			
		|||
[inline]
 | 
			
		||||
pub fn reverse_bytes_32(x u32) u32 {
 | 
			
		||||
	y := ((x>>u32(8) & (m3 & max_u32)) | ((x & (m3 & max_u32))<<u32(8)))
 | 
			
		||||
	return (y>>16) | (y<<16)
 | 
			
		||||
	return u32((y>>16) | (y<<16))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// reverse_bytes_64 returns the value of x with its bytes in reversed order.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -240,7 +240,7 @@ fn cmp_f64s(a, b f64) int {
 | 
			
		|||
// Two integers are safe to multiply when their bit lengths
 | 
			
		||||
// sum up to less than 64 (conservative estimate).
 | 
			
		||||
fn safe_to_multiply(a, b i64) bool {
 | 
			
		||||
	return (bits.len_64(abs(a)) + bits.len_64(abs(b))) < 64
 | 
			
		||||
	return (bits.len_64(u64(abs(a))) + bits.len_64(u64(abs(b)))) < 64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn cmp(f1, f2 Fraction) int {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -418,7 +418,7 @@ pub fn (mut ws Client) read() int {
 | 
			
		|||
	} else if frame.opcode in [.text_frame, .binary_frame] {
 | 
			
		||||
		data_node:
 | 
			
		||||
		l.d('read: recieved text_frame or binary_frame')
 | 
			
		||||
		mut payload := malloc(sizeof(byte) * u32(payload_len) + 1)
 | 
			
		||||
		mut payload := malloc(int(sizeof(byte) * u32(payload_len) + 1))
 | 
			
		||||
		if payload == 0 {
 | 
			
		||||
			l.f('out of memory')
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -438,7 +438,7 @@ pub fn (mut ws Client) read() int {
 | 
			
		|||
						size += f.len
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				mut pl := malloc(sizeof(byte) * u32(size))
 | 
			
		||||
				mut pl := malloc(int(sizeof(byte) * u32(size)))
 | 
			
		||||
				if pl == 0 {
 | 
			
		||||
					l.f('out of memory')
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -203,8 +203,8 @@ match c {
 | 
			
		|||
			`B` { return .history_next }
 | 
			
		||||
			`A` { return .history_previous }
 | 
			
		||||
			`1` { return r.analyse_extended_control() }
 | 
			
		||||
			`2` { return r.analyse_extended_control_no_eat(sequence) }
 | 
			
		||||
			`3` { return r.analyse_extended_control_no_eat(sequence) }
 | 
			
		||||
			`2` { return r.analyse_extended_control_no_eat(byte(sequence)) }
 | 
			
		||||
			`3` { return r.analyse_extended_control_no_eat(byte(sequence)) }
 | 
			
		||||
			else {}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,7 @@ const (
 | 
			
		|||
fn test_now_format() {
 | 
			
		||||
	t := time.now()
 | 
			
		||||
	u := t.unix
 | 
			
		||||
	assert t.format() == time.unix(u).format()
 | 
			
		||||
	assert t.format() == time.unix(int(u)).format()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn test_format() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,5 +8,5 @@ const (
 | 
			
		|||
)
 | 
			
		||||
// random returns a random time struct in *the past*.
 | 
			
		||||
pub fn random() time.Time {
 | 
			
		||||
	return time.unix(rand.next(start_time_unix))
 | 
			
		||||
	return time.unix(rand.next(int(start_time_unix)))
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -118,7 +118,7 @@ pub fn new_time(t Time) Time {
 | 
			
		|||
// unix_time returns Unix time.
 | 
			
		||||
pub fn (t Time) unix_time() int {
 | 
			
		||||
	if t.unix != 0 {
 | 
			
		||||
		return t.unix
 | 
			
		||||
		return int(t.unix)
 | 
			
		||||
	}
 | 
			
		||||
	tt := C.tm{
 | 
			
		||||
		tm_sec: t.second
 | 
			
		||||
| 
						 | 
				
			
			@ -134,12 +134,12 @@ pub fn (t Time) unix_time() int {
 | 
			
		|||
// add_seconds returns a new time struct with an added number of seconds.
 | 
			
		||||
pub fn (t Time) add_seconds(seconds int) Time {
 | 
			
		||||
	// TODO Add(d time.Duration)
 | 
			
		||||
	return unix(t.unix + u64(seconds))
 | 
			
		||||
	return unix(int(t.unix + u64(seconds)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// add_days returns a new time struct with an added number of days.
 | 
			
		||||
pub fn (t Time) add_days(days int) Time {
 | 
			
		||||
	return unix(t.unix + u64(i64(days) * 3600 * 24))
 | 
			
		||||
	return unix(int(t.unix + u64(i64(days) * 3600 * 24)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// since returns a number of seconds elapsed since a given time.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@ module checker
 | 
			
		|||
import v.table
 | 
			
		||||
import v.token
 | 
			
		||||
 | 
			
		||||
pub fn (c &Checker) check_types(got, expected table.Type) bool {
 | 
			
		||||
pub fn (c &Checker) check_basic(got, expected table.Type) bool {
 | 
			
		||||
	t := c.table
 | 
			
		||||
	got_idx := t.unalias_num_type(got).idx()
 | 
			
		||||
	exp_idx := t.unalias_num_type(expected).idx()
 | 
			
		||||
| 
						 | 
				
			
			@ -114,10 +114,10 @@ pub fn (c &Checker) check_types(got, expected table.Type) bool {
 | 
			
		|||
		exp_fn := exp_info.func
 | 
			
		||||
		// we are using check() to compare return type & args as they might include
 | 
			
		||||
		// functions themselves. TODO: optimize, only use check() when needed
 | 
			
		||||
		if got_fn.args.len == exp_fn.args.len && c.check_types(got_fn.return_type, exp_fn.return_type) {
 | 
			
		||||
		if got_fn.args.len == exp_fn.args.len && c.check_basic(got_fn.return_type, exp_fn.return_type) {
 | 
			
		||||
			for i, got_arg in got_fn.args {
 | 
			
		||||
				exp_arg := exp_fn.args[i]
 | 
			
		||||
				if !c.check_types(got_arg.typ, exp_arg.typ) {
 | 
			
		||||
				if !c.check_basic(got_arg.typ, exp_arg.typ) {
 | 
			
		||||
					return false
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -157,55 +157,57 @@ pub fn (c &Checker) promote(left_type, right_type table.Type) table.Type {
 | 
			
		|||
		return left_type // strings, self defined operators
 | 
			
		||||
	}
 | 
			
		||||
	if right_type.is_number() && left_type.is_number() {
 | 
			
		||||
		// sort the operands to save time
 | 
			
		||||
		mut type_hi := left_type
 | 
			
		||||
		mut type_lo := right_type
 | 
			
		||||
		if type_hi.idx() < type_lo.idx() {
 | 
			
		||||
			tmp := type_hi
 | 
			
		||||
			type_hi = type_lo
 | 
			
		||||
			type_lo = tmp
 | 
			
		||||
		}
 | 
			
		||||
		idx_hi := type_hi.idx()
 | 
			
		||||
		idx_lo := type_lo.idx()
 | 
			
		||||
		// the following comparisons rely on the order of the indices in atypes.v
 | 
			
		||||
		if idx_hi == table.any_int_type_idx {
 | 
			
		||||
			return type_lo
 | 
			
		||||
		} else if idx_hi == table.any_flt_type_idx {
 | 
			
		||||
			if idx_lo in table.float_type_idxs {
 | 
			
		||||
				return type_lo
 | 
			
		||||
			} else {
 | 
			
		||||
				return table.void_type
 | 
			
		||||
			}
 | 
			
		||||
		} else if type_hi.is_float() {
 | 
			
		||||
			if idx_hi == table.f32_type_idx {
 | 
			
		||||
				if idx_lo in [table.int_type_idx, table.i64_type_idx, table.u32_type_idx, table.u64_type_idx] {
 | 
			
		||||
					return table.void_type
 | 
			
		||||
				} else {
 | 
			
		||||
					return type_hi
 | 
			
		||||
				}
 | 
			
		||||
			} else { // f64, any_flt
 | 
			
		||||
				if idx_lo in [table.i64_type_idx, table.u64_type_idx] {
 | 
			
		||||
					return table.void_type
 | 
			
		||||
				} else {
 | 
			
		||||
					return type_hi
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else if idx_lo >= table.byte_type_idx { // both operands are unsigned
 | 
			
		||||
			return type_hi
 | 
			
		||||
		} else if idx_lo >= table.i8_type_idx && idx_hi <= table.i64_type_idx { // both signed
 | 
			
		||||
			return type_hi
 | 
			
		||||
		} else if idx_hi - idx_lo < (table.byte_type_idx - table.i8_type_idx) {
 | 
			
		||||
			return type_lo // conversion unsigned -> signed if signed type is larger
 | 
			
		||||
		} else {
 | 
			
		||||
			return table.void_type // conversion signed -> unsigned not allowed
 | 
			
		||||
		}
 | 
			
		||||
		return c.promote_num(left_type, right_type)
 | 
			
		||||
	} else {
 | 
			
		||||
		return left_type // default to left if not automatic promotion possible
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: promote(), assign_check(), symmetric_check() and check() overlap - should be rearranged
 | 
			
		||||
pub fn (c &Checker) assign_check(got, expected table.Type) bool {
 | 
			
		||||
fn (c &Checker) promote_num(left_type, right_type table.Type) table.Type {
 | 
			
		||||
	// sort the operands to save time
 | 
			
		||||
	mut type_hi := left_type
 | 
			
		||||
	mut type_lo := right_type
 | 
			
		||||
	if type_hi.idx() < type_lo.idx() {
 | 
			
		||||
		type_hi, type_lo = type_lo, type_hi
 | 
			
		||||
	}
 | 
			
		||||
	idx_hi := type_hi.idx()
 | 
			
		||||
	idx_lo := type_lo.idx()
 | 
			
		||||
	// the following comparisons rely on the order of the indices in atypes.v
 | 
			
		||||
	if idx_hi == table.any_int_type_idx {
 | 
			
		||||
		return type_lo
 | 
			
		||||
	} else if idx_hi == table.any_flt_type_idx {
 | 
			
		||||
		if idx_lo in table.float_type_idxs {
 | 
			
		||||
			return type_lo
 | 
			
		||||
		} else {
 | 
			
		||||
			return table.void_type
 | 
			
		||||
		}
 | 
			
		||||
	} else if type_hi.is_float() {
 | 
			
		||||
		if idx_hi == table.f32_type_idx {
 | 
			
		||||
			if idx_lo in [table.int_type_idx, table.i64_type_idx, table.u32_type_idx, table.u64_type_idx] {
 | 
			
		||||
				return table.void_type
 | 
			
		||||
			} else {
 | 
			
		||||
				return type_hi
 | 
			
		||||
			}
 | 
			
		||||
		} else { // f64, any_flt
 | 
			
		||||
			if idx_lo in [table.i64_type_idx, table.u64_type_idx] {
 | 
			
		||||
				return table.void_type
 | 
			
		||||
			} else {
 | 
			
		||||
				return type_hi
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else if idx_lo >= table.byte_type_idx { // both operands are unsigned
 | 
			
		||||
		return type_hi
 | 
			
		||||
	} else if idx_lo >= table.i8_type_idx && idx_hi <= table.i64_type_idx { // both signed
 | 
			
		||||
		return type_hi
 | 
			
		||||
	} else if idx_hi - idx_lo < (table.byte_type_idx - table.i8_type_idx) {
 | 
			
		||||
		return type_lo // conversion unsigned -> signed if signed type is larger
 | 
			
		||||
	} else {
 | 
			
		||||
		return table.void_type // conversion signed -> unsigned not allowed
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: promote(), check_types(), symmetric_check() and check() overlap - should be rearranged
 | 
			
		||||
pub fn (c &Checker) check_types(got, expected table.Type) bool {
 | 
			
		||||
	exp_idx := expected.idx()
 | 
			
		||||
	got_idx := got.idx()
 | 
			
		||||
	if exp_idx == got_idx {
 | 
			
		||||
| 
						 | 
				
			
			@ -228,12 +230,14 @@ pub fn (c &Checker) assign_check(got, expected table.Type) bool {
 | 
			
		|||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if !c.check_types(got, expected) { // TODO: this should go away...
 | 
			
		||||
	if !c.check_basic(got, expected) { // TODO: this should go away...
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	if c.promote(expected, got) != expected {
 | 
			
		||||
		println('could not promote ${c.table.get_type_symbol(got).name} to ${c.table.get_type_symbol(expected).name}')
 | 
			
		||||
		return false
 | 
			
		||||
	if got.is_number() && expected.is_number() {
 | 
			
		||||
		if c.promote_num(expected, got) != expected {
 | 
			
		||||
			// println('could not promote ${c.table.get_type_symbol(got).name} to ${c.table.get_type_symbol(expected).name}')
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -252,5 +256,5 @@ pub fn (c &Checker) symmetric_check(left, right table.Type) bool {
 | 
			
		|||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return c.check_types(left, right)
 | 
			
		||||
	return c.check_basic(left, right)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -369,7 +369,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type {
 | 
			
		|||
				expr_type := c.expr(field.expr)
 | 
			
		||||
				expr_type_sym := c.table.get_type_symbol(expr_type)
 | 
			
		||||
				field_type_sym := c.table.get_type_symbol(info_field.typ)
 | 
			
		||||
				if !c.assign_check(expr_type, info_field.typ) {
 | 
			
		||||
				if !c.check_types(expr_type, info_field.typ) {
 | 
			
		||||
					c.error('cannot assign `$expr_type_sym.name` as `$field_type_sym.name` for field `$info_field.name`',
 | 
			
		||||
						field.pos)
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -698,7 +698,7 @@ fn (mut c Checker) assign_expr(mut assign_expr ast.AssignExpr) {
 | 
			
		|||
		else {}
 | 
			
		||||
	}
 | 
			
		||||
	// Dual sides check (compatibility check)
 | 
			
		||||
	if !c.assign_check(right_type, left_type) {
 | 
			
		||||
	if !c.check_types(right_type, left_type) {
 | 
			
		||||
		left_type_sym := c.table.get_type_symbol(left_type)
 | 
			
		||||
		right_type_sym := c.table.get_type_symbol(right_type)
 | 
			
		||||
		c.error('cannot assign `$right_type_sym.name` to variable `${assign_expr.left.str()}` of type `$left_type_sym.name`',
 | 
			
		||||
| 
						 | 
				
			
			@ -1434,7 +1434,7 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type {
 | 
			
		|||
				c.expected_type = elem_type
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			if !c.check_types(elem_type, typ) {
 | 
			
		||||
			if !c.check_types(typ, elem_type) {
 | 
			
		||||
				elem_type_sym := c.table.get_type_symbol(elem_type)
 | 
			
		||||
				c.error('expected array element with type `$elem_type_sym.name`', array_init.pos)
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
vlib/v/checker/tests/function_wrong_arg_type.v:7:7: error: cannot use type `f64` as type `int` in argument 1 to `f`
 | 
			
		||||
    5 | fn main() {
 | 
			
		||||
    6 |     a := 12.3
 | 
			
		||||
    7 |     q := f(a)
 | 
			
		||||
      |          ~~~~
 | 
			
		||||
    8 |     println('$q')
 | 
			
		||||
    9 | }
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
fn f(x int) int {
 | 
			
		||||
	return x+x
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
	a := 12.3
 | 
			
		||||
	q := f(a)
 | 
			
		||||
	println('$q')
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
vlib/v/checker/tests/function_wrong_return_type.v:2:9: error: cannot use `any_float` as type `int` in return argument
 | 
			
		||||
    1 | fn h() int {
 | 
			
		||||
    2 |     return 3.14
 | 
			
		||||
      |            ~~~~
 | 
			
		||||
    3 | }
 | 
			
		||||
    4 |
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
fn h() int {
 | 
			
		||||
	return 3.14
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
	d := h()
 | 
			
		||||
	println('$d')
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -225,7 +225,7 @@ fn (mut g Gen) jne() int {
 | 
			
		|||
	pos := g.pos()
 | 
			
		||||
	g.write32(placeholder)
 | 
			
		||||
	g.println('jne')
 | 
			
		||||
	return pos
 | 
			
		||||
	return int(pos)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn (mut g Gen) jge() int {
 | 
			
		||||
| 
						 | 
				
			
			@ -233,7 +233,7 @@ fn (mut g Gen) jge() int {
 | 
			
		|||
	pos := g.pos()
 | 
			
		||||
	g.write32(placeholder)
 | 
			
		||||
	g.println('jne')
 | 
			
		||||
	return pos
 | 
			
		||||
	return int(pos)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn (mut g Gen) jmp(addr int) {
 | 
			
		||||
| 
						 | 
				
			
			@ -669,7 +669,7 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
 | 
			
		|||
	// The value is the relative address, difference between current position and the location
 | 
			
		||||
	// after `jne 00 00 00 00`
 | 
			
		||||
	// println('after if g.pos=$g.pos() jneaddr=$jne_addr')
 | 
			
		||||
	g.write32_at(jne_addr, g.pos() - jne_addr - 4) // 4 is for "00 00 00 00"
 | 
			
		||||
	g.write32_at(jne_addr, int(g.pos() - jne_addr - 4)) // 4 is for "00 00 00 00"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn (mut g Gen) for_stmt(node ast.ForStmt) {
 | 
			
		||||
| 
						 | 
				
			
			@ -690,9 +690,9 @@ fn (mut g Gen) for_stmt(node ast.ForStmt) {
 | 
			
		|||
	g.stmts(node.stmts)
 | 
			
		||||
	// Go back to `cmp ...`
 | 
			
		||||
	// Diff between `jmp 00 00 00 00 X` and `cmp`
 | 
			
		||||
	g.jmp(0xffffffff - (g.pos() + 5 - start) + 1)
 | 
			
		||||
	g.jmp(int(0xffffffff - (g.pos() + 5 - start) + 1))
 | 
			
		||||
	// Update the jump addr to current pos
 | 
			
		||||
	g.write32_at(jump_addr, g.pos() - jump_addr - 4) // 4 is for "00 00 00 00"
 | 
			
		||||
	g.write32_at(jump_addr, int(g.pos() - jump_addr - 4)) // 4 is for "00 00 00 00"
 | 
			
		||||
	g.println('jpm after for')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,7 +23,7 @@ fn high_fn_multi_return(a int, b fn (c []int, d []string) ([]int, []string)) {
 | 
			
		|||
fn high_fn_return_single_anon() (fn(int)f32) {
 | 
			
		||||
	_ := 1
 | 
			
		||||
	correct := fn(n int)f32 {
 | 
			
		||||
		return n * n
 | 
			
		||||
		return f32(n * n)
 | 
			
		||||
	}
 | 
			
		||||
	return correct
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -36,7 +36,7 @@ fn high_fn_return_multi_anons() (fn(int)f32, fn(int)string) {
 | 
			
		|||
		return '$n'
 | 
			
		||||
	}
 | 
			
		||||
	correct_first := fn(n int)f32 {
 | 
			
		||||
		return n * n
 | 
			
		||||
		return f32(n * n)
 | 
			
		||||
	}
 | 
			
		||||
	// parsing trap
 | 
			
		||||
	_ := fn(n int)[]int {
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +110,7 @@ fn simple_fn1() int {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn simple_fn2(n f32) (int, string) {
 | 
			
		||||
	return 1 + n, "fish"
 | 
			
		||||
	return int(1 + n), "fish"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn test_assigning_fns() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue