fix the if not check in ir codegen

This commit is contained in:
Irmen de Jong 2024-11-18 22:33:47 +01:00
parent e0e01f794e
commit b4fb43bc80
3 changed files with 51 additions and 2 deletions

View File

@ -1330,7 +1330,7 @@ class IRCodeGen(
}
private fun translateIfElse(ifElse: PtIfElse): IRCodeChunks {
if((ifElse.condition as? PtPrefix)?.operator=="not")
if((ifElse.condition as? PtPrefix)?.operator=="not" && ifElse.hasElse())
throw AssemblyError("not prefix in ifelse should have been replaced by swapped if-else blocks")
val condition = ifElse.condition as? PtBinaryExpression

View File

@ -401,7 +401,7 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
val prefixedFcall = prefix.expression as? FunctionCallExpression
if (prefixedFcall != null) {
val returnRegs = prefixedFcall.target.targetSubroutine(program)?.asmReturnvaluesRegisters
if(returnRegs!=null && returnRegs.size==1 && returnRegs[0].statusflag!=null) {
if (returnRegs != null && returnRegs.size == 1 && returnRegs[0].statusflag != null) {
return codeForStatusflag(prefixedFcall, returnRegs[0].statusflag!!, true)
}
}

View File

@ -9,6 +9,9 @@ import io.kotest.matchers.string.shouldStartWith
import io.kotest.matchers.types.instanceOf
import prog8.code.ast.PtAssignment
import prog8.code.ast.PtBinaryExpression
import prog8.code.ast.PtFunctionCall
import prog8.code.ast.PtIfElse
import prog8.code.ast.PtPrefix
import prog8.code.ast.PtVariable
import prog8.code.core.DataType
import prog8.code.target.*
@ -514,4 +517,50 @@ main {
compileText(C64Target(), false, src, writeAssembly = true) shouldNotBe null
}
test("if not without else is not swapped") {
val src="""
main {
sub start() {
if not thing()
cx16.r0++
}
sub thing() -> bool {
cx16.r0++
return false
}
}"""
compileText(C64Target(), false, src, writeAssembly = true) shouldNotBe null
val result = compileText(VMTarget(), false, src, writeAssembly = true)!!
val st = result.codegenAst!!.entrypoint()!!.children
st.size shouldBe 2
val ifelse = st[0] as PtIfElse
ifelse.hasElse() shouldBe false
(ifelse.condition as PtPrefix).operator shouldBe "not"
}
test("if not with else is swapped") {
val src="""
main {
sub start() {
if not thing()
cx16.r0++
else
cx16.r1++
}
sub thing() -> bool {
cx16.r0++
return false
}
}"""
compileText(C64Target(), false, src, writeAssembly = true) shouldNotBe null
val result = compileText(VMTarget(), false, src, writeAssembly = true)!!
val st = result.codegenAst!!.entrypoint()!!.children
st.size shouldBe 2
val ifelse = st[0] as PtIfElse
ifelse.hasElse() shouldBe true
ifelse.condition shouldBe instanceOf<PtFunctionCall>()
}
})