diff --git a/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt b/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt index e8294a4c5..2df64e661 100644 --- a/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt +++ b/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt @@ -54,40 +54,6 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() { return mods } - override fun before(expr: PrefixExpression, parent: Node): Iterable { - if (expr.operator == "+") { - // +X --> X - return listOf(IAstModification.ReplaceNode(expr, expr.expression, parent)) - } else if (expr.operator == "not") { - when(expr.expression) { - is PrefixExpression -> { - // NOT(NOT(...)) -> ... - val pe = expr.expression as PrefixExpression - if(pe.operator == "not") - return listOf(IAstModification.ReplaceNode(expr, pe.expression, parent)) - } - is BinaryExpression -> { - // NOT (xxxx) -> invert the xxxx - val be = expr.expression as BinaryExpression - val newExpr = when (be.operator) { - "<" -> BinaryExpression(be.left, ">=", be.right, be.position) - ">" -> BinaryExpression(be.left, "<=", be.right, be.position) - "<=" -> BinaryExpression(be.left, ">", be.right, be.position) - ">=" -> BinaryExpression(be.left, "<", be.right, be.position) - "==" -> BinaryExpression(be.left, "!=", be.right, be.position) - "!=" -> BinaryExpression(be.left, "==", be.right, be.position) - else -> null - } - - if (newExpr != null) - return listOf(IAstModification.ReplaceNode(expr, newExpr, parent)) - } - else -> return noModifications - } - } - return noModifications - } - override fun after(expr: BinaryExpression, parent: Node): Iterable { val leftVal = expr.left.constValue(program) val rightVal = expr.right.constValue(program) diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index fbecabc74..783ff6dc5 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -265,10 +265,10 @@ private fun processAst(program: Program, errors: IErrorReporter, compilerOptions program.charLiteralsToUByteLiterals(compilerOptions.compTarget) program.constantFold(errors, compilerOptions.compTarget) errors.report() - program.reorderStatements(errors, compilerOptions) - errors.report() program.desugaring(errors) errors.report() + program.reorderStatements(errors, compilerOptions) + errors.report() program.addTypecasts(errors, compilerOptions) errors.report() program.variousCleanups(program, errors) diff --git a/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt b/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt index ad817ec35..e77220103 100644 --- a/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt +++ b/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt @@ -92,24 +92,25 @@ if not CONDITION /* while CONDITION { STUFF } ==> - goto _whilecond _whileloop: + if NOT CONDITION goto _after STUFF -_whilecond: - if CONDITION goto _whileloop + goto _whileloop +_after: */ val pos = whileLoop.position - val condLabel = makeLabel("whilecond", pos) val loopLabel = makeLabel("whileloop", pos) + val afterLabel = makeLabel("afterwhile", pos) + val notCondition = PrefixExpression("not", whileLoop.condition, pos) val replacement = AnonymousScope(mutableListOf( - jumpLabel(condLabel), loopLabel, - whileLoop.body, - condLabel, - IfStatement(whileLoop.condition, - AnonymousScope(mutableListOf(jumpLabel(loopLabel)), pos), + IfStatement(notCondition, + AnonymousScope(mutableListOf(jumpLabel(afterLabel)), pos), AnonymousScope(mutableListOf(), pos), - pos) + pos), + whileLoop.body, + jumpLabel(loopLabel), + afterLabel ), pos) return listOf(IAstModification.ReplaceNode(whileLoop, replacement, parent)) } diff --git a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt index 5b329737b..a32afa87c 100644 --- a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt +++ b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt @@ -66,4 +66,37 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter) return noModifications } + + override fun after(expr: PrefixExpression, parent: Node): Iterable { + if(expr.operator=="+") { + // +X --> X + return listOf(IAstModification.ReplaceNode(expr, expr.expression, parent)) + } + if(expr.operator=="not") { + val nestedPrefix = expr.expression as? PrefixExpression + if(nestedPrefix!=null && nestedPrefix.operator=="not") { + // NOT NOT X --> X + return listOf(IAstModification.ReplaceNode(expr, nestedPrefix.expression, parent)) + } + val comparison = expr.expression as? BinaryExpression + if (comparison != null) { + // NOT COMPARISON ==> inverted COMPARISON + val invertedOperator = + when (comparison.operator) { + "==" -> "!=" + "!=" -> "==" + "<" -> ">=" + ">" -> "<=" + "<=" -> ">" + ">=" -> "<" + else -> null + } + if (invertedOperator != null) { + comparison.operator = invertedOperator + return listOf(IAstModification.ReplaceNode(expr, comparison, parent)) + } + } + } + return noModifications + } } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 73c0469e7..cf9074baa 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,6 @@ TODO For next compiler release (7.6) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -change desugar of while loop so that no initial jump is required optimize ifs containing only a jump: reuse old code from AsmGen translateComparisonExpressionWithJumpIfFalse?