improved bool type checking

This commit is contained in:
Irmen de Jong 2022-07-08 22:59:35 +02:00
parent 211e2bb37a
commit 6a57337a68
2 changed files with 9 additions and 9 deletions

View File

@ -919,12 +919,12 @@ internal class AstChecker(private val program: Program,
errors.err("can't use boolean operand with this comparison operator", expr.position) errors.err("can't use boolean operand with this comparison operator", expr.position)
} }
if(expr.operator in setOf("-", "*", "/", "%") && (leftDt==DataType.BOOL || (expr.left as? TypecastExpression)?.expression?.inferType(program)?.istype(DataType.BOOL)==true)) { if(expr.operator in setOf("-", "*", "/", "%") && (leftDt==DataType.BOOL || (expr.left as? TypecastExpression)?.expression?.inferType(program)?.istype(DataType.BOOL)==true)) {
errors.err("can't use boolean operand with this operator", expr.left.position) errors.err("can't use boolean operand with this operator ${expr.operator}", expr.left.position)
} }
if(expr.operator=="+" && (leftDt==DataType.BOOL || (expr.left as? TypecastExpression)?.expression?.inferType(program)?.istype(DataType.BOOL)==true)) { if(expr.operator=="+" && (leftDt==DataType.BOOL || (expr.left as? TypecastExpression)?.expression?.inferType(program)?.istype(DataType.BOOL)==true)) {
val rightNum = expr.right.constValue(program)?.number ?: 0.0 val rightNum = expr.right.constValue(program)?.number ?: 0.0
if(rightNum > 1.0) if(rightNum > 1.0)
errors.err("can't use boolean operand with this operator", expr.left.position) errors.err("can't use boolean operand with this operator ${expr.operator}", expr.left.position)
} }
if(expr.operator == "==" || expr.operator == "!=") { if(expr.operator == "==" || expr.operator == "!=") {
val leftNum = expr.left.constValue(program)?.number ?: 0.0 val leftNum = expr.left.constValue(program)?.number ?: 0.0
@ -934,7 +934,7 @@ internal class AstChecker(private val program: Program,
} }
} }
if((expr.operator == "/" || expr.operator == "%") && ( rightDt==DataType.BOOL || (expr.right as? TypecastExpression)?.expression?.inferType(program)?.istype(DataType.BOOL)==true)) { if((expr.operator == "/" || expr.operator == "%") && ( rightDt==DataType.BOOL || (expr.right as? TypecastExpression)?.expression?.inferType(program)?.istype(DataType.BOOL)==true)) {
errors.err("can't use boolean operand with this operator", expr.right.position) errors.err("can't use boolean operand with this operator ${expr.operator}", expr.right.position)
} }
} }
} }
@ -1170,7 +1170,7 @@ internal class AstChecker(private val program: Program,
// else if(postIncrDecr.target.memoryAddress != null) { } // a memory location can always be ++/-- // else if(postIncrDecr.target.memoryAddress != null) { } // a memory location can always be ++/--
if(postIncrDecr.target.inferType(program) istype DataType.BOOL) { if(postIncrDecr.target.inferType(program) istype DataType.BOOL) {
errors.err("can't use boolean operand with this operator", postIncrDecr.position) errors.err("can't use boolean operand with this operator ${postIncrDecr.operator}", postIncrDecr.position)
} }
super.visit(postIncrDecr) super.visit(postIncrDecr)

View File

@ -743,7 +743,7 @@ class TestProg8Parser: FunSpec( {
main { main {
ubyte bb ubyte bb
uword ww uword ww
ubyte bb2 = (3+bb) or (3333+ww) ; expression combining ubyte and uword bool bb2 = (3+bb) or (3333+ww) ; expression combining ubyte and uword
} }
""") """)
val module = parseModule(src) val module = parseModule(src)
@ -755,7 +755,7 @@ class TestProg8Parser: FunSpec( {
expr.operator shouldBe "or" expr.operator shouldBe "or"
expr.left.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UBYTE expr.left.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UBYTE
expr.right.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UWORD expr.right.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UWORD
expr.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UBYTE expr.inferType(program).getOrElse { fail("dt") } shouldBe DataType.BOOL
} }
test("inferred type for typecasted expressions with logical operators") { test("inferred type for typecasted expressions with logical operators") {
@ -779,15 +779,15 @@ class TestProg8Parser: FunSpec( {
val bb2 = (stmts[4] as VarDecl).value as BinaryExpression val bb2 = (stmts[4] as VarDecl).value as BinaryExpression
val zz2 = (stmts[5] as VarDecl).value as BinaryExpression val zz2 = (stmts[5] as VarDecl).value as BinaryExpression
qq.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UWORD qq.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UWORD
zz.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UBYTE zz.inferType(program).getOrElse { fail("dt") } shouldBe DataType.BOOL
bb2.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UBYTE bb2.inferType(program).getOrElse { fail("dt") } shouldBe DataType.BOOL
zz2.operator shouldBe "or" zz2.operator shouldBe "or"
val left = zz2.left as TypecastExpression val left = zz2.left as TypecastExpression
val right = zz2.right as PrefixExpression val right = zz2.right as PrefixExpression
left.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UWORD left.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UWORD
right.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UWORD right.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UWORD
zz2.inferType(program).getOrElse { fail("dt") } shouldBe DataType.UBYTE // 'or' causes UBYTE result zz2.inferType(program).getOrElse { fail("dt") } shouldBe DataType.BOOL
} }
test("type cast from byte to ubyte as desired target type") { test("type cast from byte to ubyte as desired target type") {