mirror of
https://github.com/irmen/prog8.git
synced 2024-10-19 07:23:56 +00:00
nonconst forloops (bytes)
This commit is contained in:
parent
4862fb7db1
commit
c79b587eea
@ -1016,7 +1016,84 @@ internal class AsmGen2(val program: Program,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translateForOverNonconstRange(stmt: ForLoop, iterableDt: DataType, range: RangeExpr) {
|
private fun translateForOverNonconstRange(stmt: ForLoop, iterableDt: DataType, range: RangeExpr) {
|
||||||
TODO("non-const range loop")
|
val loopLabel = makeLabel("for_loop")
|
||||||
|
val endLabel = makeLabel("for_end")
|
||||||
|
val continueLabel = makeLabel("for_continue")
|
||||||
|
val counterLabel = makeLabel("for_counter")
|
||||||
|
loopEndLabels.push(endLabel)
|
||||||
|
loopContinueLabels.push(continueLabel)
|
||||||
|
when (range.step.constValue(program)?.number) {
|
||||||
|
1 -> {
|
||||||
|
when(iterableDt) {
|
||||||
|
DataType.ARRAY_B, DataType.ARRAY_UB -> {
|
||||||
|
if (stmt.loopRegister != null) {
|
||||||
|
// loop register over range
|
||||||
|
if(stmt.loopRegister!=Register.A)
|
||||||
|
throw AssemblyError("can only use A")
|
||||||
|
translateExpression(range.to)
|
||||||
|
translateExpression(range.from)
|
||||||
|
out("""
|
||||||
|
inx
|
||||||
|
lda $ESTACK_LO_HEX,x
|
||||||
|
sta $loopLabel+1
|
||||||
|
inx
|
||||||
|
lda $ESTACK_LO_HEX,x
|
||||||
|
sec
|
||||||
|
sbc $loopLabel+1
|
||||||
|
adc #0
|
||||||
|
sta $counterLabel
|
||||||
|
$loopLabel lda #0 ; modified""")
|
||||||
|
translate(stmt.body)
|
||||||
|
out("""
|
||||||
|
$continueLabel dec $counterLabel
|
||||||
|
beq $endLabel
|
||||||
|
inc $loopLabel+1
|
||||||
|
jmp $loopLabel
|
||||||
|
$counterLabel .byte 0
|
||||||
|
$endLabel""")
|
||||||
|
} else {
|
||||||
|
// loop over byte range via loopvar
|
||||||
|
val varname = asmIdentifierName(stmt.loopVar!!)
|
||||||
|
translateExpression(range.to)
|
||||||
|
translateExpression(range.from)
|
||||||
|
out("""
|
||||||
|
inx
|
||||||
|
lda $ESTACK_LO_HEX,x
|
||||||
|
sta $varname
|
||||||
|
inx
|
||||||
|
lda $ESTACK_LO_HEX,x
|
||||||
|
sec
|
||||||
|
sbc $varname
|
||||||
|
adc #0
|
||||||
|
sta $counterLabel
|
||||||
|
$loopLabel""")
|
||||||
|
translate(stmt.body)
|
||||||
|
out("""
|
||||||
|
$continueLabel dec $counterLabel
|
||||||
|
beq $endLabel
|
||||||
|
inc $varname
|
||||||
|
jmp $loopLabel
|
||||||
|
$counterLabel .byte 0
|
||||||
|
$endLabel""")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DataType.ARRAY_UW, DataType.ARRAY_W -> {
|
||||||
|
TODO("loop over word range")
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("range expression can only be byte or word")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-1 -> {
|
||||||
|
TODO("non-const forloop with step -1")
|
||||||
|
}
|
||||||
|
else -> when (iterableDt) {
|
||||||
|
DataType.ARRAY_UB, DataType.ARRAY_B -> TODO()
|
||||||
|
DataType.ARRAY_UW, DataType.ARRAY_W -> TODO()
|
||||||
|
else -> throw AssemblyError("range expression can only be byte or word")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loopEndLabels.pop()
|
||||||
|
loopContinueLabels.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateForOverIterableVar(stmt: ForLoop, iterableDt: DataType, ident: IdentifierReference) {
|
private fun translateForOverIterableVar(stmt: ForLoop, iterableDt: DataType, ident: IdentifierReference) {
|
||||||
@ -1121,6 +1198,7 @@ $endLabel""")
|
|||||||
val loopLabel = makeLabel("for_loop")
|
val loopLabel = makeLabel("for_loop")
|
||||||
val endLabel = makeLabel("for_end")
|
val endLabel = makeLabel("for_end")
|
||||||
val continueLabel = makeLabel("for_continue")
|
val continueLabel = makeLabel("for_continue")
|
||||||
|
val counterLabel = makeLabel("for_counter")
|
||||||
loopEndLabels.push(endLabel)
|
loopEndLabels.push(endLabel)
|
||||||
loopContinueLabels.push(continueLabel)
|
loopContinueLabels.push(continueLabel)
|
||||||
when(iterableDt) {
|
when(iterableDt) {
|
||||||
@ -1134,7 +1212,6 @@ $endLabel""")
|
|||||||
when {
|
when {
|
||||||
range.step==1 -> {
|
range.step==1 -> {
|
||||||
// step = 1
|
// step = 1
|
||||||
val counterLabel = makeLabel("for_counter")
|
|
||||||
out("""
|
out("""
|
||||||
lda #${range.first}
|
lda #${range.first}
|
||||||
sta $loopLabel+1
|
sta $loopLabel+1
|
||||||
@ -1152,7 +1229,6 @@ $endLabel""")
|
|||||||
}
|
}
|
||||||
range.step==-1 -> {
|
range.step==-1 -> {
|
||||||
// step = -1
|
// step = -1
|
||||||
val counterLabel = makeLabel("for_counter")
|
|
||||||
out("""
|
out("""
|
||||||
lda #${range.first}
|
lda #${range.first}
|
||||||
sta $loopLabel+1
|
sta $loopLabel+1
|
||||||
@ -1170,7 +1246,6 @@ $endLabel""")
|
|||||||
}
|
}
|
||||||
range.step >= 2 -> {
|
range.step >= 2 -> {
|
||||||
// step >= 2
|
// step >= 2
|
||||||
val counterLabel = makeLabel("for_counter")
|
|
||||||
out("""
|
out("""
|
||||||
lda #${(range.last-range.first) / range.step + 1}
|
lda #${(range.last-range.first) / range.step + 1}
|
||||||
sta $counterLabel
|
sta $counterLabel
|
||||||
@ -1189,7 +1264,6 @@ $endLabel""")
|
|||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
// step <= -2
|
// step <= -2
|
||||||
val counterLabel = makeLabel("for_counter")
|
|
||||||
out("""
|
out("""
|
||||||
lda #${(range.first-range.last) / range.step.absoluteValue + 1}
|
lda #${(range.first-range.last) / range.step.absoluteValue + 1}
|
||||||
sta $counterLabel
|
sta $counterLabel
|
||||||
@ -1212,7 +1286,6 @@ $endLabel""")
|
|||||||
|
|
||||||
// loop over byte range via loopvar
|
// loop over byte range via loopvar
|
||||||
val varname = asmIdentifierName(stmt.loopVar!!)
|
val varname = asmIdentifierName(stmt.loopVar!!)
|
||||||
val counterLabel = makeLabel("for_counter")
|
|
||||||
when {
|
when {
|
||||||
range.step==1 -> {
|
range.step==1 -> {
|
||||||
// step = 1
|
// step = 1
|
||||||
@ -1293,7 +1366,6 @@ $endLabel""")
|
|||||||
}
|
}
|
||||||
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
||||||
// loop over word range via loopvar
|
// loop over word range via loopvar
|
||||||
val counterLabel = makeLabel("for_counter")
|
|
||||||
val varname = asmIdentifierName(stmt.loopVar!!)
|
val varname = asmIdentifierName(stmt.loopVar!!)
|
||||||
when {
|
when {
|
||||||
range.step == 1 -> {
|
range.step == 1 -> {
|
||||||
@ -1769,9 +1841,8 @@ $endLabel""")
|
|||||||
RegisterOrPair.AY -> out(" sta $ESTACK_LO_HEX,x | tya | sta $ESTACK_HI_HEX,x | dex")
|
RegisterOrPair.AY -> out(" sta $ESTACK_LO_HEX,x | tya | sta $ESTACK_HI_HEX,x | dex")
|
||||||
RegisterOrPair.X, RegisterOrPair.AX, RegisterOrPair.XY -> throw AssemblyError("can't push X register - use a variable")
|
RegisterOrPair.X, RegisterOrPair.AX, RegisterOrPair.XY -> throw AssemblyError("can't push X register - use a variable")
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
TODO("put return value from statusregister on stack $reg")
|
|
||||||
}
|
}
|
||||||
|
// return value from a statusregister is not put on the stack, it should be acted on via a conditional branch such as if_cc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,12 @@ main {
|
|||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
|
||||||
uword uw
|
for ubyte ub1 in 10 to 20 {
|
||||||
|
for ubyte ub2 in ub1 to 30 {
|
||||||
uw = c64utils.str2uword("12345")
|
c64scr.print_ub(ub2)
|
||||||
c64scr.print_uw(uw)
|
c64.CHROUT(',')
|
||||||
c64.CHROUT('\n')
|
}
|
||||||
|
c64.CHROUT('\n')
|
||||||
uw = c64utils.str2uword("11")
|
}
|
||||||
c64scr.print_uw(uw)
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user