diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 4fd601a86..1c4250b39 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -747,8 +747,7 @@ internal class AstChecker(private val program: Program, else errors.err("invalid assignment value", assignment.value.position) } else { - val dt = targetDatatype.getOrUndef() - checkAssignmentCompatible(dt, sourceDatatype.getOrUndef(), assignment.value.position) + checkAssignmentCompatible(targetDatatype.getOrUndef(),sourceDatatype.getOrUndef(), assignment.value, assignment.value.position) } } } @@ -2261,6 +2260,7 @@ internal class AstChecker(private val program: Program, private fun checkAssignmentCompatible(targetDatatype: DataType, sourceDatatype: DataType, + sourceValue: Expression, position: Position) : Boolean { if (targetDatatype.isArray) { @@ -2297,6 +2297,7 @@ internal class AstChecker(private val program: Program, if(result) return true + val sourceIsBitwiseOperatorExpression = (sourceValue as? BinaryExpression)?.operator in BitwiseOperators if(sourceDatatype.isWord && targetDatatype.isByte) errors.err("cannot assign word to byte, maybe use msb() or lsb()", position) else if(sourceDatatype.isFloat&& targetDatatype.isInteger) @@ -2304,6 +2305,9 @@ internal class AstChecker(private val program: Program, else if(targetDatatype.isUnsignedWord && sourceDatatype.isPassByRef) { // this is allowed: a pass-by-reference datatype into an uword (pointer value). } + else if(sourceIsBitwiseOperatorExpression && targetDatatype.equalsSize(sourceDatatype)) { + // this is allowed: bitwise operation between different types as long as they're the same size. + } else if (targetDatatype.isPointer) { if(sourceDatatype.isPointer) { if(!(sourceDatatype isAssignableTo targetDatatype)) diff --git a/compiler/test/TestTypecasts.kt b/compiler/test/TestTypecasts.kt index 6f6e54c4d..c6341a2db 100644 --- a/compiler/test/TestTypecasts.kt +++ b/compiler/test/TestTypecasts.kt @@ -976,32 +976,32 @@ main { BinaryExpression.commonDatatype(DataType.WORD, DataType.pointer(BaseDataType.BOOL), null, null).first shouldBe DataType.pointer(BaseDataType.BOOL) } - xtest("bitwise operator on signed values") { + test("bitwise operator on signed values") { val src = """ main { sub start() { word[5] xpos - xpos[4] &= ${'$'}fff8 ; TODO fix type error - xpos[4] &= ${'$'}fff8 as word ; TODO fix type error - xpos[4] = xpos[4] & ${'$'}fff8 ; TODO fix type error - xpos[4] = xpos[4] & ${'$'}fff8 as word ; this one works, oddly enough + xpos[4] &= ${'$'}fff8 + xpos[4] &= ${'$'}fff8 as word + xpos[4] = xpos[4] & ${'$'}fff8 + xpos[4] = xpos[4] & ${'$'}fff8 as word - xpos[4] &= $7000 ; TODO fix type error - xpos[4] &= $7000 as word ; TODO fix type error - xpos[4] = xpos[4] & $7000 ; TODO fix type error - xpos[4] = xpos[4] & $7000 as word ; this one works, oddly enough + xpos[4] &= $7000 + xpos[4] &= $7000 as word + xpos[4] = xpos[4] & $7000 + xpos[4] = xpos[4] & $7000 as word - xpos[4] |= $7000 ; TODO fix type error - xpos[4] |= $7000 as word ; TODO fix type error - xpos[4] = xpos[4] | $7000 ; TODO fix type error - xpos[4] = xpos[4] | $7000 as word ; this one works, oddly enough + xpos[4] |= $7000 + xpos[4] |= $7000 as word + xpos[4] = xpos[4] | $7000 + xpos[4] = xpos[4] | $7000 as word ; the error doesn't occur with other operators: xpos[4] += $7000 xpos[4] += $7000 as word xpos[4] = xpos[4] + $7000 - xpos[4] = xpos[4] + $7000 as word ; this one works, oddly enough + xpos[4] = xpos[4] + $7000 as word } }"""