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

View File

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