From 4661cba97403b68f6ec7f2b0400283d9f63ac710 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 29 Jul 2019 22:47:04 +0200 Subject: [PATCH] asm for when statements added --- .../src/prog8/ast/processing/AstChecker.kt | 3 ++ .../ast/processing/StatementReorderer.kt | 21 ---------- .../compiler/target/c64/codegen2/AsmGen2.kt | 39 ++++++++++++++++++- examples/test.p8 | 1 + 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/compiler/src/prog8/ast/processing/AstChecker.kt b/compiler/src/prog8/ast/processing/AstChecker.kt index 17674df63..9585ee67a 100644 --- a/compiler/src/prog8/ast/processing/AstChecker.kt +++ b/compiler/src/prog8/ast/processing/AstChecker.kt @@ -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) } diff --git a/compiler/src/prog8/ast/processing/StatementReorderer.kt b/compiler/src/prog8/ast/processing/StatementReorderer.kt index 6955cd2c4..20d5ea510 100644 --- a/compiler/src/prog8/ast/processing/StatementReorderer.kt +++ b/compiler/src/prog8/ast/processing/StatementReorderer.kt @@ -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(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) diff --git a/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt b/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt index 82f80a460..b16f3a47a 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt @@ -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>() + 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) { diff --git a/examples/test.p8 b/examples/test.p8 index 5ac4fea35..9ca864974 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -59,6 +59,7 @@ 9999 -> c64scr.print("ninetynine99") else -> c64scr.print("don't know") } + c64.CHROUT('\n') }