mirror of
https://github.com/irmen/prog8.git
synced 2024-07-10 23:29:02 +00:00
more for loops
This commit is contained in:
parent
299ea72d70
commit
82f01d84c2
@ -965,11 +965,14 @@ internal class AsmGen2(val program: Program,
|
|||||||
when(iterableDt) {
|
when(iterableDt) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
if(stmt.loopRegister!=null) {
|
if(stmt.loopRegister!=null) {
|
||||||
// loop register
|
|
||||||
|
// loop register over range
|
||||||
|
|
||||||
if(stmt.loopRegister!=Register.A)
|
if(stmt.loopRegister!=Register.A)
|
||||||
throw AssemblyError("can only use A")
|
throw AssemblyError("can only use A")
|
||||||
when {
|
when {
|
||||||
range.step==1 -> {
|
range.step==1 -> {
|
||||||
|
// step = 1
|
||||||
val counterLabel = makeLabel("for_counter")
|
val counterLabel = makeLabel("for_counter")
|
||||||
out("""
|
out("""
|
||||||
lda #${range.first}
|
lda #${range.first}
|
||||||
@ -987,6 +990,7 @@ $counterLabel .byte 0
|
|||||||
$endLabel""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
range.step==-1 -> {
|
range.step==-1 -> {
|
||||||
|
// step = -1
|
||||||
val counterLabel = makeLabel("for_counter")
|
val counterLabel = makeLabel("for_counter")
|
||||||
out("""
|
out("""
|
||||||
lda #${range.first}
|
lda #${range.first}
|
||||||
@ -1004,6 +1008,7 @@ $counterLabel .byte 0
|
|||||||
$endLabel""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
range.step>0 -> {
|
range.step>0 -> {
|
||||||
|
// step >= 2
|
||||||
val counterLabel = makeLabel("for_counter")
|
val counterLabel = makeLabel("for_counter")
|
||||||
out("""
|
out("""
|
||||||
lda #${(range.last-range.first) / range.step + 1}
|
lda #${(range.last-range.first) / range.step + 1}
|
||||||
@ -1022,6 +1027,7 @@ $counterLabel .byte 0
|
|||||||
$endLabel""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
// step <= -2
|
||||||
val counterLabel = makeLabel("for_counter")
|
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}
|
||||||
@ -1040,8 +1046,91 @@ $counterLabel .byte 0
|
|||||||
$endLabel""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
TODO("loop over byte range via loopvar $stmt")
|
|
||||||
|
// loop over byte range via loopvar
|
||||||
|
val varname = asmIdentifierName(stmt.loopVar!!)
|
||||||
|
when {
|
||||||
|
range.step==1 -> {
|
||||||
|
// step = 1
|
||||||
|
val counterLabel = makeLabel("for_counter")
|
||||||
|
out("""
|
||||||
|
lda #${range.first}
|
||||||
|
sta $varname
|
||||||
|
lda #${range.last-range.first+1 and 255}
|
||||||
|
sta $counterLabel
|
||||||
|
$loopLabel""")
|
||||||
|
translate(stmt.body)
|
||||||
|
out("""
|
||||||
|
dec $counterLabel
|
||||||
|
beq $endLabel
|
||||||
|
inc $varname
|
||||||
|
jmp $loopLabel
|
||||||
|
$counterLabel .byte 0
|
||||||
|
$endLabel""")
|
||||||
|
}
|
||||||
|
range.step==-1 -> {
|
||||||
|
// step = -1
|
||||||
|
val counterLabel = makeLabel("for_counter")
|
||||||
|
out("""
|
||||||
|
lda #${range.first}
|
||||||
|
sta $varname
|
||||||
|
lda #${range.first-range.last+1 and 255}
|
||||||
|
sta $counterLabel
|
||||||
|
$loopLabel""")
|
||||||
|
translate(stmt.body)
|
||||||
|
out("""
|
||||||
|
dec $counterLabel
|
||||||
|
beq $endLabel
|
||||||
|
dec $varname
|
||||||
|
jmp $loopLabel
|
||||||
|
$counterLabel .byte 0
|
||||||
|
$endLabel""")
|
||||||
|
}
|
||||||
|
range.step>0 -> {
|
||||||
|
// step >= 2
|
||||||
|
val counterLabel = makeLabel("for_counter")
|
||||||
|
out("""
|
||||||
|
lda #${(range.last-range.first) / range.step + 1}
|
||||||
|
sta $counterLabel
|
||||||
|
lda #${range.first}
|
||||||
|
sta $varname
|
||||||
|
$loopLabel""")
|
||||||
|
translate(stmt.body)
|
||||||
|
out("""
|
||||||
|
dec $counterLabel
|
||||||
|
beq $endLabel
|
||||||
|
lda $varname
|
||||||
|
clc
|
||||||
|
adc #${range.step}
|
||||||
|
sta $varname
|
||||||
|
jmp $loopLabel
|
||||||
|
$counterLabel .byte 0
|
||||||
|
$endLabel""")
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
// step <= -2
|
||||||
|
val counterLabel = makeLabel("for_counter")
|
||||||
|
out("""
|
||||||
|
lda #${(range.first-range.last) / range.step.absoluteValue + 1}
|
||||||
|
sta $counterLabel
|
||||||
|
lda #${range.first}
|
||||||
|
sta $varname
|
||||||
|
$loopLabel""")
|
||||||
|
translate(stmt.body)
|
||||||
|
out("""
|
||||||
|
dec $counterLabel
|
||||||
|
beq $endLabel
|
||||||
|
lda $varname
|
||||||
|
sec
|
||||||
|
sbc #${range.step.absoluteValue}
|
||||||
|
sta $varname
|
||||||
|
jmp $loopLabel
|
||||||
|
$counterLabel .byte 0
|
||||||
|
$endLabel""")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
in WordDatatypes -> {
|
||||||
@ -1056,37 +1145,32 @@ $endLabel""")
|
|||||||
val decl = ident.targetVarDecl(program.namespace)!!
|
val decl = ident.targetVarDecl(program.namespace)!!
|
||||||
when(iterableDt) {
|
when(iterableDt) {
|
||||||
DataType.STR, DataType.STR_S -> {
|
DataType.STR, DataType.STR_S -> {
|
||||||
if(stmt.loopRegister!=null) {
|
if(stmt.loopRegister!=null && stmt.loopRegister!=Register.A)
|
||||||
// loop register
|
throw AssemblyError("can only use A")
|
||||||
if(stmt.loopRegister!=Register.A)
|
out("""
|
||||||
throw AssemblyError("can only use A")
|
|
||||||
out("""
|
|
||||||
lda #<$iterableName
|
lda #<$iterableName
|
||||||
ldy #>$iterableName
|
ldy #>$iterableName
|
||||||
sta $loopLabel+1
|
sta $loopLabel+1
|
||||||
sty $loopLabel+2
|
sty $loopLabel+2
|
||||||
$loopLabel lda ${65535.toHex()} ; modified
|
$loopLabel lda ${65535.toHex()} ; modified
|
||||||
beq $endLabel""")
|
beq $endLabel""")
|
||||||
translate(stmt.body)
|
if(stmt.loopVar!=null)
|
||||||
out("""
|
out(" sta ${asmIdentifierName(stmt.loopVar!!)}")
|
||||||
|
translate(stmt.body)
|
||||||
|
out("""
|
||||||
inc $loopLabel+1
|
inc $loopLabel+1
|
||||||
bne $loopLabel
|
bne $loopLabel
|
||||||
inc $loopLabel+2
|
inc $loopLabel+2
|
||||||
bne $loopLabel
|
bne $loopLabel
|
||||||
$endLabel""")
|
$endLabel""")
|
||||||
} else {
|
|
||||||
TODO("loop over string via loopvar $stmt")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
||||||
val length = decl.arraysize!!.size()
|
val length = decl.arraysize!!.size()
|
||||||
if(stmt.loopRegister!=null) {
|
if(stmt.loopRegister!=null && stmt.loopRegister!=Register.A)
|
||||||
// loop register
|
throw AssemblyError("can only use A")
|
||||||
if(stmt.loopRegister!=Register.A)
|
val counterLabel = makeLabel("for_counter")
|
||||||
throw AssemblyError("can only use A")
|
val modifiedLabel = makeLabel("for_modified")
|
||||||
val counterLabel = makeLabel("for_counter")
|
out("""
|
||||||
val modifiedLabel = makeLabel("for_modified")
|
|
||||||
out("""
|
|
||||||
lda #<$iterableName
|
lda #<$iterableName
|
||||||
ldy #>$iterableName
|
ldy #>$iterableName
|
||||||
sta $modifiedLabel+1
|
sta $modifiedLabel+1
|
||||||
@ -1095,18 +1179,16 @@ $endLabel""")
|
|||||||
$loopLabel sty $counterLabel
|
$loopLabel sty $counterLabel
|
||||||
cpy #$length
|
cpy #$length
|
||||||
beq $endLabel
|
beq $endLabel
|
||||||
$modifiedLabel lda ${65535.toHex()},y ; modified
|
$modifiedLabel lda ${65535.toHex()},y ; modified""")
|
||||||
""")
|
if(stmt.loopVar!=null)
|
||||||
translate(stmt.body)
|
out(" sta ${asmIdentifierName(stmt.loopVar!!)}")
|
||||||
out("""
|
translate(stmt.body)
|
||||||
|
out("""
|
||||||
ldy $counterLabel
|
ldy $counterLabel
|
||||||
iny
|
iny
|
||||||
jmp $loopLabel
|
jmp $loopLabel
|
||||||
$counterLabel .byte 0
|
$counterLabel .byte 0
|
||||||
$endLabel""")
|
$endLabel""")
|
||||||
} else {
|
|
||||||
TODO("loop variable over bytearray of len $length")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
||||||
val length = decl.arraysize!!.size()
|
val length = decl.arraysize!!.size()
|
||||||
|
@ -11,7 +11,7 @@ main {
|
|||||||
sub start() {
|
sub start() {
|
||||||
c64scr.print("fibonacci sequence\n")
|
c64scr.print("fibonacci sequence\n")
|
||||||
fib_setup()
|
fib_setup()
|
||||||
for ubyte i in 0 to 20 {
|
for A in 0 to 20 {
|
||||||
c64scr.print_uw(fib_next())
|
c64scr.print_uw(fib_next())
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
}
|
}
|
||||||
|
@ -43,24 +43,45 @@ main {
|
|||||||
c64.CHROUT(',')
|
c64.CHROUT(',')
|
||||||
}
|
}
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
|
for ubyte cc in "hello" {
|
||||||
|
c64scr.print_ub(cc)
|
||||||
|
c64.CHROUT(',')
|
||||||
|
}
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
|
for ubyte cc2 in [1,3,5,99] {
|
||||||
|
c64scr.print_ub(cc2)
|
||||||
|
c64.CHROUT(',')
|
||||||
|
}
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
|
for ubyte cc3 in 10 to 20 {
|
||||||
|
c64scr.print_ub(cc3)
|
||||||
|
c64.CHROUT(',')
|
||||||
|
}
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
|
for ubyte cc4 in 20 to 10 step -1 {
|
||||||
|
c64scr.print_ub(cc4)
|
||||||
|
c64.CHROUT(',')
|
||||||
|
}
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
|
for ubyte cc5 in 10 to 21 step 3 {
|
||||||
|
c64scr.print_ub(cc5)
|
||||||
|
c64.CHROUT(',')
|
||||||
|
}
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
|
for ubyte cc6 in 24 to 10 step -3 {
|
||||||
|
c64scr.print_ub(cc6)
|
||||||
|
c64.CHROUT(',')
|
||||||
|
}
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
; for var2 in 10 to 20 {
|
|
||||||
; c64scr.print_ub(var2)
|
|
||||||
; c64.CHROUT(',')
|
|
||||||
; }
|
|
||||||
; c64.CHROUT('\n')
|
|
||||||
;
|
|
||||||
; for ubyte var3 in 10 to 20 {
|
|
||||||
; c64scr.print_ub(var3)
|
|
||||||
; c64.CHROUT(',')
|
|
||||||
; }
|
|
||||||
; c64.CHROUT('\n')
|
|
||||||
;
|
|
||||||
; for bvar in -5 to 5 {
|
|
||||||
; c64scr.print_b(bvar)
|
|
||||||
; c64.CHROUT(',')
|
|
||||||
; }
|
|
||||||
; c64.CHROUT('\n')
|
|
||||||
|
|
||||||
; for float fl in [1.1, 2.2, 5.5, 99.99] {
|
; for float fl in [1.1, 2.2, 5.5, 99.99] {
|
||||||
; c64flt.print_f(fl)
|
; c64flt.print_f(fl)
|
||||||
|
Loading…
Reference in New Issue
Block a user