implemented asm for continue and break

This commit is contained in:
Irmen de Jong 2019-08-04 16:05:50 +02:00
parent a1cd202cd2
commit 0431d3cddc
2 changed files with 73 additions and 47 deletions

View File

@ -36,9 +36,14 @@ internal class AsmGen2(val program: Program,
private val allocatedZeropageVariables = mutableMapOf<String, Pair<Int, DataType>>()
private val breakpointLabels = mutableListOf<String>()
private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, options, zeropage, this)
private val loopEndLabels = Stack<String>()
private val loopContinueLabels = Stack<String>()
internal fun compileToAssembly(optimize: Boolean): AssemblyProgram {
assemblyLines.clear()
loopEndLabels.clear()
loopContinueLabels.clear()
println("Generating assembly code... ")
header()
@ -619,8 +624,8 @@ internal class AsmGen2(val program: Program,
is BranchStatement -> translate(stmt)
is IfStatement -> translate(stmt)
is ForLoop -> translate(stmt)
is Continue -> TODO("continue")
is Break -> TODO("break")
is Continue -> out(" jmp ${loopContinueLabels.peek()}")
is Break -> out(" jmp ${loopEndLabels.peek()}")
is WhileLoop -> translate(stmt)
is RepeatLoop -> translate(stmt)
is WhenStatement -> translate(stmt)
@ -844,6 +849,8 @@ internal class AsmGen2(val program: Program,
private fun translate(stmt: WhileLoop) {
val whileLabel = makeLabel("while")
val endLabel = makeLabel("whileend")
loopEndLabels.push(endLabel)
loopContinueLabels.push(whileLabel)
out(whileLabel)
// TODO optimize for the simple cases, can we avoid stack use?
translateExpression(stmt.condition)
@ -861,10 +868,15 @@ internal class AsmGen2(val program: Program,
translate(stmt.body)
out(" jmp $whileLabel")
out(endLabel)
loopEndLabels.pop()
loopContinueLabels.pop()
}
private fun translate(stmt: RepeatLoop) {
val repeatLabel = makeLabel("repeat")
val endLabel = makeLabel("repeatend")
loopEndLabels.push(endLabel)
loopContinueLabels.push(repeatLabel)
out(repeatLabel)
// TODO optimize this for the simple cases, can we avoid stack use?
translate(stmt.body)
@ -880,6 +892,9 @@ internal class AsmGen2(val program: Program,
beq $repeatLabel
+ """)
}
out(endLabel)
loopEndLabels.pop()
loopContinueLabels.pop()
}
private fun translate(stmt: WhenStatement) {
@ -1014,6 +1029,9 @@ internal class AsmGen2(val program: Program,
private fun translateForOverIterableVar(stmt: ForLoop, iterableDt: DataType, ident: IdentifierReference) {
val loopLabel = makeLabel("for_loop")
val endLabel = makeLabel("for_end")
val continueLabel = makeLabel("for_continue")
loopEndLabels.push(endLabel)
loopContinueLabels.push(continueLabel)
val iterableName = asmIdentifierName(ident)
val decl = ident.targetVarDecl(program.namespace)!!
when(iterableDt) {
@ -1031,7 +1049,7 @@ $loopLabel lda ${65535.toHex()} ; modified
out(" sta ${asmIdentifierName(stmt.loopVar!!)}")
translate(stmt.body)
out("""
inc $loopLabel+1
$continueLabel inc $loopLabel+1
bne $loopLabel
inc $loopLabel+2
bne $loopLabel
@ -1055,7 +1073,7 @@ $modifiedLabel lda ${65535.toHex()},y ; modified""")
out(" sta ${asmIdentifierName(stmt.loopVar!!)}")
translate(stmt.body)
out("""
ldy $counterLabel
$continueLabel ldy $counterLabel
iny
cpy #${length and 255}
beq $endLabel
@ -1088,7 +1106,7 @@ $modifiedLabel2 lda ${65535.toHex()},y ; modified
sta $loopvarName+1""")
translate(stmt.body)
out("""
ldy $counterLabel
$continueLabel ldy $counterLabel
iny
iny
cpy #${length and 255}
@ -1102,11 +1120,16 @@ $endLabel""")
}
else -> throw AssemblyError("can't iterate over $iterableDt")
}
loopEndLabels.pop()
loopContinueLabels.pop()
}
private fun translateForOverConstRange(stmt: ForLoop, iterableDt: DataType, range: IntProgression) {
val loopLabel = makeLabel("for_loop")
val endLabel = makeLabel("for_end")
val continueLabel = makeLabel("for_continue")
loopEndLabels.push(endLabel)
loopContinueLabels.push(continueLabel)
when(iterableDt) {
DataType.ARRAY_B, DataType.ARRAY_UB -> {
if(stmt.loopRegister!=null) {
@ -1127,7 +1150,7 @@ $endLabel""")
$loopLabel lda #0 ; modified""")
translate(stmt.body)
out("""
dec $counterLabel
$continueLabel dec $counterLabel
beq $endLabel
inc $loopLabel+1
jmp $loopLabel
@ -1145,7 +1168,7 @@ $endLabel""")
$loopLabel lda #0 ; modified """)
translate(stmt.body)
out("""
dec $counterLabel
$continueLabel dec $counterLabel
beq $endLabel
dec $loopLabel+1
jmp $loopLabel
@ -1162,7 +1185,7 @@ $endLabel""")
$loopLabel pha""")
translate(stmt.body)
out("""
pla
$continueLabel pla
dec $counterLabel
beq $endLabel
clc
@ -1181,7 +1204,7 @@ $endLabel""")
$loopLabel pha""")
translate(stmt.body)
out("""
pla
$continueLabel pla
dec $counterLabel
beq $endLabel
sec
@ -1208,7 +1231,7 @@ $endLabel""")
$loopLabel""")
translate(stmt.body)
out("""
dec $counterLabel
$continueLabel dec $counterLabel
beq $endLabel
inc $varname
jmp $loopLabel
@ -1225,7 +1248,7 @@ $endLabel""")
$loopLabel""")
translate(stmt.body)
out("""
dec $counterLabel
$continueLabel dec $counterLabel
beq $endLabel
dec $varname
jmp $loopLabel
@ -1242,7 +1265,7 @@ $endLabel""")
$loopLabel""")
translate(stmt.body)
out("""
dec $counterLabel
$continueLabel dec $counterLabel
beq $endLabel
lda $varname
clc
@ -1262,7 +1285,7 @@ $endLabel""")
$loopLabel""")
translate(stmt.body)
out("""
dec $counterLabel
$continueLabel dec $counterLabel
beq $endLabel
lda $varname
sec
@ -1292,7 +1315,7 @@ $endLabel""")
$loopLabel""")
translate(stmt.body)
out("""
dec $counterLabel
$continueLabel dec $counterLabel
beq $endLabel
inc $varname
bne $loopLabel
@ -1313,7 +1336,7 @@ $endLabel""")
$loopLabel""")
translate(stmt.body)
out("""
dec $counterLabel
$continueLabel dec $counterLabel
beq $endLabel
lda $varname
bne +
@ -1335,7 +1358,7 @@ $endLabel""")
$loopLabel""")
translate(stmt.body)
out("""
dec $counterLabel
$continueLabel dec $counterLabel
beq $endLabel
clc
lda $varname
@ -1360,7 +1383,7 @@ $endLabel""")
$loopLabel""")
translate(stmt.body)
out("""
dec $counterLabel
$continueLabel dec $counterLabel
beq $endLabel
sec
lda $varname
@ -1377,6 +1400,8 @@ $endLabel""")
}
else -> throw AssemblyError("range expression can only be byte or word")
}
loopEndLabels.pop()
loopContinueLabels.pop()
}
private fun translate(stmt: PostIncrDecr) {

View File

@ -5,38 +5,39 @@
main {
ubyte[10] barray
uword[10] warray
float[10] farray
&ubyte memubarray = 1000
&uword memuwarray = 1000
&float memfltarray = 1000
sub start() {
ubyte i
uword uw
float fl = farray[2]
ubyte ub=0
while ub<30 {
ub++
if ub < 5
continue
c64scr.print_ub(ub)
c64.CHROUT(',')
if ub >= 10
break
}
c64.CHROUT('\n')
barray[4] = 4
barray[i] = 4
barray[i+4] = 4
memubarray[4] = 4
memubarray[i] = 4
memubarray[i+4] = 4
ub=0
repeat {
ub++
if ub < 5
continue
c64scr.print_ub(ub)
c64.CHROUT(',')
if ub>=10
break
} until ub>30
c64.CHROUT('\n')
warray[4] = 4
warray[i] = 4
warray[i+4] = 4
memuwarray[4] = 4
memuwarray[i] = 4
memuwarray[i+4] = 4
farray[4] = 4
farray[i] = 4
farray[i+4] = 4
memfltarray[4] = 4
memfltarray[i] = 4
memfltarray[i+4] = 4
for ub in 1 to 30 {
if ub < 5
continue
c64scr.print_ub(ub)
c64.CHROUT(',')
if ub >=10
break
}
c64.CHROUT('\n')
}
}