allow boolean when conditions, optimize into a regular if

This commit is contained in:
Irmen de Jong 2023-07-11 21:33:29 +02:00
parent 15ee90e99c
commit b8284a147d
5 changed files with 80 additions and 30 deletions

View File

@ -391,4 +391,47 @@ class StatementOptimizer(private val program: Program,
else else
noModifications noModifications
} }
override fun after(whenStmt: When, parent: Node): Iterable<IAstModification> {
fun replaceWithIf(condition: Expression, trueBlock: AnonymousScope, elseBlock: AnonymousScope?): List<IAstModification> {
val ifStmt = IfElse(condition, trueBlock, elseBlock ?: AnonymousScope(mutableListOf(), whenStmt.position), whenStmt.position)
errors.warn("for boolean condition a normal if statement is preferred", whenStmt.position)
return listOf(IAstModification.ReplaceNode(whenStmt, ifStmt, parent))
}
if(whenStmt.condition.inferType(program).isBool) {
if(whenStmt.choices.all { it.values?.size==1 }) {
if (whenStmt.choices.all { it.values!!.single().constValue(program)!!.number in arrayOf(0.0, 1.0) }) {
// it's a when statement on booleans that can just be replaced by an if or if..else.
if (whenStmt.choices.size == 1) {
return if(whenStmt.choices[0].values!![0].constValue(program)!!.number==1.0) {
replaceWithIf(whenStmt.condition, whenStmt.choices[0].statements, null)
} else {
val notCondition = BinaryExpression(whenStmt.condition, "==", NumericLiteral(DataType.UBYTE, 0.0, whenStmt.condition.position), whenStmt.condition.position)
replaceWithIf(notCondition, whenStmt.choices[0].statements, null)
}
} else if (whenStmt.choices.size == 2) {
var trueBlock: AnonymousScope? = null
var elseBlock: AnonymousScope? = null
if(whenStmt.choices[0].values!![0].constValue(program)!!.number==1.0) {
trueBlock = whenStmt.choices[0].statements
} else {
elseBlock = whenStmt.choices[0].statements
}
if(whenStmt.choices[1].values!![0].constValue(program)!!.number==1.0) {
trueBlock = whenStmt.choices[1].statements
} else {
elseBlock = whenStmt.choices[1].statements
}
if(trueBlock!=null && elseBlock!=null) {
return replaceWithIf(whenStmt.condition, trueBlock, elseBlock)
}
}
}
}
}
return noModifications
}
} }

View File

@ -1341,8 +1341,14 @@ internal class AstChecker(private val program: Program,
constvalue == null -> errors.err("choice value must be a constant", whenChoice.position) constvalue == null -> errors.err("choice value must be a constant", whenChoice.position)
constvalue.type !in IntegerDatatypes -> errors.err("choice value must be a byte or word", whenChoice.position) constvalue.type !in IntegerDatatypes -> errors.err("choice value must be a byte or word", whenChoice.position)
conditionType isnot constvalue.type -> { conditionType isnot constvalue.type -> {
if(conditionType.isKnown) if(conditionType.isKnown) {
errors.err("choice value datatype differs from condition value", whenChoice.position) if(conditionType.istype(DataType.BOOL)) {
if(constvalue.number!=0.0 && constvalue.number!=1.0)
errors.err("choice value datatype differs from condition value", whenChoice.position)
} else {
errors.err("choice value datatype differs from condition value", whenChoice.position)
}
}
} }
} }
} }

View File

@ -334,5 +334,22 @@ main {
}""" }"""
compileText(VMTarget(), optimize=false, src, writeAssembly=false) shouldNotBe null compileText(VMTarget(), optimize=false, src, writeAssembly=false) shouldNotBe null
} }
test("when on booleans") {
val src = """
main
{
sub start()
{
bool choiceVariable=true
when choiceVariable {
false -> cx16.r0++
true -> cx16.r1++
}
}
}"""
compileText(VMTarget(), optimize=false, src, writeAssembly=false) shouldNotBe null
}
}) })

View File

@ -1,32 +1,16 @@
%import textio %import textio
%zeropage basicsafe %zeropage basicsafe
; (127 instructions in 15 chunks, 47 registers) main
; 679 steps {
; 00f9
sub start()
main { {
bool rasterIrqAfterSubs=false
sub start() { when rasterIrqAfterSubs {
uword i false -> txt.print("false\n")
uword n true -> txt.print("true\n")
}
repeat 10 { txt.print("done")
txt.chrout('.')
}
txt.nl()
n=10
for i in 0 to n step 3 {
txt.print_uw(i)
txt.nl()
}
txt.nl()
n=0
for i in 10 downto n step -3 {
txt.print_uw(i)
txt.nl()
} }
} }
}

View File

@ -5,4 +5,4 @@ org.gradle.daemon=true
kotlin.code.style=official kotlin.code.style=official
javaVersion=11 javaVersion=11
kotlinVersion=1.9.0 kotlinVersion=1.9.0
version=9.1 version=9.2-SNAPSHOT