mirror of
https://github.com/irmen/prog8.git
synced 2024-10-19 07:23:56 +00:00
more for loops, words
This commit is contained in:
parent
82f01d84c2
commit
3f4050c647
@ -150,14 +150,14 @@ internal class AstChecker(private val program: Program,
|
|||||||
checkResult.add(ExpressionError("word loop variable can only loop over bytes or words", forLoop.position))
|
checkResult.add(ExpressionError("word loop variable can only loop over bytes or words", forLoop.position))
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
if(iterableDt!= DataType.FLOAT && iterableDt != DataType.ARRAY_F)
|
checkResult.add(ExpressionError("for loop only supports integers", forLoop.position))
|
||||||
checkResult.add(ExpressionError("float loop variable can only loop over floats", forLoop.position))
|
|
||||||
}
|
}
|
||||||
else -> checkResult.add(ExpressionError("loop variable must be numeric type", forLoop.position))
|
else -> checkResult.add(ExpressionError("loop variable must be numeric type", forLoop.position))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.visit(forLoop)
|
super.visit(forLoop)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -772,8 +772,11 @@ internal class AstChecker(private val program: Program,
|
|||||||
super.visit(range)
|
super.visit(range)
|
||||||
val from = range.from.constValue(program)
|
val from = range.from.constValue(program)
|
||||||
val to = range.to.constValue(program)
|
val to = range.to.constValue(program)
|
||||||
val stepLv = range.step.constValue(program) ?: NumericLiteralValue(DataType.UBYTE, 1, range.position)
|
val stepLv = range.step.constValue(program)
|
||||||
if (stepLv.type !in IntegerDatatypes || stepLv.number.toInt() == 0) {
|
if(stepLv==null) {
|
||||||
|
err("range step must be a constant integer")
|
||||||
|
return
|
||||||
|
} else if (stepLv.type !in IntegerDatatypes || stepLv.number.toInt() == 0) {
|
||||||
err("range step must be an integer != 0")
|
err("range step must be an integer != 0")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -952,195 +952,32 @@ internal class AsmGen2(val program: Program,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translate(stmt: ForLoop) {
|
private fun translate(stmt: ForLoop) {
|
||||||
val iterableDt = stmt.iterable.inferType(program)
|
val iterableDt = stmt.iterable.inferType(program)!!
|
||||||
val loopLabel = makeLabel("for_loop")
|
|
||||||
val endLabel = makeLabel("for_end")
|
|
||||||
when(stmt.iterable) {
|
when(stmt.iterable) {
|
||||||
is RangeExpr -> {
|
is RangeExpr -> {
|
||||||
val range = (stmt.iterable as RangeExpr).toConstantIntegerRange()
|
val range = (stmt.iterable as RangeExpr).toConstantIntegerRange()
|
||||||
if(range==null)
|
if(range==null) {
|
||||||
TODO("non-const range loop")
|
translateForOverNonconstRange(stmt, iterableDt, stmt.iterable as RangeExpr)
|
||||||
if(range.isEmpty())
|
|
||||||
throw AssemblyError("empty range")
|
|
||||||
when(iterableDt) {
|
|
||||||
in ByteDatatypes -> {
|
|
||||||
if(stmt.loopRegister!=null) {
|
|
||||||
|
|
||||||
// loop register over range
|
|
||||||
|
|
||||||
if(stmt.loopRegister!=Register.A)
|
|
||||||
throw AssemblyError("can only use A")
|
|
||||||
when {
|
|
||||||
range.step==1 -> {
|
|
||||||
// step = 1
|
|
||||||
val counterLabel = makeLabel("for_counter")
|
|
||||||
out("""
|
|
||||||
lda #${range.first}
|
|
||||||
sta $loopLabel+1
|
|
||||||
lda #${range.last-range.first+1 and 255}
|
|
||||||
sta $counterLabel
|
|
||||||
$loopLabel lda #0 ; modified""")
|
|
||||||
translate(stmt.body)
|
|
||||||
out("""
|
|
||||||
dec $counterLabel
|
|
||||||
beq $endLabel
|
|
||||||
inc $loopLabel+1
|
|
||||||
jmp $loopLabel
|
|
||||||
$counterLabel .byte 0
|
|
||||||
$endLabel""")
|
|
||||||
}
|
|
||||||
range.step==-1 -> {
|
|
||||||
// step = -1
|
|
||||||
val counterLabel = makeLabel("for_counter")
|
|
||||||
out("""
|
|
||||||
lda #${range.first}
|
|
||||||
sta $loopLabel+1
|
|
||||||
lda #${range.first-range.last+1 and 255}
|
|
||||||
sta $counterLabel
|
|
||||||
$loopLabel lda #0 ; modified """)
|
|
||||||
translate(stmt.body)
|
|
||||||
out("""
|
|
||||||
dec $counterLabel
|
|
||||||
beq $endLabel
|
|
||||||
dec $loopLabel+1
|
|
||||||
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}
|
|
||||||
$loopLabel pha""")
|
|
||||||
translate(stmt.body)
|
|
||||||
out("""
|
|
||||||
pla
|
|
||||||
dec $counterLabel
|
|
||||||
beq $endLabel
|
|
||||||
clc
|
|
||||||
adc #${range.step}
|
|
||||||
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}
|
|
||||||
$loopLabel pha""")
|
|
||||||
translate(stmt.body)
|
|
||||||
out("""
|
|
||||||
pla
|
|
||||||
dec $counterLabel
|
|
||||||
beq $endLabel
|
|
||||||
sec
|
|
||||||
sbc #${range.step.absoluteValue}
|
|
||||||
jmp $loopLabel
|
|
||||||
$counterLabel .byte 0
|
|
||||||
$endLabel""")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
if (range.isEmpty())
|
||||||
// loop over byte range via loopvar
|
throw AssemblyError("empty range")
|
||||||
val varname = asmIdentifierName(stmt.loopVar!!)
|
translateForOverConstRange(stmt, iterableDt, range)
|
||||||
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 -> {
|
|
||||||
TODO("forloop over word range $stmt") // TODO
|
|
||||||
}
|
|
||||||
else -> throw AssemblyError("range expression can only be byte or word")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is IdentifierReference -> {
|
is IdentifierReference -> {
|
||||||
val ident = (stmt.iterable as IdentifierReference)
|
translateForOverIterableVar(stmt, iterableDt, stmt.iterable as IdentifierReference)
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("can't iterate over ${stmt.iterable}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun translateForOverNonconstRange(stmt: ForLoop, iterableDt: DataType, range: RangeExpr) {
|
||||||
|
TODO("non-const range loop")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun translateForOverIterableVar(stmt: ForLoop, iterableDt: DataType, ident: IdentifierReference) {
|
||||||
|
val loopLabel = makeLabel("for_loop")
|
||||||
|
val endLabel = makeLabel("for_end")
|
||||||
val iterableName = asmIdentifierName(ident)
|
val iterableName = asmIdentifierName(ident)
|
||||||
val decl = ident.targetVarDecl(program.namespace)!!
|
val decl = ident.targetVarDecl(program.namespace)!!
|
||||||
when(iterableDt) {
|
when(iterableDt) {
|
||||||
@ -1191,27 +1028,318 @@ $counterLabel .byte 0
|
|||||||
$endLabel""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
||||||
val length = decl.arraysize!!.size()
|
val length = decl.arraysize!!.size()!! * 2
|
||||||
println("forloop over word array len $length $stmt") // TODO
|
if(stmt.loopRegister!=null)
|
||||||
if(stmt.loopRegister!=null) {
|
throw AssemblyError("can't use register to loop over words")
|
||||||
TODO("loop register over wordarray of len $length")
|
val counterLabel = makeLabel("for_counter")
|
||||||
} else {
|
val modifiedLabel = makeLabel("for_modified")
|
||||||
TODO("loop variable over wordarray of len $length")
|
val modifiedLabel2 = makeLabel("for_modified2")
|
||||||
}
|
val loopvarName = asmIdentifierName(stmt.loopVar!!)
|
||||||
|
out("""
|
||||||
|
lda #<$iterableName
|
||||||
|
ldy #>$iterableName
|
||||||
|
sta $modifiedLabel+1
|
||||||
|
sty $modifiedLabel+2
|
||||||
|
lda #<$iterableName+1
|
||||||
|
ldy #>$iterableName+1
|
||||||
|
sta $modifiedLabel2+1
|
||||||
|
sty $modifiedLabel2+2
|
||||||
|
ldy #0
|
||||||
|
$loopLabel sty $counterLabel
|
||||||
|
cpy #$length
|
||||||
|
beq $endLabel
|
||||||
|
$modifiedLabel lda ${65535.toHex()},y ; modified
|
||||||
|
sta $loopvarName
|
||||||
|
$modifiedLabel2 lda ${65535.toHex()},y ; modified
|
||||||
|
sta $loopvarName+1""")
|
||||||
|
translate(stmt.body)
|
||||||
|
out("""
|
||||||
|
ldy $counterLabel
|
||||||
|
iny
|
||||||
|
iny
|
||||||
|
jmp $loopLabel
|
||||||
|
$counterLabel .byte 0
|
||||||
|
$endLabel""")
|
||||||
}
|
}
|
||||||
DataType.ARRAY_F -> {
|
DataType.ARRAY_F -> {
|
||||||
val length = decl.arraysize!!.size()
|
throw AssemblyError("for loop with floating point variables is not supported")
|
||||||
println("forloop over float array len $length $stmt") // TODO
|
|
||||||
if(stmt.loopRegister!=null) {
|
|
||||||
throw AssemblyError("can't use register to loop over floats")
|
|
||||||
} else {
|
|
||||||
TODO("loop variable over floatarray of len $length")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("can't iterate over $iterableDt")
|
else -> throw AssemblyError("can't iterate over $iterableDt")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("can't iterate over ${stmt.iterable}")
|
|
||||||
|
private fun translateForOverConstRange(stmt: ForLoop, iterableDt: DataType, range: IntProgression) {
|
||||||
|
val loopLabel = makeLabel("for_loop")
|
||||||
|
val endLabel = makeLabel("for_end")
|
||||||
|
when(iterableDt) {
|
||||||
|
in ByteDatatypes -> {
|
||||||
|
if(stmt.loopRegister!=null) {
|
||||||
|
|
||||||
|
// loop register over range
|
||||||
|
|
||||||
|
if(stmt.loopRegister!=Register.A)
|
||||||
|
throw AssemblyError("can only use A")
|
||||||
|
when {
|
||||||
|
range.step==1 -> {
|
||||||
|
// step = 1
|
||||||
|
val counterLabel = makeLabel("for_counter")
|
||||||
|
out("""
|
||||||
|
lda #${range.first}
|
||||||
|
sta $loopLabel+1
|
||||||
|
lda #${range.last-range.first+1 and 255}
|
||||||
|
sta $counterLabel
|
||||||
|
$loopLabel lda #0 ; modified""")
|
||||||
|
translate(stmt.body)
|
||||||
|
out("""
|
||||||
|
dec $counterLabel
|
||||||
|
beq $endLabel
|
||||||
|
inc $loopLabel+1
|
||||||
|
jmp $loopLabel
|
||||||
|
$counterLabel .byte 0
|
||||||
|
$endLabel""")
|
||||||
|
}
|
||||||
|
range.step==-1 -> {
|
||||||
|
// step = -1
|
||||||
|
val counterLabel = makeLabel("for_counter")
|
||||||
|
out("""
|
||||||
|
lda #${range.first}
|
||||||
|
sta $loopLabel+1
|
||||||
|
lda #${range.first-range.last+1 and 255}
|
||||||
|
sta $counterLabel
|
||||||
|
$loopLabel lda #0 ; modified """)
|
||||||
|
translate(stmt.body)
|
||||||
|
out("""
|
||||||
|
dec $counterLabel
|
||||||
|
beq $endLabel
|
||||||
|
dec $loopLabel+1
|
||||||
|
jmp $loopLabel
|
||||||
|
$counterLabel .byte 0
|
||||||
|
$endLabel""")
|
||||||
|
}
|
||||||
|
range.step >= 2 -> {
|
||||||
|
// step >= 2
|
||||||
|
val counterLabel = makeLabel("for_counter")
|
||||||
|
out("""
|
||||||
|
lda #${(range.last-range.first) / range.step + 1}
|
||||||
|
sta $counterLabel
|
||||||
|
lda #${range.first}
|
||||||
|
$loopLabel pha""")
|
||||||
|
translate(stmt.body)
|
||||||
|
out("""
|
||||||
|
pla
|
||||||
|
dec $counterLabel
|
||||||
|
beq $endLabel
|
||||||
|
clc
|
||||||
|
adc #${range.step}
|
||||||
|
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}
|
||||||
|
$loopLabel pha""")
|
||||||
|
translate(stmt.body)
|
||||||
|
out("""
|
||||||
|
pla
|
||||||
|
dec $counterLabel
|
||||||
|
beq $endLabel
|
||||||
|
sec
|
||||||
|
sbc #${range.step.absoluteValue}
|
||||||
|
jmp $loopLabel
|
||||||
|
$counterLabel .byte 0
|
||||||
|
$endLabel""")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// loop over byte range via loopvar
|
||||||
|
val varname = asmIdentifierName(stmt.loopVar!!)
|
||||||
|
val counterLabel = makeLabel("for_counter")
|
||||||
|
when {
|
||||||
|
range.step==1 -> {
|
||||||
|
// step = 1
|
||||||
|
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
|
||||||
|
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 >= 2 -> {
|
||||||
|
// step >= 2
|
||||||
|
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
|
||||||
|
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 -> {
|
||||||
|
// loop over word range via loopvar
|
||||||
|
val counterLabel = makeLabel("for_counter")
|
||||||
|
val varname = asmIdentifierName(stmt.loopVar!!)
|
||||||
|
when {
|
||||||
|
range.step == 1 -> {
|
||||||
|
// step = 1
|
||||||
|
out("""
|
||||||
|
lda #<${range.first}
|
||||||
|
ldy #>${range.first}
|
||||||
|
sta $varname
|
||||||
|
sty $varname+1
|
||||||
|
lda #${range.last - range.first + 1 and 255}
|
||||||
|
sta $counterLabel
|
||||||
|
$loopLabel""")
|
||||||
|
translate(stmt.body)
|
||||||
|
out("""
|
||||||
|
dec $counterLabel
|
||||||
|
beq $endLabel
|
||||||
|
inc $varname
|
||||||
|
bne $loopLabel
|
||||||
|
inc $varname+1
|
||||||
|
jmp $loopLabel
|
||||||
|
$counterLabel .byte 0
|
||||||
|
$endLabel""")
|
||||||
|
}
|
||||||
|
range.step == -1 -> {
|
||||||
|
// step = 1
|
||||||
|
out("""
|
||||||
|
lda #<${range.first}
|
||||||
|
ldy #>${range.first}
|
||||||
|
sta $varname
|
||||||
|
sty $varname+1
|
||||||
|
lda #${range.first - range.last + 1 and 255}
|
||||||
|
sta $counterLabel
|
||||||
|
$loopLabel""")
|
||||||
|
translate(stmt.body)
|
||||||
|
out("""
|
||||||
|
dec $counterLabel
|
||||||
|
beq $endLabel
|
||||||
|
lda $varname
|
||||||
|
bne +
|
||||||
|
dec $varname+1
|
||||||
|
+ dec $varname
|
||||||
|
jmp $loopLabel
|
||||||
|
$counterLabel .byte 0
|
||||||
|
$endLabel""")
|
||||||
|
}
|
||||||
|
range.step >= 2 -> {
|
||||||
|
// step >= 2
|
||||||
|
out("""
|
||||||
|
lda #<${range.first}
|
||||||
|
ldy #>${range.first}
|
||||||
|
sta $varname
|
||||||
|
sty $varname+1
|
||||||
|
lda #${(range.last-range.first) / range.step + 1}
|
||||||
|
sta $counterLabel
|
||||||
|
$loopLabel""")
|
||||||
|
translate(stmt.body)
|
||||||
|
out("""
|
||||||
|
dec $counterLabel
|
||||||
|
beq $endLabel
|
||||||
|
clc
|
||||||
|
lda $varname
|
||||||
|
adc #<${range.step}
|
||||||
|
sta $varname
|
||||||
|
lda $varname+1
|
||||||
|
adc #>${range.step}
|
||||||
|
sta $varname+1
|
||||||
|
jmp $loopLabel
|
||||||
|
$counterLabel .byte 0
|
||||||
|
$endLabel""")
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
// step <= -2
|
||||||
|
out("""
|
||||||
|
lda #<${range.first}
|
||||||
|
ldy #>${range.first}
|
||||||
|
sta $varname
|
||||||
|
sty $varname+1
|
||||||
|
lda #${(range.first-range.last) / range.step.absoluteValue + 1}
|
||||||
|
sta $counterLabel
|
||||||
|
$loopLabel""")
|
||||||
|
translate(stmt.body)
|
||||||
|
out("""
|
||||||
|
dec $counterLabel
|
||||||
|
beq $endLabel
|
||||||
|
sec
|
||||||
|
lda $varname
|
||||||
|
sbc #<${range.step.absoluteValue}
|
||||||
|
sta $varname
|
||||||
|
lda $varname+1
|
||||||
|
sbc #>${range.step.absoluteValue}
|
||||||
|
sta $varname+1
|
||||||
|
jmp $loopLabel
|
||||||
|
$counterLabel .byte 0
|
||||||
|
$endLabel""")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("range expression can only be byte or word")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,9 @@ main {
|
|||||||
byte bvar
|
byte bvar
|
||||||
ubyte var2
|
ubyte var2
|
||||||
|
|
||||||
|
ubyte[] barr = [22,33,44,55,66]
|
||||||
|
word[] warr = [-111,222,-333,444]
|
||||||
|
|
||||||
for A in "hello" {
|
for A in "hello" {
|
||||||
c64scr.print_ub(A)
|
c64scr.print_ub(A)
|
||||||
c64.CHROUT(',')
|
c64.CHROUT(',')
|
||||||
@ -43,6 +46,12 @@ main {
|
|||||||
c64.CHROUT(',')
|
c64.CHROUT(',')
|
||||||
}
|
}
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
|
for A in barr {
|
||||||
|
c64scr.print_ub(A)
|
||||||
|
c64.CHROUT(',')
|
||||||
|
}
|
||||||
|
c64.CHROUT('\n')
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
for ubyte cc in "hello" {
|
for ubyte cc in "hello" {
|
||||||
@ -80,13 +89,49 @@ main {
|
|||||||
c64.CHROUT(',')
|
c64.CHROUT(',')
|
||||||
}
|
}
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
|
for ubyte cc7 in barr {
|
||||||
|
c64scr.print_ub(cc7)
|
||||||
|
c64.CHROUT(',')
|
||||||
|
}
|
||||||
|
c64.CHROUT('\n')
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
|
for uword ww1 in [1111, 2222, 3333] {
|
||||||
|
c64scr.print_uw(ww1)
|
||||||
|
c64.CHROUT(',')
|
||||||
|
}
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
; for float fl in [1.1, 2.2, 5.5, 99.99] {
|
for word ww2 in warr {
|
||||||
; c64flt.print_f(fl)
|
c64scr.print_w(ww2)
|
||||||
; c64.CHROUT(',')
|
c64.CHROUT(',')
|
||||||
; }
|
}
|
||||||
; c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
|
for uword ww3 in 1111 to 1122 {
|
||||||
|
c64scr.print_uw(ww3)
|
||||||
|
c64.CHROUT(',')
|
||||||
|
}
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
|
for uword ww3b in 2000 to 1990 step -1 {
|
||||||
|
c64scr.print_uw(ww3b)
|
||||||
|
c64.CHROUT(',')
|
||||||
|
}
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
|
for uword ww3c in 1111 to 50000 step 3333 {
|
||||||
|
c64scr.print_uw(ww3c)
|
||||||
|
c64.CHROUT(',')
|
||||||
|
}
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
|
||||||
|
for word ww4 in 999 to -999 step -500 {
|
||||||
|
c64scr.print_w(ww4)
|
||||||
|
c64.CHROUT(',')
|
||||||
|
}
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
c64.CHROUT('\n')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user