mirror of
https://github.com/irmen/prog8.git
synced 2025-03-01 00:30:03 +00:00
more forloop codegen
This commit is contained in:
parent
e6ff87ecd0
commit
3976cc26a2
@ -14,10 +14,6 @@ import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_PLUS1_HEX
|
|||||||
import prog8.compiler.toHex
|
import prog8.compiler.toHex
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
|
|
||||||
// todo choose more efficient comparisons to avoid needless lda's
|
|
||||||
// todo optimized code for step == 2 or -2
|
|
||||||
// todo allocate loop counter variable dynamically, preferrably on zeropage
|
|
||||||
|
|
||||||
internal class ForLoopsAsmGen(private val program: Program, private val asmgen: AsmGen) {
|
internal class ForLoopsAsmGen(private val program: Program, private val asmgen: AsmGen) {
|
||||||
|
|
||||||
internal fun translate(stmt: ForLoop) {
|
internal fun translate(stmt: ForLoop) {
|
||||||
@ -41,8 +37,6 @@ internal class ForLoopsAsmGen(private val program: Program, private val asmgen:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translateForOverNonconstRange(stmt: ForLoop, iterableDt: DataType, range: RangeExpr) {
|
private fun translateForOverNonconstRange(stmt: ForLoop, iterableDt: DataType, range: RangeExpr) {
|
||||||
// TODO more optimized code possible now that continue is gone?
|
|
||||||
|
|
||||||
val loopLabel = asmgen.makeLabel("for_loop")
|
val loopLabel = asmgen.makeLabel("for_loop")
|
||||||
val endLabel = asmgen.makeLabel("for_end")
|
val endLabel = asmgen.makeLabel("for_end")
|
||||||
asmgen.loopEndLabels.push(endLabel)
|
asmgen.loopEndLabels.push(endLabel)
|
||||||
@ -66,13 +60,13 @@ $loopLabel""")
|
|||||||
asmgen.translate(stmt.body)
|
asmgen.translate(stmt.body)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $varname
|
lda $varname
|
||||||
cmp $ESTACK_LO_PLUS1_HEX,x
|
cmp $ESTACK_LO_PLUS1_HEX,x TODO modifying code
|
||||||
beq $endLabel
|
beq $endLabel
|
||||||
$incdec $varname
|
$incdec $varname
|
||||||
jmp $loopLabel
|
jmp $loopLabel
|
||||||
$endLabel inx""")
|
$endLabel inx""")
|
||||||
}
|
|
||||||
else {
|
} else {
|
||||||
|
|
||||||
// bytes, step >= 2 or <= -2
|
// bytes, step >= 2 or <= -2
|
||||||
|
|
||||||
@ -93,7 +87,7 @@ $loopLabel""")
|
|||||||
clc
|
clc
|
||||||
adc #$stepsize
|
adc #$stepsize
|
||||||
sta $varname
|
sta $varname
|
||||||
cmp $ESTACK_LO_PLUS1_HEX,x
|
cmp $ESTACK_LO_PLUS1_HEX,x TODO modifying code
|
||||||
bcc $loopLabel
|
bcc $loopLabel
|
||||||
beq $loopLabel""")
|
beq $loopLabel""")
|
||||||
} else {
|
} else {
|
||||||
@ -101,7 +95,7 @@ $loopLabel""")
|
|||||||
sec
|
sec
|
||||||
sbc #${stepsize.absoluteValue}
|
sbc #${stepsize.absoluteValue}
|
||||||
sta $varname
|
sta $varname
|
||||||
cmp $ESTACK_LO_PLUS1_HEX,x
|
cmp $ESTACK_LO_PLUS1_HEX,x TODO modifying code
|
||||||
bcs $loopLabel""")
|
bcs $loopLabel""")
|
||||||
}
|
}
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
@ -123,10 +117,10 @@ $endLabel inx""")
|
|||||||
asmgen.translate(stmt.body)
|
asmgen.translate(stmt.body)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $varname+1
|
lda $varname+1
|
||||||
cmp $ESTACK_HI_PLUS1_HEX,x
|
cmp $ESTACK_HI_PLUS1_HEX,x TODO modifying code
|
||||||
bne +
|
bne +
|
||||||
lda $varname
|
lda $varname
|
||||||
cmp $ESTACK_LO_PLUS1_HEX,x
|
cmp $ESTACK_LO_PLUS1_HEX,x TODO modifying code
|
||||||
beq $endLabel""")
|
beq $endLabel""")
|
||||||
if(stepsize==1) {
|
if(stepsize==1) {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
@ -166,12 +160,12 @@ $endLabel inx""")
|
|||||||
lda $varname+1
|
lda $varname+1
|
||||||
adc #>$stepsize
|
adc #>$stepsize
|
||||||
sta $varname+1
|
sta $varname+1
|
||||||
lda $ESTACK_HI_PLUS1_HEX,x
|
lda $ESTACK_HI_PLUS1_HEX,x TODO modifying code
|
||||||
cmp $varname+1
|
cmp $varname+1
|
||||||
bcc $endLabel
|
bcc $endLabel
|
||||||
bne $loopLabel
|
bne $loopLabel
|
||||||
lda $varname
|
lda $varname
|
||||||
cmp $ESTACK_LO_PLUS1_HEX,x
|
cmp $ESTACK_LO_PLUS1_HEX,x TODO modifying code
|
||||||
bcc $endLabel
|
bcc $endLabel
|
||||||
bcs $loopLabel
|
bcs $loopLabel
|
||||||
$endLabel inx""")
|
$endLabel inx""")
|
||||||
@ -184,9 +178,9 @@ $endLabel inx""")
|
|||||||
lda $varname+1
|
lda $varname+1
|
||||||
adc #>$stepsize
|
adc #>$stepsize
|
||||||
sta $varname+1
|
sta $varname+1
|
||||||
lda $ESTACK_LO_PLUS1_HEX,x
|
lda $ESTACK_LO_PLUS1_HEX,x TODO modifying code
|
||||||
cmp $varname
|
cmp $varname
|
||||||
lda $ESTACK_HI_PLUS1_HEX,x
|
lda $ESTACK_HI_PLUS1_HEX,x TODO modifying code
|
||||||
sbc $varname+1
|
sbc $varname+1
|
||||||
bvc +
|
bvc +
|
||||||
eor #$80
|
eor #$80
|
||||||
@ -214,11 +208,11 @@ $endLabel inx""")
|
|||||||
lda $varname+1
|
lda $varname+1
|
||||||
sbc #>${stepsize.absoluteValue}
|
sbc #>${stepsize.absoluteValue}
|
||||||
sta $varname+1
|
sta $varname+1
|
||||||
cmp $ESTACK_HI_PLUS1_HEX,x
|
cmp $ESTACK_HI_PLUS1_HEX,x TODO modifying code
|
||||||
bcc $endLabel
|
bcc $endLabel
|
||||||
bne $loopLabel
|
bne $loopLabel
|
||||||
lda $varname
|
lda $varname
|
||||||
cmp $ESTACK_LO_PLUS1_HEX,x
|
cmp $ESTACK_LO_PLUS1_HEX,x TODO modifying code
|
||||||
bcs $loopLabel
|
bcs $loopLabel
|
||||||
$endLabel inx""")
|
$endLabel inx""")
|
||||||
} else {
|
} else {
|
||||||
@ -232,9 +226,9 @@ $endLabel inx""")
|
|||||||
sbc #>${stepsize.absoluteValue}
|
sbc #>${stepsize.absoluteValue}
|
||||||
sta $varname+1
|
sta $varname+1
|
||||||
pla
|
pla
|
||||||
cmp $ESTACK_LO_PLUS1_HEX,x
|
cmp $ESTACK_LO_PLUS1_HEX,x TODO modifying code
|
||||||
lda $varname+1
|
lda $varname+1
|
||||||
sbc $ESTACK_HI_PLUS1_HEX,x
|
sbc $ESTACK_HI_PLUS1_HEX,x TODO modifying code
|
||||||
bvc +
|
bvc +
|
||||||
eor #$80
|
eor #$80
|
||||||
+ bpl $loopLabel
|
+ bpl $loopLabel
|
||||||
@ -250,7 +244,6 @@ $endLabel inx""")
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translateForOverIterableVar(stmt: ForLoop, iterableDt: DataType, ident: IdentifierReference) {
|
private fun translateForOverIterableVar(stmt: ForLoop, iterableDt: DataType, ident: IdentifierReference) {
|
||||||
// TODO more optimized code possible now that continue is gone?
|
|
||||||
val loopLabel = asmgen.makeLabel("for_loop")
|
val loopLabel = asmgen.makeLabel("for_loop")
|
||||||
val endLabel = asmgen.makeLabel("for_end")
|
val endLabel = asmgen.makeLabel("for_end")
|
||||||
asmgen.loopEndLabels.push(endLabel)
|
asmgen.loopEndLabels.push(endLabel)
|
||||||
@ -275,9 +268,9 @@ $loopLabel lda ${65535.toHex()} ; modified
|
|||||||
$endLabel""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
||||||
// TODO: optimize loop code when the length of the array is < 256
|
// TODO: optimize loop code when the length of the array is < 256 (i.e. always)
|
||||||
val length = decl.arraysize!!.size()!!
|
val length = decl.arraysize!!.size()!!
|
||||||
val counterLabel = asmgen.makeLabel("for_counter")
|
val counterLabel = asmgen.makeLabel("for_counter") // todo allocate dynamically, zero page preferred if iterations >= 8
|
||||||
val modifiedLabel = asmgen.makeLabel("for_modified")
|
val modifiedLabel = asmgen.makeLabel("for_modified")
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #<$iterableName
|
lda #<$iterableName
|
||||||
@ -294,14 +287,14 @@ $modifiedLabel lda ${65535.toHex()},y ; modified""")
|
|||||||
iny
|
iny
|
||||||
cpy #${length and 255}
|
cpy #${length and 255}
|
||||||
beq $endLabel
|
beq $endLabel
|
||||||
jmp $loopLabel
|
bne $loopLabel
|
||||||
$counterLabel .byte 0
|
$counterLabel .byte 0
|
||||||
$endLabel""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
||||||
// TODO: optimize loop code when the length of the array is < 256
|
// TODO: optimize loop code when the length of the array is < 256 (i.e. always)
|
||||||
val length = decl.arraysize!!.size()!! * 2
|
val length = decl.arraysize!!.size()!! * 2
|
||||||
val counterLabel = asmgen.makeLabel("for_counter")
|
val counterLabel = asmgen.makeLabel("for_counter") // todo allocate dynamically, zero page preferred if iterations >= 8
|
||||||
val modifiedLabel = asmgen.makeLabel("for_modified")
|
val modifiedLabel = asmgen.makeLabel("for_modified")
|
||||||
val modifiedLabel2 = asmgen.makeLabel("for_modified2")
|
val modifiedLabel2 = asmgen.makeLabel("for_modified2")
|
||||||
val loopvarName = asmgen.asmIdentifierName(stmt.loopVar)
|
val loopvarName = asmgen.asmIdentifierName(stmt.loopVar)
|
||||||
@ -327,7 +320,7 @@ $modifiedLabel2 lda ${65535.toHex()},y ; modified
|
|||||||
iny
|
iny
|
||||||
cpy #${length and 255}
|
cpy #${length and 255}
|
||||||
beq $endLabel
|
beq $endLabel
|
||||||
jmp $loopLabel
|
bne $loopLabel
|
||||||
$counterLabel .byte 0
|
$counterLabel .byte 0
|
||||||
$endLabel""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
@ -343,179 +336,117 @@ $endLabel""")
|
|||||||
if (range.isEmpty() || range.step==0)
|
if (range.isEmpty() || range.step==0)
|
||||||
throw AssemblyError("empty range or step 0")
|
throw AssemblyError("empty range or step 0")
|
||||||
if(iterableDt==DataType.ARRAY_B || iterableDt==DataType.ARRAY_UB) {
|
if(iterableDt==DataType.ARRAY_B || iterableDt==DataType.ARRAY_UB) {
|
||||||
if(range.step==1 && range.first>=0 && range.last <= 255 && range.last>range.first) return translateForSimpleByteRangeAsc(stmt, range)
|
if(range.step==1 && range.last>range.first) return translateForSimpleByteRangeAsc(stmt, range)
|
||||||
if(range.step==-1 && range.first<=255 && range.first >=0 && range.last<range.first) return translateForSimpleByteRangeDesc(stmt, range)
|
if(range.step==-1 && range.last<range.first) return translateForSimpleByteRangeDesc(stmt, range)
|
||||||
}
|
}
|
||||||
if(iterableDt==DataType.ARRAY_W || iterableDt==DataType.ARRAY_UW) {
|
else if(iterableDt==DataType.ARRAY_W || iterableDt==DataType.ARRAY_UW) {
|
||||||
if(range.step==1 && range.first>=0 && range.last <= 255 && range.last>range.first) return translateForSimpleWordRange255Asc(stmt, range)
|
if(range.step==1 && range.last>range.first) return translateForSimpleWordRangeAsc(stmt, range)
|
||||||
if(range.step==-1 && range.first<=255 && range.first >=0 && range.last<range.first) return translateForSimpleWordRange255Desc(stmt, range)
|
if(range.step==-1 && range.last<range.first) return translateForSimpleWordRangeDesc(stmt, range)
|
||||||
if(range.step==1 && range.first>=0 && range.last <= 65535 && range.last>range.first) return translateForSimpleWordRange65535Asc(stmt, range)
|
|
||||||
if(range.step==-1 && range.first<=65535 && range.first >=0 && range.last<range.first) return translateForSimpleWordRange65535Desc(stmt, range)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// not one of the easy cases, generate more complex code...
|
||||||
val loopLabel = asmgen.makeLabel("for_loop")
|
val loopLabel = asmgen.makeLabel("for_loop")
|
||||||
val endLabel = asmgen.makeLabel("for_end")
|
val endLabel = asmgen.makeLabel("for_end")
|
||||||
asmgen.loopEndLabels.push(endLabel)
|
asmgen.loopEndLabels.push(endLabel)
|
||||||
// TODO more optimized code possible now that continue is gone?
|
|
||||||
when(iterableDt) {
|
when(iterableDt) {
|
||||||
DataType.ARRAY_B, DataType.ARRAY_UB -> {
|
DataType.ARRAY_B, DataType.ARRAY_UB -> {
|
||||||
// loop over byte range via loopvar, step > 1 or < -1
|
// loop over byte range via loopvar, step >= 2 or <= -2
|
||||||
val counterLabel = asmgen.makeLabel("for_counter")
|
|
||||||
val varname = asmgen.asmIdentifierName(stmt.loopVar)
|
val varname = asmgen.asmIdentifierName(stmt.loopVar)
|
||||||
when {
|
asmgen.out("""
|
||||||
range.step==1 || range.step==-1 -> {
|
lda #${range.first}
|
||||||
throw AssemblyError("step 1 and -1 should have been handled specifically")
|
sta $varname
|
||||||
}
|
|
||||||
range.step >= 2 -> {
|
|
||||||
// step >= 2
|
|
||||||
asmgen.out("""
|
|
||||||
lda #${(range.last-range.first) / range.step + 1}
|
|
||||||
sta $counterLabel
|
|
||||||
lda #${range.first}
|
|
||||||
sta $varname
|
|
||||||
$loopLabel""")
|
$loopLabel""")
|
||||||
asmgen.translate(stmt.body)
|
asmgen.translate(stmt.body)
|
||||||
asmgen.out("""
|
when (range.step) {
|
||||||
dec $counterLabel
|
0, 1, -1 -> {
|
||||||
beq $endLabel
|
throw AssemblyError("step 0, 1 and -1 should have been handled specifically $stmt")
|
||||||
lda $varname
|
}
|
||||||
clc
|
2 -> {
|
||||||
adc #${range.step}
|
if(range.last==255) {
|
||||||
sta $varname
|
asmgen.out("""
|
||||||
jmp $loopLabel
|
inc $varname
|
||||||
$counterLabel .byte 0
|
beq $endLabel
|
||||||
$endLabel""")
|
inc $varname
|
||||||
|
bne $loopLabel""")
|
||||||
|
} else {
|
||||||
|
asmgen.out("""
|
||||||
|
lda $varname
|
||||||
|
cmp #${range.last}
|
||||||
|
beq $endLabel
|
||||||
|
inc $varname
|
||||||
|
inc $varname
|
||||||
|
jmp $loopLabel""")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-2 -> {
|
||||||
|
when (range.last) {
|
||||||
|
0 -> asmgen.out("""
|
||||||
|
lda $varname
|
||||||
|
beq $endLabel
|
||||||
|
dec $varname
|
||||||
|
dec $varname
|
||||||
|
jmp $loopLabel""")
|
||||||
|
1 -> asmgen.out("""
|
||||||
|
dec $varname
|
||||||
|
beq $endLabel
|
||||||
|
dec $varname
|
||||||
|
bne $loopLabel""")
|
||||||
|
else -> asmgen.out("""
|
||||||
|
lda $varname
|
||||||
|
cmp #${range.last}
|
||||||
|
beq $endLabel
|
||||||
|
dec $varname
|
||||||
|
dec $varname
|
||||||
|
jmp $loopLabel""")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
// step <= -2
|
// step <= -3 or >= 3
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #${(range.first-range.last) / range.step.absoluteValue + 1}
|
lda $varname
|
||||||
sta $counterLabel
|
cmp #${range.last}
|
||||||
lda #${range.first}
|
beq $endLabel
|
||||||
sta $varname
|
clc
|
||||||
$loopLabel""")
|
adc #${range.step}
|
||||||
asmgen.translate(stmt.body)
|
sta $varname
|
||||||
asmgen.out("""
|
jmp $loopLabel""")
|
||||||
dec $counterLabel
|
|
||||||
beq $endLabel
|
|
||||||
lda $varname
|
|
||||||
sec
|
|
||||||
sbc #${range.step.absoluteValue}
|
|
||||||
sta $varname
|
|
||||||
jmp $loopLabel
|
|
||||||
$counterLabel .byte 0
|
|
||||||
$endLabel""")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
asmgen.out(endLabel)
|
||||||
}
|
}
|
||||||
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
||||||
// loop over word range via loopvar, step > 1 or < -1
|
// loop over word range via loopvar, step >= 2 or <= -2
|
||||||
val varname = asmgen.asmIdentifierName(stmt.loopVar)
|
val varname = asmgen.asmIdentifierName(stmt.loopVar)
|
||||||
when {
|
when (range.step) {
|
||||||
range.step==1 || range.step==-1 -> {
|
0, 1, -1 -> {
|
||||||
throw AssemblyError("step 1 and -1 should have been handled specifically")
|
throw AssemblyError("step 0, 1 and -1 should have been handled specifically $stmt")
|
||||||
}
|
|
||||||
// range.step == 1 -> {
|
|
||||||
// // word, step = 1
|
|
||||||
// val lastValue = range.last+1
|
|
||||||
// asmgen.out("""
|
|
||||||
// lda #<${range.first}
|
|
||||||
// ldy #>${range.first}
|
|
||||||
// sta $varname
|
|
||||||
// sty $varname+1
|
|
||||||
//$loopLabel""")
|
|
||||||
// asmgen.translate(stmt.body)
|
|
||||||
// asmgen.out("""
|
|
||||||
// inc $varname
|
|
||||||
// bne +
|
|
||||||
// inc $varname+1
|
|
||||||
//+ lda $varname
|
|
||||||
// cmp #<$lastValue
|
|
||||||
// bne +
|
|
||||||
// lda $varname+1
|
|
||||||
// cmp #>$lastValue
|
|
||||||
// beq $endLabel
|
|
||||||
//+ jmp $loopLabel
|
|
||||||
//$endLabel""")
|
|
||||||
// }
|
|
||||||
// range.step == -1 -> {
|
|
||||||
// // word, step = 1
|
|
||||||
// val lastValue = range.last-1
|
|
||||||
// asmgen.out("""
|
|
||||||
// lda #<${range.first}
|
|
||||||
// ldy #>${range.first}
|
|
||||||
// sta $varname
|
|
||||||
// sty $varname+1
|
|
||||||
//$loopLabel""")
|
|
||||||
// asmgen.translate(stmt.body)
|
|
||||||
// asmgen.out("""
|
|
||||||
// lda $varname
|
|
||||||
// bne +
|
|
||||||
// dec $varname+1
|
|
||||||
//+ dec $varname
|
|
||||||
// lda $varname
|
|
||||||
// cmp #<$lastValue
|
|
||||||
// bne +
|
|
||||||
// lda $varname+1
|
|
||||||
// cmp #>$lastValue
|
|
||||||
// beq $endLabel
|
|
||||||
//+ jmp $loopLabel
|
|
||||||
//$endLabel""")
|
|
||||||
// }
|
|
||||||
range.step >= 2 -> {
|
|
||||||
// word, step >= 2
|
|
||||||
// note: range.last has already been adjusted by kotlin itself to actually be the last value of the sequence
|
|
||||||
val lastValue = range.last+range.step
|
|
||||||
asmgen.out("""
|
|
||||||
lda #<${range.first}
|
|
||||||
ldy #>${range.first}
|
|
||||||
sta $varname
|
|
||||||
sty $varname+1
|
|
||||||
$loopLabel""")
|
|
||||||
asmgen.translate(stmt.body)
|
|
||||||
asmgen.out("""
|
|
||||||
clc
|
|
||||||
lda $varname
|
|
||||||
adc #<${range.step}
|
|
||||||
sta $varname
|
|
||||||
lda $varname+1
|
|
||||||
adc #>${range.step}
|
|
||||||
sta $varname+1
|
|
||||||
lda $varname
|
|
||||||
cmp #<$lastValue
|
|
||||||
bne +
|
|
||||||
lda $varname+1
|
|
||||||
cmp #>$lastValue
|
|
||||||
beq $endLabel
|
|
||||||
+ jmp $loopLabel
|
|
||||||
$endLabel""")
|
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
// step <= -2
|
// word, step >= 2 or <= -2
|
||||||
// note: range.last has already been adjusted by kotlin itself to actually be the last value of the sequence
|
// note: range.last has already been adjusted by kotlin itself to actually be the last value of the sequence
|
||||||
val lastValue = range.last+range.step
|
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #<${range.first}
|
lda #<${range.first}
|
||||||
ldy #>${range.first}
|
ldy #>${range.first}
|
||||||
sta $varname
|
sta $varname
|
||||||
sty $varname+1
|
sty $varname+1
|
||||||
$loopLabel""")
|
$loopLabel""")
|
||||||
asmgen.translate(stmt.body)
|
asmgen.translate(stmt.body)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
sec
|
lda $varname
|
||||||
lda $varname
|
cmp #<${range.last}
|
||||||
sbc #<${range.step.absoluteValue}
|
bne +
|
||||||
sta $varname
|
lda $varname+1
|
||||||
lda $varname+1
|
cmp #>${range.last}
|
||||||
sbc #>${range.step.absoluteValue}
|
bne +
|
||||||
sta $varname+1
|
beq $endLabel
|
||||||
lda $varname
|
+ lda $varname
|
||||||
cmp #<$lastValue
|
clc
|
||||||
bne +
|
adc #<${range.step}
|
||||||
lda $varname+1
|
sta $varname
|
||||||
cmp #>$lastValue
|
lda $varname+1
|
||||||
beq $endLabel
|
adc #>${range.step}
|
||||||
+ jmp $loopLabel
|
sta $varname+1
|
||||||
|
jmp $loopLabel
|
||||||
$endLabel""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -530,28 +461,23 @@ $endLabel""")
|
|||||||
val endLabel = asmgen.makeLabel("for_end")
|
val endLabel = asmgen.makeLabel("for_end")
|
||||||
asmgen.loopEndLabels.push(endLabel)
|
asmgen.loopEndLabels.push(endLabel)
|
||||||
val varname = asmgen.asmIdentifierName(stmt.loopVar)
|
val varname = asmgen.asmIdentifierName(stmt.loopVar)
|
||||||
if (range.last == 255) {
|
asmgen.out("""
|
||||||
asmgen.out("""
|
|
||||||
lda #${range.first}
|
lda #${range.first}
|
||||||
sta $varname
|
sta $varname
|
||||||
$loopLabel""")
|
$loopLabel""")
|
||||||
asmgen.translate(stmt.body)
|
asmgen.translate(stmt.body)
|
||||||
|
if (range.last == 255) {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inc $varname
|
inc $varname
|
||||||
bne $loopLabel
|
bne $loopLabel
|
||||||
$endLabel""")
|
$endLabel""")
|
||||||
} else {
|
} else {
|
||||||
asmgen.out("""
|
|
||||||
lda #${range.first}
|
|
||||||
sta $varname
|
|
||||||
$loopLabel""")
|
|
||||||
asmgen.translate(stmt.body)
|
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $varname
|
lda $varname
|
||||||
cmp #${range.last}
|
cmp #${range.last}
|
||||||
beq $endLabel
|
beq $endLabel
|
||||||
inc $varname
|
inc $varname
|
||||||
bne $loopLabel
|
jmp $loopLabel
|
||||||
$endLabel""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
asmgen.loopEndLabels.pop()
|
asmgen.loopEndLabels.pop()
|
||||||
@ -562,13 +488,13 @@ $endLabel""")
|
|||||||
val endLabel = asmgen.makeLabel("for_end")
|
val endLabel = asmgen.makeLabel("for_end")
|
||||||
asmgen.loopEndLabels.push(endLabel)
|
asmgen.loopEndLabels.push(endLabel)
|
||||||
val varname = asmgen.asmIdentifierName(stmt.loopVar)
|
val varname = asmgen.asmIdentifierName(stmt.loopVar)
|
||||||
when (range.last) {
|
asmgen.out("""
|
||||||
0 -> {
|
|
||||||
asmgen.out("""
|
|
||||||
lda #${range.first}
|
lda #${range.first}
|
||||||
sta $varname
|
sta $varname
|
||||||
$loopLabel""")
|
$loopLabel""")
|
||||||
asmgen.translate(stmt.body)
|
asmgen.translate(stmt.body)
|
||||||
|
when (range.last) {
|
||||||
|
0 -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $varname
|
lda $varname
|
||||||
beq $endLabel
|
beq $endLabel
|
||||||
@ -577,48 +503,78 @@ $loopLabel""")
|
|||||||
$endLabel""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
1 -> {
|
1 -> {
|
||||||
asmgen.out("""
|
|
||||||
lda #${range.first}
|
|
||||||
sta $varname
|
|
||||||
$loopLabel""")
|
|
||||||
asmgen.translate(stmt.body)
|
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
dec $varname
|
dec $varname
|
||||||
bne $loopLabel
|
jmp $loopLabel
|
||||||
$endLabel""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
asmgen.out("""
|
|
||||||
lda #${range.first}
|
|
||||||
sta $varname
|
|
||||||
$loopLabel""")
|
|
||||||
asmgen.translate(stmt.body)
|
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $varname
|
lda $varname
|
||||||
cmp #${range.last}
|
cmp #${range.last}
|
||||||
beq $endLabel
|
beq $endLabel
|
||||||
dec $varname
|
dec $varname
|
||||||
bne $loopLabel
|
jmp $loopLabel
|
||||||
$endLabel""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
asmgen.loopEndLabels.pop()
|
asmgen.loopEndLabels.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateForSimpleWordRange255Asc(stmt: ForLoop, range: IntProgression) {
|
private fun translateForSimpleWordRangeAsc(stmt: ForLoop, range: IntProgression) {
|
||||||
TODO("Not yet implemented")
|
val loopLabel = asmgen.makeLabel("for_loop")
|
||||||
|
val endLabel = asmgen.makeLabel("for_end")
|
||||||
|
asmgen.loopEndLabels.push(endLabel)
|
||||||
|
val varname = asmgen.asmIdentifierName(stmt.loopVar)
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<${range.first}
|
||||||
|
ldy #>${range.first}
|
||||||
|
sta $varname
|
||||||
|
sty $varname+1
|
||||||
|
$loopLabel""")
|
||||||
|
asmgen.translate(stmt.body)
|
||||||
|
asmgen.out("""
|
||||||
|
lda $varname
|
||||||
|
cmp #<${range.last}
|
||||||
|
bne +
|
||||||
|
lda $varname+1
|
||||||
|
cmp #>${range.last}
|
||||||
|
bne +
|
||||||
|
beq $endLabel
|
||||||
|
+ inc $varname
|
||||||
|
bne $loopLabel
|
||||||
|
inc $varname+1
|
||||||
|
jmp $loopLabel
|
||||||
|
$endLabel""")
|
||||||
|
asmgen.loopEndLabels.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateForSimpleWordRange255Desc(stmt: ForLoop, range: IntProgression) {
|
private fun translateForSimpleWordRangeDesc(stmt: ForLoop, range: IntProgression) {
|
||||||
TODO("Not yet implemented")
|
val loopLabel = asmgen.makeLabel("for_loop")
|
||||||
|
val endLabel = asmgen.makeLabel("for_end")
|
||||||
|
asmgen.loopEndLabels.push(endLabel)
|
||||||
|
val varname = asmgen.asmIdentifierName(stmt.loopVar)
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<${range.first}
|
||||||
|
ldy #>${range.first}
|
||||||
|
sta $varname
|
||||||
|
sty $varname+1
|
||||||
|
$loopLabel""")
|
||||||
|
asmgen.translate(stmt.body)
|
||||||
|
asmgen.out("""
|
||||||
|
lda $varname
|
||||||
|
cmp #<${range.last}
|
||||||
|
bne +
|
||||||
|
lda $varname+1
|
||||||
|
cmp #>${range.last}
|
||||||
|
bne +
|
||||||
|
beq $endLabel
|
||||||
|
+ lda $varname
|
||||||
|
bne +
|
||||||
|
dec $varname+1
|
||||||
|
+ dec $varname
|
||||||
|
jmp $loopLabel
|
||||||
|
$endLabel""")
|
||||||
|
asmgen.loopEndLabels.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateForSimpleWordRange65535Asc(stmt: ForLoop, range: IntProgression) {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun translateForSimpleWordRange65535Desc(stmt: ForLoop, range: IntProgression) {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,93 +6,82 @@
|
|||||||
main {
|
main {
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
ubyte counterb
|
byte counterb
|
||||||
uword counterw
|
word counterw
|
||||||
|
|
||||||
|
for counterb in -10 to 11 {
|
||||||
for counterb in 0 to 10 {
|
c64scr.print_b(counterb)
|
||||||
c64scr.print_ub(counterb)
|
|
||||||
c64.CHROUT(',')
|
c64.CHROUT(',')
|
||||||
}
|
}
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
for counterb in 10 to 30 {
|
for counterb in 11 to -10 step -1 {
|
||||||
c64scr.print_ub(counterb)
|
c64scr.print_b(counterb)
|
||||||
c64.CHROUT(',')
|
c64.CHROUT(',')
|
||||||
}
|
}
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
for counterb in 250 to 255 {
|
for counterb in -10 to 11 step 2 {
|
||||||
c64scr.print_ub(counterb)
|
c64scr.print_b(counterb)
|
||||||
c64.CHROUT(',')
|
c64.CHROUT(',')
|
||||||
}
|
}
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
for counterb in 10 to 0 step -1 {
|
for counterb in 11 to -10 step -2 {
|
||||||
c64scr.print_ub(counterb)
|
c64scr.print_b(counterb)
|
||||||
c64.CHROUT(',')
|
c64.CHROUT(',')
|
||||||
}
|
}
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
for counterb in 10 to 1 step -1 {
|
for counterb in -10 to 11 step 3 {
|
||||||
c64scr.print_ub(counterb)
|
c64scr.print_b(counterb)
|
||||||
c64.CHROUT(',')
|
c64.CHROUT(',')
|
||||||
}
|
}
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
for counterb in 30 to 10 step -1 {
|
for counterb in 11 to -10 step -3 {
|
||||||
c64scr.print_ub(counterb)
|
c64scr.print_b(counterb)
|
||||||
|
c64.CHROUT(',')
|
||||||
|
}
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
|
for counterw in -10 to 11 {
|
||||||
|
c64scr.print_w(counterw)
|
||||||
c64.CHROUT(',')
|
c64.CHROUT(',')
|
||||||
}
|
}
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
for counterb in 255 to 250 step -1 {
|
for counterw in 11 to -10 step -1 {
|
||||||
c64scr.print_ub(counterb)
|
c64scr.print_w(counterw)
|
||||||
c64.CHROUT(',')
|
|
||||||
}
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
|
|
||||||
for counterw in 0 to 10 {
|
|
||||||
c64scr.print_uw(counterw)
|
|
||||||
c64.CHROUT(',')
|
c64.CHROUT(',')
|
||||||
}
|
}
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
for counterw in 10 to 30 {
|
for counterw in -10 to 11 step 2 {
|
||||||
c64scr.print_uw(counterw)
|
c64scr.print_w(counterw)
|
||||||
c64.CHROUT(',')
|
c64.CHROUT(',')
|
||||||
}
|
}
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
for counterw in 250 to 255 {
|
for counterw in 11 to -10 step -2 {
|
||||||
c64scr.print_uw(counterw)
|
c64scr.print_w(counterw)
|
||||||
c64.CHROUT(',')
|
c64.CHROUT(',')
|
||||||
}
|
}
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
for counterw in 10 to 0 step -1 {
|
for counterw in -10 to 11 step 3 {
|
||||||
c64scr.print_uw(counterw)
|
c64scr.print_w(counterw)
|
||||||
c64.CHROUT(',')
|
c64.CHROUT(',')
|
||||||
}
|
}
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
for counterw in 10 to 1 step -1 {
|
for counterw in 11 to -10 step -3 {
|
||||||
c64scr.print_uw(counterw)
|
c64scr.print_w(counterw)
|
||||||
c64.CHROUT(',')
|
c64.CHROUT(',')
|
||||||
}
|
}
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
for counterw in 30 to 10 step -1 {
|
|
||||||
c64scr.print_uw(counterw)
|
|
||||||
c64.CHROUT(',')
|
|
||||||
}
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
|
|
||||||
for counterw in 255 to 250 step -1 {
|
|
||||||
c64scr.print_uw(counterw)
|
|
||||||
c64.CHROUT(',')
|
|
||||||
}
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user