From 563122ac92b87ff1372b676446cfb0d69903953c Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Fri, 15 Mar 2019 23:34:15 +0100 Subject: [PATCH] stricter argument check for boolean operator --- compiler/src/prog8/ast/AstChecker.kt | 15 +++++++++++++-- examples/test.p8 | 27 ++++----------------------- 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/compiler/src/prog8/ast/AstChecker.kt b/compiler/src/prog8/ast/AstChecker.kt index 4492b43ca..f86f14b8c 100644 --- a/compiler/src/prog8/ast/AstChecker.kt +++ b/compiler/src/prog8/ast/AstChecker.kt @@ -695,12 +695,23 @@ private class AstChecker(private val namespace: INameScope, checkResult.add(ExpressionError("remainder can only be used on unsigned integer operands", expr.right.position)) } } - "and", "or", "xor", "&", "|", "^" -> { + "and", "or", "xor" -> { + // only integer numeric operands accepted, and if literal constants, only boolean values accepted (0 or 1) + val rightDt = expr.right.resultingDatatype(namespace, heap) + val leftDt = expr.left.resultingDatatype(namespace, heap) + if(leftDt !in IntegerDatatypes || rightDt !in IntegerDatatypes) + checkResult.add(ExpressionError("logical operator can only be used on boolean operands", expr.right.position)) + val constLeft = expr.left.constValue(namespace, heap) + val constRight = expr.right.constValue(namespace, heap) + if(constLeft!=null && constLeft.asIntegerValue !in 0..1 || constRight!=null && constRight.asIntegerValue !in 0..1) + checkResult.add(ExpressionError("const literal argument of logical operator must be boolean (0 or 1)", expr.position)) + } + "&", "|", "^" -> { // only integer numeric operands accepted val rightDt = expr.right.resultingDatatype(namespace, heap) val leftDt = expr.left.resultingDatatype(namespace, heap) if(leftDt !in IntegerDatatypes || rightDt !in IntegerDatatypes) - checkResult.add(ExpressionError("logical or bitwise operator can only be used on integer operands", expr.right.position)) + checkResult.add(ExpressionError("bitwise operator can only be used on integer operands", expr.right.position)) } } diff --git a/examples/test.p8 b/examples/test.p8 index 0159e7524..1054ac3ad 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -4,31 +4,12 @@ ~ main { ; @todo see problem in looplabelproblem.p8 - ; @todo compiler error for using literal values other than 0 or 1 with boolean expressions sub start() { - str s1 = "hello\u0000abcd12345" - str_s s2 = "hellothere\u0000bcde" - - c64scr.print(s1) - c64.CHROUT('\n') - c64scr.print_ub(len(s1)) - c64.CHROUT('\n') - c64scr.print_ub(strlen(s1)) - c64.CHROUT('\n') - s1[2]=0 - c64scr.print_ub(strlen(s1)) - c64.CHROUT('\n') - c64.CHROUT('\n') - - c64scr.print_ub(len(s2)) - c64.CHROUT('\n') - c64scr.print_ub(strlen(s2)) - c64.CHROUT('\n') - s2[7]=0 - c64scr.print_ub(strlen(s2)) - c64.CHROUT('\n') - + ubyte ub + A = 123 or 44 + Y = A or 1 + ub = ub or 1 } }