parser: make let shift operators work with all types

pull/2660/head
Alvydas Vitkauskas 2019-11-06 00:02:50 +02:00 committed by Alexander Medvednikov
parent 1b5f724df0
commit 3080959084
5 changed files with 56 additions and 10 deletions

View File

@ -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) {

View File

@ -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] {

View File

@ -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 {

View File

@ -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
}

View File

@ -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)
}