asm for when statements added

This commit is contained in:
Irmen de Jong 2019-07-29 22:47:04 +02:00
parent 025be8cb7c
commit 4661cba974
4 changed files with 42 additions and 22 deletions

View File

@ -955,6 +955,9 @@ internal class AstChecker(private val program: Program,
tally.filter { it.value>1 }.forEach {
checkResult.add(SyntaxError("choice value occurs multiple times", it.key.position))
}
if(whenStatement.choices.isEmpty())
checkResult.add(SyntaxError("empty when statement", whenStatement.position))
super.visit(whenStatement)
}

View File

@ -329,27 +329,6 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
return super.visit(typecast)
}
override fun visit(whenStatement: WhenStatement): Statement {
// make sure all choices are just for one single value
val choices = whenStatement.choices.toList()
for(choice in choices) {
val choiceValues = choice.values
if(choiceValues==null || choiceValues.size==1)
continue
for(v in choiceValues) {
val newchoice=WhenChoice(listOf(v), choice.statements, choice.position)
newchoice.parent = choice.parent
whenStatement.choices.add(newchoice)
}
whenStatement.choices.remove(choice)
}
// sort the choices in low-to-high value order (nulls last)
whenStatement.choices
.sortWith(compareBy<WhenChoice, Int?>(nullsLast(), {it.values?.single()?.constValue(program)?.number?.toInt()}))
return super.visit(whenStatement)
}
override fun visit(memread: DirectMemoryRead): Expression {
// make sure the memory address is an uword
val dt = memread.addressExpression.inferType(program)

View File

@ -837,7 +837,44 @@ internal class AsmGen2(val program: Program,
}
private fun translate(stmt: WhenStatement) {
TODO("when $stmt")
translateExpression(stmt.condition)
val endLabel = makeLabel("choice_end")
val choiceBlocks = mutableListOf<Pair<String, AnonymousScope>>()
val conditionDt = stmt.condition.inferType(program)!!
if(conditionDt in ByteDatatypes)
out(" inx | lda $ESTACK_LO_HEX,x")
else
out(" inx | lda $ESTACK_LO_HEX,x | ldy $ESTACK_HI_HEX,x")
for(choice in stmt.choices) {
val choiceLabel = makeLabel("choice")
if(choice.values==null) {
// the else choice
translate(choice.statements)
out(" jmp $endLabel")
} else {
choiceBlocks.add(Pair(choiceLabel, choice.statements))
for (cv in choice.values!!) {
val value = (cv as NumericLiteralValue).number.toInt()
if(conditionDt in ByteDatatypes) {
out(" cmp #${value.toHex()} | beq $choiceLabel")
} else {
out("""
cmp #<${value.toHex()}
bne +
cpy #>${value.toHex()}
beq $choiceLabel
+
""")
}
}
}
}
for(choiceBlock in choiceBlocks) {
out(choiceBlock.first)
translate(choiceBlock.second)
out(" jmp $endLabel")
}
out(endLabel)
}
private fun translate(stmt: Label) {

View File

@ -59,6 +59,7 @@
9999 -> c64scr.print("ninetynine99")
else -> c64scr.print("don't know")
}
c64.CHROUT('\n')
}