diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index b86b41b74..4d3d1d528 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -294,6 +294,7 @@ internal class AssignmentAsmGen(private val program: Program, "+" -> {} "-" -> augmentableAsmGen.inplaceNegate(assign, true) "~" -> augmentableAsmGen.inplaceInvert(assign) + "not" -> throw AssemblyError("not should have been replaced in the Ast by ==0") else -> throw AssemblyError("invalid prefix operator") } } else { diff --git a/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt b/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt index 86b9d0b24..674a94ff4 100644 --- a/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt +++ b/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt @@ -231,6 +231,18 @@ class ExpressionSimplifier(private val program: Program, } } + if(leftDt==DataType.BOOL) { + // optimize boolean constant comparisons +// if(expr.operator=="==" && rightVal?.number==0.0) +// return listOf(IAstModification.ReplaceNode(expr, PrefixExpression("not", expr.left, expr.position), parent)) +// if(expr.operator=="!=" && rightVal?.number==1.0) +// return listOf(IAstModification.ReplaceNode(expr, PrefixExpression("not", expr.left, expr.position), parent)) + if(expr.operator=="==" && rightVal?.number==1.0) + return listOf(IAstModification.ReplaceNode(expr, expr.left, parent)) + if(expr.operator=="!=" && rightVal?.number==0.0) + return listOf(IAstModification.ReplaceNode(expr, expr.left, parent)) + } + // simplify when a term is constant and directly determines the outcome val constFalse = NumericLiteral.fromBoolean(false, expr.position) val newExpr: Expression? = when (expr.operator) { diff --git a/compiler/src/prog8/compiler/astprocessing/NotExpressionAndIfComparisonExprChanger.kt b/compiler/src/prog8/compiler/astprocessing/NotExpressionAndIfComparisonExprChanger.kt index 940d0648c..99ec7c415 100644 --- a/compiler/src/prog8/compiler/astprocessing/NotExpressionAndIfComparisonExprChanger.kt +++ b/compiler/src/prog8/compiler/astprocessing/NotExpressionAndIfComparisonExprChanger.kt @@ -40,6 +40,13 @@ internal class NotExpressionAndIfComparisonExprChanger(val program: Program, val } } } + + if(expr.operator=="^" && expr.left.inferType(program) istype DataType.BOOL && expr.right.constValue(program)?.number == 1.0) { + // boolean ^ 1 --> not boolean + val notExpr = PrefixExpression("not", expr.left, expr.position) + return listOf(IAstModification.ReplaceNode(expr, notExpr, parent)) + } + return noModifications } diff --git a/compiler/test/TestTypecasts.kt b/compiler/test/TestTypecasts.kt index 5956eb533..3f6673323 100644 --- a/compiler/test/TestTypecasts.kt +++ b/compiler/test/TestTypecasts.kt @@ -368,16 +368,16 @@ main { txt.print("const inv 255: ") txt.print_ub(~ 0) txt.nl() - bvalue = 129 - txt.print("bitwise inv 126: ") - bvalue = ~ bvalue - txt.print_ub(bvalue) - txt.nl() - bvalue = 0 - txt.print("bitwise inv 255: ") - bvalue = ~ bvalue - txt.print_ub(bvalue) - txt.nl() + ; bvalue = 129 + ; txt.print("bitwise inv 126: ") + ; bvalue = ~ bvalue + ; txt.print_ub(bvalue) + ; txt.nl() + ; bvalue = 0 + ; txt.print("bitwise inv 255: ") + ; bvalue = ~ bvalue + ; txt.print_ub(bvalue) + ; txt.nl() txt.print("bitwise or 14: ") txt.print_ub(ub1 | ub2 | ub3 | ub4) @@ -397,12 +397,12 @@ main { txt.print("bitwise xor 6: ") txt.print_ub(ub1 ^ ub2 ^ ub3 ^ 8) txt.nl() - txt.print("bitwise not 247: ") - txt.print_ub(~ub3) - txt.nl() - txt.print("bitwise not 255: ") - txt.print_ub(~ub4) - txt.nl() + ;txt.print("bitwise not 247: ") + ;txt.print_ub(~ub3) + ;txt.nl() + ;txt.print("bitwise not 255: ") + ;txt.print_ub(~ub4) + ;txt.nl() txt.print("not 0: ") bvalue = 3 * (ub4 | not (ub3 | ub3 | ub3)) diff --git a/docs/source/todo.rst b/docs/source/todo.rst index bb39f23f1..d9b426c7b 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,12 +3,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- make sure bool value is always 0 or 1 (all casts should convert, or actually, bool!=0 comparison should return 0 or 1), then: - - ast rewrite bool=bool^1 into bool=not bool - - should solve: bool bb = not bb -> larger code than bool bb ^= 1 - -- check that bool==0 / bool==1 / bool!=0 / bool != 1 are optimized away - ...