diff --git a/compiler/src/prog8/ast/expressions/AstExpressions.kt b/compiler/src/prog8/ast/expressions/AstExpressions.kt index 1f48adc9a..a5cd21e2e 100644 --- a/compiler/src/prog8/ast/expressions/AstExpressions.kt +++ b/compiler/src/prog8/ast/expressions/AstExpressions.kt @@ -43,6 +43,23 @@ sealed class Expression: Node { (other is ArrayIndexedExpression && other.identifier.nameInSource == identifier.nameInSource && other.arrayspec.index isSameAs arrayspec.index) } + is DirectMemoryRead -> { + (other is DirectMemoryRead && other.addressExpression isSameAs addressExpression) + } + is TypecastExpression -> { + (other is TypecastExpression && other.implicit==implicit && other.type==type && other.expression isSameAs expression) + } + is AddressOf -> { + (other is AddressOf && other.identifier.nameInSource == identifier.nameInSource) + } + is RangeExpr -> { + (other is RangeExpr && other.from==from && other.to==to && other.step==step) + } + is FunctionCall -> { + (other is FunctionCall && other.target.nameInSource == target.nameInSource + && other.args.size == args.size + && other.args.zip(args).all { it.first isSameAs it.second } ) + } else -> other==this } } diff --git a/compiler/src/prog8/optimizer/ExpressionSimplifier.kt b/compiler/src/prog8/optimizer/ExpressionSimplifier.kt index cf8739e69..38046e555 100644 --- a/compiler/src/prog8/optimizer/ExpressionSimplifier.kt +++ b/compiler/src/prog8/optimizer/ExpressionSimplifier.kt @@ -40,13 +40,6 @@ internal class ExpressionSimplifier(private val program: Program) : AstWalker() // remove the sub-typecast if its datatype is larger than the outer typecast if(subTypecast.type largerThan typecast.type) { mods += IAstModification.ReplaceNode(typecast.expression, subTypecast.expression, typecast) - } else { - if(subTypecast.type == DataType.UBYTE && typecast.type == DataType.UWORD) { - // (X as ubyte) as uword -> X & 255 - // TODO don't optimize this because the asm code generated by it is worse... -// val and255 = BinaryExpression(subTypecast.expression, "&", NumericLiteralValue.optimalInteger(255, subTypecast.position), subTypecast.position) -// mods += IAstModification.ReplaceNode(typecast, and255, parent) - } } } else { if (typecast.expression.inferType(program).istype(typecast.type)) { diff --git a/compiler/src/prog8/optimizer/StatementOptimizer.kt b/compiler/src/prog8/optimizer/StatementOptimizer.kt index be6794d97..50804e93f 100644 --- a/compiler/src/prog8/optimizer/StatementOptimizer.kt +++ b/compiler/src/prog8/optimizer/StatementOptimizer.kt @@ -368,11 +368,12 @@ internal class StatementOptimizer(private val program: Program, } } } - if(binExpr.right isSameAs assignment.target) { - if(binExpr.operator in setOf("+", "*", "&", "|")) { - // associative operator, swap the operands so that the assignment target is first (left) + + if(binExpr.operator in associativeOperators && binExpr.right isSameAs assignment.target) { + // associative operator, swap the operands so that the assignment target is first (left) + // unless the other operand is the same in which case we don't swap (endless loop!) + if (!(binExpr.left isSameAs binExpr.right)) return listOf(IAstModification.SwapOperands(binExpr)) - } } } diff --git a/examples/test.p8 b/examples/test.p8 index 631dfd690..def5f62be 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -7,18 +7,22 @@ main { sub start() { - ;@($d020) += @($d020) ; TODO fix compiler hang + @($d020) += @($d020) ; TODO fix compiler hang - ubyte A = 10 - @($c00a) = $4a - @($c000+A) ++ ; TODO implement this + ubyte A - c64scr.print_ubhex(@($c00a), true) - c64.CHROUT('\n') - @($c000+A) -- ; TODO implement this + A = 44+A - c64scr.print_ubhex(@($c00a), true) - c64.CHROUT('\n') +; ubyte A = 10 +; @($c00a) = $4a +; @($c000+A) ++ ; TODO implement this +; +; c64scr.print_ubhex(@($c00a), true) +; c64.CHROUT('\n') +; @($c000+A) -- ; TODO implement this +; +; c64scr.print_ubhex(@($c00a), true) +; c64.CHROUT('\n') } }