diff --git a/vlib/bitfield/bitfield.v b/vlib/bitfield/bitfield.v index d1ac91f9f6..85cd4b33c2 100644 --- a/vlib/bitfield/bitfield.v +++ b/vlib/bitfield/bitfield.v @@ -34,7 +34,7 @@ fn bitslot(size int) int { } fn bitget(instance BitField, bitnr int) int { - return (instance.field[bitslot(bitnr)] >> u32(bitnr % SLOT_SIZE)) & 1 + return (instance.field[bitslot(bitnr)] >> (bitnr % SLOT_SIZE)) & u32(1) } fn bitset(instance mut BitField, bitnr int) { diff --git a/vlib/compiler/parser.v b/vlib/compiler/parser.v index 0ccef455cc..c4b4e69fff 100644 --- a/vlib/compiler/parser.v +++ b/vlib/compiler/parser.v @@ -2411,15 +2411,15 @@ fn (p mut Parser) expression() string { else { p.next() p.gen(' << ') - p.check_types(p.expression(), typ) - return 'int' + p.check_types(p.expression(), 'integer') + return typ } } if p.tok == .righ_shift { p.next() p.gen(' >> ') - p.check_types(p.expression(), typ) - return 'int' + p.check_types(p.expression(), 'integer') + return typ } // + - | ^ for p.tok in [.plus, .minus, .pipe, .amp, .xor] { diff --git a/vlib/compiler/table.v b/vlib/compiler/table.v index ad72137490..aaaa300f09 100644 --- a/vlib/compiler/table.v +++ b/vlib/compiler/table.v @@ -201,13 +201,17 @@ pub fn (t &Table) debug_fns() string { // fn (types array_Type) print_to_file(f string) { // } const ( - number_types = ['number', 'int', 'i8', 'i16', 'u16', 'u32', 'byte', 'i64', 'u64', 'f32', 'f64'] - float_types = ['f32', 'f64'] + integer_types = ['int', 'i8', 'byte', 'i16', 'u16', 'u32', 'i64', 'u64'] + float_types = ['f32', 'f64'] reserved_type_param_names = ['R', 'S', 'T', 'U', 'W'] ) fn is_number_type(typ string) bool { - return typ in number_types + return typ in integer_types || typ in float_types +} + +fn is_integer_type(typ string) bool { + return typ in integer_types } fn is_float_type(typ string) bool { @@ -671,6 +675,15 @@ fn (p mut Parser) check_types2(got_, expected_ string, throw bool) bool { if is_number_type(got) && is_number_type(expected) && p.is_const_literal { return true } + + if expected == 'integer' { + if is_integer_type(got) { + return true + } else { + p.error('expected type `$expected`, but got `$got`') + } + } + expected = expected.replace('*', '') got = got.replace('*', '') if got != expected { diff --git a/vlib/compiler/tests/shift_test.v b/vlib/compiler/tests/shift_test.v new file mode 100644 index 0000000000..5d3460afdd --- /dev/null +++ b/vlib/compiler/tests/shift_test.v @@ -0,0 +1,33 @@ +fn test_shift_operators() { + + // check that shift works with all integer types + // as the right-hand side operand + a := 1 + b := 1024 + i := 10 + + assert b == a << i8(i) + assert b == a << byte(i) + assert b == a << i16(i) + assert b == a << u16(i) + assert b == a << int(i) + assert b == a << u32(i) + assert b == a << i64(i) + assert b == a << u64(i) + + assert a == b >> i8(i) + assert a == b >> byte(i) + assert a == b >> i16(i) + assert a == b >> u16(i) + assert a == b >> int(i) + assert a == b >> u32(i) + assert a == b >> i64(i) + assert a == b >> u64(i) + + // check that shift operation result type is + // the same as the type of the left-hand side operand + mut c := u64(0) + d := u64(1) + c = d << i8(63) + assert c == 9223372036854775808 +} \ No newline at end of file diff --git a/vlib/hash/crc32/crc32.v b/vlib/hash/crc32/crc32.v index 944262b76e..669486e92c 100644 --- a/vlib/hash/crc32/crc32.v +++ b/vlib/hash/crc32/crc32.v @@ -27,8 +27,8 @@ fn(c mut Crc32) generate_table(poly int) { for i := 0; i < 256; i++ { mut crc := u32(i) for j := 0; j < 8; j++ { - if crc&u32(1) == u32(1) { - crc = u32((crc >> u32(1)) ^ poly) + if crc & u32(1) == u32(1) { + crc = (crc >> 1) ^ u32(poly) } else { crc >>= u32(1) }