checker: ambiguous expression notice for & << >>, similar to && ||

This commit is contained in:
Alexander Medvednikov 2024-05-07 20:38:28 +03:00
parent 5e7d8cd99a
commit 6cc096a4b3
3 changed files with 20 additions and 8 deletions

View file

@ -30,9 +30,9 @@ fn encode_from_buffer(dest &u8, src &u8, src_len int) int {
unsafe {
val := u32(d[si + 0]) << 16 | u32(d[si + 1]) << 8 | u32(d[si + 2])
b[di + 0] = etable[val >> 18 & 0x3F]
b[di + 1] = etable[val >> 12 & 0x3F]
b[di + 2] = etable[val >> 6 & 0x3F]
b[di + 0] = etable[(val >> 18) & 0x3F]
b[di + 1] = etable[(val >> 12) & 0x3F]
b[di + 2] = etable[(val >> 6) & 0x3F]
b[di + 3] = etable[val & 0x3F]
}
si += 3
@ -51,12 +51,12 @@ fn encode_from_buffer(dest &u8, src &u8, src_len int) int {
val |= u32(d[si + 1]) << 8
}
b[di + 0] = etable[val >> 18 & 0x3F]
b[di + 1] = etable[val >> 12 & 0x3F]
b[di + 0] = etable[(val >> 18) & 0x3F]
b[di + 1] = etable[(val >> 12) & 0x3F]
match remain {
2 {
b[di + 2] = etable[val >> 6 & 0x3F]
b[di + 2] = etable[(val >> 6) & 0x3F]
b[di + 3] = u8(`=`)
}
1 {

View file

@ -44,14 +44,14 @@ pub fn bg_rgb(r int, g int, b int, msg string) string {
// For example, `rgb(255, 'hi')` returns the `'hi'` string in
// blue color, which is `(0, 0, 255)` in RGB.
pub fn hex(hex int, msg string) string {
return format_rgb(hex >> 16, hex >> 8 & 0xFF, hex & 0xFF, msg, '38', '39')
return format_rgb(hex >> 16, (hex >> 8) & 0xFF, hex & 0xFF, msg, '38', '39')
}
// hex returns the `msg` with the background in the specified `hex` color
// For example, `bg_rgb(255, 'hi')` returns the `'hi'` string in
// a background of blue color, which is `(0, 0, 255)` in RGB.
pub fn bg_hex(hex int, msg string) string {
return format_rgb(hex >> 16, hex >> 8 & 0xFF, hex & 0xFF, msg, '48', '49')
return format_rgb(hex >> 16, (hex >> 8) & 0xFF, hex & 0xFF, msg, '48', '49')
}
// reset resets all formatting for `msg`.

View file

@ -743,6 +743,18 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
}
else {}
}
// Do an ambiguous expression check for << >> and &, since they all have the same precedence (unlike in C)
if !c.is_builtin_mod && node.op in [.amp, .left_shift, .right_shift] {
if !c.mod.starts_with('math') { // TODO fix all warnings in math
if mut node.left is ast.InfixExpr {
if node.left.op != node.op && node.left.op in [.amp, .left_shift, .right_shift] {
// for example: `(a << b) & c` instead of `a << b & c`
c.note('ambiguous expression. use `()` to ensure correct order of operations',
node.pos)
}
}
}
}
// TODO: Absorb this block into the above single side check block to accelerate.
if left_type == ast.bool_type && node.op !in [.eq, .ne, .logical_or, .and] {
c.error('bool types only have the following operators defined: `==`, `!=`, `||`, and `&&`',