mirror of
https://github.com/irmen/prog8.git
synced 2024-09-08 10:55:08 +00:00
implemented asm for continue and break
This commit is contained in:
parent
a1cd202cd2
commit
0431d3cddc
@ -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) {
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user