fix failing optimization of 'not' in if statements

This commit is contained in:
Irmen de Jong 2024-12-04 19:00:02 +01:00
parent ef192a5778
commit 617ea15c3a
3 changed files with 55 additions and 20 deletions

View File

@ -477,6 +477,14 @@ private fun optimizeAst(program: Program, compilerOptions: CompilationOptions, e
program.constantFold(errors, compilerOptions) // because simplified statements and expressions can result in more constants that can be folded away program.constantFold(errors, compilerOptions) // because simplified statements and expressions can result in more constants that can be folded away
} }
if(errors.noErrors()) {
// certain optimization steps could have introduced a "not" in an if statement, postprocess those again.
var changer = NotExpressionAndIfComparisonExprChanger(program, errors, compilerOptions.compTarget)
changer.visit(program)
if(errors.noErrors())
changer.applyModifications()
}
errors.report() errors.report()
} }

View File

@ -1126,4 +1126,35 @@ other {
compileText(VMTarget(), true, src, writeAssembly = true) shouldNotBe null compileText(VMTarget(), true, src, writeAssembly = true) shouldNotBe null
compileText(C64Target(), true, src, writeAssembly = true) shouldNotBe null compileText(C64Target(), true, src, writeAssembly = true) shouldNotBe null
} }
test("if-else should not have 'not' in the condition even after optimization steps") {
val src="""
main {
sub start() {
if (cx16.r0 & 1) as bool == false
cx16.r1++
else
cx16.r2++
if (cx16.r0 & 1) as bool == true
cx16.r1++
else
cx16.r2++
if not((cx16.r0 & 1) as bool)
cx16.r1++
else
cx16.r2++
if (cx16.r0 & 1) as bool
cx16.r1++
else
cx16.r2++
}
}"""
compileText(VMTarget(), false, src, writeAssembly = false) shouldNotBe null
compileText(C64Target(), false, src, writeAssembly = false) shouldNotBe null
compileText(VMTarget(), true, src, writeAssembly = true) shouldNotBe null
compileText(C64Target(), true, src, writeAssembly = true) shouldNotBe null
}
}) })

View File

@ -1,30 +1,26 @@
%import textio %import textio
%import diskio
%option no_sysinit
%zeropage basicsafe %zeropage basicsafe
main { main {
sub start() { sub start() {
if (cx16.r0 & 1) as bool == false
cx16.r1++
else
cx16.r2++
if diskio.f_open("lines.txt") { if (cx16.r0 & 1) as bool == true
defer diskio.f_close() cx16.r1++
else
cx16.r2++
if diskio.f_open_w("@:copy.txt") { if not((cx16.r0 & 1) as bool)
defer diskio.f_close_w() cx16.r1++
else
cx16.r2++
str buffer = " "*80 if (cx16.r0 & 1) as bool
ubyte length, status cx16.r1++
do { else
length, status = diskio.f_readline(&buffer) cx16.r2++
cbm.CLRCHN()
txt.print_uw(length)
txt.nl()
if length!=0 {
if not diskio.f_write(buffer, length)
return
}
} until status!=0
}
}
} }
} }