Fix compiler crash in for loops with just 1 iteration

This commit is contained in:
Irmen de Jong 2024-09-05 21:23:17 +02:00
parent 5c45adc7f0
commit 29dd758302
7 changed files with 95 additions and 35 deletions

View File

@ -296,6 +296,7 @@ class PtRange(type: DataType, position: Position) : PtExpression(type, position)
fun toConstantIntegerRange(): IntProgression? {
fun makeRange(fromVal: Int, toVal: Int, stepVal: Int): IntProgression {
return when {
fromVal == toVal -> fromVal .. toVal
fromVal <= toVal -> when {
stepVal <= 0 -> IntRange.EMPTY
stepVal == 1 -> fromVal..toVal

View File

@ -484,10 +484,12 @@ $loopLabel sty $indexVar
if (range.isEmpty() || range.step==0)
throw AssemblyError("empty range or step 0")
if(iterableDt==DataType.ARRAY_B || iterableDt==DataType.ARRAY_UB) {
if(range.last==range.first) return translateForSimpleByteRangeAsc(stmt, range)
if(range.step==1 && range.last>range.first) return translateForSimpleByteRangeAsc(stmt, range)
if(range.step==-1 && range.last<range.first) return translateForSimpleByteRangeDesc(stmt, range)
}
else if(iterableDt==DataType.ARRAY_W || iterableDt==DataType.ARRAY_UW) {
if(range.last==range.first) return translateForSimpleWordRangeAsc(stmt, range)
if(range.step==1 && range.last>range.first) return translateForSimpleWordRangeAsc(stmt, range)
if(range.step==-1 && range.last<range.first) return translateForSimpleWordRangeDesc(stmt, range)
}
@ -507,7 +509,7 @@ $loopLabel""")
asmgen.translate(stmt.statements)
when (range.step) {
0, 1, -1 -> {
throw AssemblyError("step 0, 1 and -1 should have been handled specifically $stmt")
throw AssemblyError("step 0, 1 and -1 should have been handled specifically $range ${stmt.position}")
}
2 -> {
if(range.last==255 || range.last==254) {

View File

@ -101,4 +101,12 @@ graphics {
return
cx16.GRAPH_draw_oval(xcenter - h_radius, ycenter - v_radius, h_radius*2, v_radius*2, true)
}
inline asmsub plot(uword plotx @R0, uword ploty @R1) clobbers(A, X, Y) {
%asm {{
jsr cx16.FB_cursor_position
lda p8b_graphics.p8v_stroke_color
jsr cx16.FB_set_pixel
}}
}
}

View File

@ -383,4 +383,41 @@ main {
compileText(AtariTarget(), false, text, writeAssembly = true) shouldNotBe null
compileText(VMTarget(), false, text, writeAssembly = true) shouldNotBe null
}
test("for loops with just 1 iteration") {
val src="""
main {
sub start() {
for cx16.r0L in 100 downto 100 {
cx16.r1++
}
for cx16.r0L in 100 to 100 {
cx16.r1++
}
for cx16.r0 in 2222 downto 2222 {
cx16.r1++
}
for cx16.r0 in 2222 to 2222 {
cx16.r1++
}
for cx16.r0L in 100 downto 100 step -5 {
cx16.r1++
}
for cx16.r0L in 100 to 100 step 5 {
cx16.r1++
}
for cx16.r0 in 2222 downto 2222 step -5 {
cx16.r1++
}
for cx16.r0 in 2222 to 2222 step 5 {
cx16.r1++
}
}
}"""
compileText(VMTarget(), true, src, writeAssembly = true) shouldNotBe null
compileText(VMTarget(), false, src, writeAssembly = true) shouldNotBe null
compileText(Cx16Target(), true, src, writeAssembly = true) shouldNotBe null
compileText(Cx16Target(), false, src, writeAssembly = true) shouldNotBe null
}
})

View File

@ -1006,6 +1006,7 @@ class RangeExpression(var from: Expression,
fun makeRange(fromVal: Int, toVal: Int, stepVal: Int): IntProgression {
return when {
fromVal == toVal -> fromVal .. toVal
fromVal <= toVal -> when {
stepVal <= 0 -> IntRange.EMPTY
stepVal == 1 -> fromVal..toVal

View File

@ -1,9 +1,6 @@
TODO
====
Fix compiler crash for: for radius in 100 downto 100 step -10
Improve register load order in subroutine call args assignments:
in certain situations, the "wrong" order of evaluation of function call arguments is done which results
in overwriting registers that already got their value, which requires a lot of stack juggling (especially on plain 6502 cpu!)

View File

@ -1,39 +1,53 @@
%import gfx2
%import textio
%import math
%option no_sysinit
%zeropage basicsafe
main {
sub start() {
gfx2.screen_mode(2)
demofill()
}
sub demofill() {
gfx2.circle(160, 120, 110, 1)
gfx2.rect(180, 5, 25, 190, 2)
gfx2.line(100, 150, 240, 10, 2)
gfx2.rect(150, 130, 10, 100, 3)
sys.wait(30)
cbm.SETTIM(0,0,0)
gfx2.fill(100,100,3)
gfx2.fill(100,100,2)
gfx2.fill(100,100,0)
uword duration = cbm.RDTIM16()
sys.wait(30)
gfx2.screen_mode(0)
txt.nl()
txt.print_uw(duration)
txt.print(" jiffies\n")
; hires 4c before optimizations: ~345 jiffies
for cx16.r0L in 5 to 5 {
txt.print("derp0.")
txt.print_ub(cx16.r0L)
txt.nl()
}
for cx16.r0L in 100 downto 100 {
txt.print("derp1.")
txt.print_ub(cx16.r0L)
txt.nl()
}
for cx16.r0L in 100 to 100 {
txt.print("derp2.")
txt.print_ub(cx16.r0L)
txt.nl()
}
for cx16.r0 in 2222 downto 2222 {
txt.print("derp3.")
txt.print_uw(cx16.r0)
txt.nl()
}
for cx16.r0 in 2222 to 2222 {
txt.print("derp4.")
txt.print_uw(cx16.r0)
txt.nl()
}
for cx16.r0L in 100 downto 100 step -5 {
txt.print("derp5.")
txt.print_ub(cx16.r0L)
txt.nl()
}
for cx16.r0L in 100 to 100 step 5 {
txt.print("derp6.")
txt.print_ub(cx16.r0L)
txt.nl()
}
for cx16.r0 in 2222 downto 2222 step -5 {
txt.print("derp7.")
txt.print_uw(cx16.r0)
txt.nl()
}
for cx16.r0 in 2222 to 2222 step 5 {
txt.print("derp8.")
txt.print_uw(cx16.r0)
txt.nl()
}
}
}