parser: fix shift-assign to work with all integer types
							parent
							
								
									3080959084
								
							
						
					
					
						commit
						af81b02ef0
					
				| 
						 | 
				
			
			@ -1277,6 +1277,14 @@ fn ($v.name mut $v.typ) $p.cur_fn.name (...) {
 | 
			
		|||
		}
 | 
			
		||||
		p.cgen.resetln('memcpy( (& $left), ($etype{$expr}), sizeof( $left ) );')
 | 
			
		||||
	} 
 | 
			
		||||
	else if tok == .left_shift_assign || tok == .righ_shift_assign {
 | 
			
		||||
		if !is_integer_type(p.assigned_type) {
 | 
			
		||||
			p.error_with_token_index( 'cannot use shift operator on non-integer type `$p.assigned_type`', errtok)
 | 
			
		||||
		}
 | 
			
		||||
		if !is_integer_type(expr_type) {
 | 
			
		||||
			p.error_with_token_index( 'cannot use non-integer type `$expr_type` as shift argument', errtok)
 | 
			
		||||
		}
 | 
			
		||||
	} 
 | 
			
		||||
	else if !p.builtin_mod && !p.check_types_no_throw(expr_type, p.assigned_type) {
 | 
			
		||||
		p.error_with_token_index( 'cannot use type `$expr_type` as type `$p.assigned_type` in assignment', errtok)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -2409,6 +2417,9 @@ fn (p mut Parser) expression() string {
 | 
			
		|||
			return 'void'
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			if !is_integer_type(typ) {
 | 
			
		||||
				p.error('cannot use shift operator on non-integer type `$typ`')
 | 
			
		||||
			}
 | 
			
		||||
			p.next()
 | 
			
		||||
			p.gen(' << ')
 | 
			
		||||
			p.check_types(p.expression(), 'integer')
 | 
			
		||||
| 
						 | 
				
			
			@ -2416,6 +2427,9 @@ fn (p mut Parser) expression() string {
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if p.tok == .righ_shift {
 | 
			
		||||
		if !is_integer_type(typ) {
 | 
			
		||||
			p.error('cannot use shift operator on non-integer type `$typ`')
 | 
			
		||||
		}
 | 
			
		||||
		p.next()
 | 
			
		||||
		p.gen(' >> ')
 | 
			
		||||
		p.check_types(p.expression(), 'integer')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,4 +30,40 @@ fn test_shift_operators() {
 | 
			
		|||
	d := u64(1)
 | 
			
		||||
	c = d << i8(63)
 | 
			
		||||
	assert c == 9223372036854775808
 | 
			
		||||
 | 
			
		||||
	// check that shift-assign works with all types
 | 
			
		||||
	// of integers on the right-hand side
 | 
			
		||||
	mut e := 1
 | 
			
		||||
	e <<= i8(i)
 | 
			
		||||
	assert e == b
 | 
			
		||||
	e >>= i8(i)
 | 
			
		||||
	assert e == a
 | 
			
		||||
	e <<= i16(i)
 | 
			
		||||
	assert e == b
 | 
			
		||||
	e >>= i16(i)
 | 
			
		||||
	assert e == a
 | 
			
		||||
	e <<= int(i)
 | 
			
		||||
	assert e == b
 | 
			
		||||
	e >>= int(i)
 | 
			
		||||
	assert e == a
 | 
			
		||||
	e <<= i64(i)
 | 
			
		||||
	assert e == b
 | 
			
		||||
	e >>= i64(i)
 | 
			
		||||
	assert e == a
 | 
			
		||||
	e <<= byte(i)
 | 
			
		||||
	assert e == b
 | 
			
		||||
	e >>= byte(i)
 | 
			
		||||
	assert e == a
 | 
			
		||||
	e <<= u16(i)
 | 
			
		||||
	assert e == b
 | 
			
		||||
	e >>= u16(i)
 | 
			
		||||
	assert e == a
 | 
			
		||||
	e <<= u32(i)
 | 
			
		||||
	assert e == b
 | 
			
		||||
	e >>= u32(i)
 | 
			
		||||
	assert e == a
 | 
			
		||||
	e <<= u64(i)
 | 
			
		||||
	assert e == b
 | 
			
		||||
	e >>= u64(i)
 | 
			
		||||
	assert e == a
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue