checker: allow &=,|=,^=,%= on an integer number type aliases

pull/6560/head
Delyan Angelov 2020-10-04 15:29:05 +03:00
parent 628b136e85
commit 0c174104fc
3 changed files with 58 additions and 4 deletions

View File

@ -2022,19 +2022,23 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
}
}
.mult_assign, .div_assign {
if !left_sym.is_number() {
if !left_sym.is_number() &&
!c.table.get_final_type_symbol(left_type_unwrapped).is_int() {
c.error('operator $assign_stmt.op.str() not defined on left operand type `$left_sym.source_name`',
left.position())
} else if !right_sym.is_number() {
} else if !right_sym.is_number() &&
!c.table.get_final_type_symbol(left_type_unwrapped).is_int() {
c.error('operator $assign_stmt.op.str() not defined on right operand type `$right_sym.source_name`',
right.position())
}
}
.and_assign, .or_assign, .xor_assign, .mod_assign, .left_shift_assign, .right_shift_assign {
if !left_sym.is_int() {
if !left_sym.is_int() &&
!c.table.get_final_type_symbol(left_type_unwrapped).is_int() {
c.error('operator $assign_stmt.op.str() not defined on left operand type `$left_sym.source_name`',
left.position())
} else if !right_sym.is_int() {
} else if !right_sym.is_int() &&
!c.table.get_final_type_symbol(right_type_unwrapped).is_int() {
c.error('operator $assign_stmt.op.str() not defined on right operand type `$right_sym.source_name`',
right.position())
}

View File

@ -0,0 +1,18 @@
// see https://discordapp.com/channels/592103645835821068/592114487759470596/762271917293043762
const (
steamid_id_shift = 2
steamid_id_mask = 0x04
)
type SteamId = u64
fn (mut s SteamId) set_id(i u32) {
(*s) &= ~steamid_id_mask
(*s) |= ((u64(i) << steamid_id_shift) & steamid_id_mask)
}
fn test_bitops_work_with_type_aliases() {
mut x := SteamId(123)
x.set_id(5)
assert 'x: $x' == 'x: 127'
}

View File

@ -0,0 +1,32 @@
// see: https://discordapp.com/channels/592103645835821068/592114487759470596/762270244566728704
enum WireType {
varint = 0
_64bit = 1
length_prefixed = 2
_32bit = 5
}
fn pack_wire_type(w WireType) byte {
return byte(w)
}
fn test_casting_an_enum_to_byte() {
x := WireType.length_prefixed
y := pack_wire_type(x)
assert 'x: $x' == 'x: length_prefixed'
assert 'y: $y.hex()' == 'y: 02'
}
//
fn test_casting_a_float_to_byte() {
x := 1.23
b := byte(x)
assert 'x: $x | b: $b.hex()' == 'x: 1.23 | b: 01'
}
fn test_casting_an_int_to_byte() {
x := 12
b := byte(x)
assert 'x: $x | b: $b.hex()' == 'x: 12 | b: 0c'
}