mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
added compiler check against impossible for loop range (unsigned downto exactly 0 with non-const startvalue and step != -1)
This commit is contained in:
parent
ee1c43ca91
commit
4c080afb76
@ -92,6 +92,18 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
|
||||
override fun visit(forLoop: ForLoop) {
|
||||
|
||||
fun checkUnsignedLoopDownto0(range: RangeExpr?) {
|
||||
if(range==null)
|
||||
return
|
||||
val step = range.step.constValue(program)?.number?.toDouble() ?: 1.0
|
||||
if(step < -1.0) {
|
||||
val limit = range.to.constValue(program)?.number?.toDouble()
|
||||
if(limit==0.0 && range.from.constValue(program)==null)
|
||||
errors.err("for unsigned loop variable it's not possible to count down with step != -1 from a non-const value to exactly zero due to value wrapping", forLoop.position)
|
||||
}
|
||||
}
|
||||
|
||||
val iterableDt = forLoop.iterable.inferType(program).typeOrElse(DataType.BYTE)
|
||||
if(iterableDt !in IterableDatatypes && forLoop.iterable !is RangeExpr) {
|
||||
errors.err("can only loop over an iterable type", forLoop.position)
|
||||
@ -104,11 +116,15 @@ internal class AstChecker(private val program: Program,
|
||||
DataType.UBYTE -> {
|
||||
if(iterableDt!= DataType.UBYTE && iterableDt!= DataType.ARRAY_UB && iterableDt != DataType.STR)
|
||||
errors.err("ubyte loop variable can only loop over unsigned bytes or strings", forLoop.position)
|
||||
|
||||
checkUnsignedLoopDownto0(forLoop.iterable as? RangeExpr)
|
||||
}
|
||||
DataType.UWORD -> {
|
||||
if(iterableDt!= DataType.UBYTE && iterableDt!= DataType.UWORD && iterableDt != DataType.STR &&
|
||||
iterableDt != DataType.ARRAY_UB && iterableDt!= DataType.ARRAY_UW)
|
||||
errors.err("uword loop variable can only loop over unsigned bytes, words or strings", forLoop.position)
|
||||
|
||||
checkUnsignedLoopDownto0(forLoop.iterable as? RangeExpr)
|
||||
}
|
||||
DataType.BYTE -> {
|
||||
if(iterableDt!= DataType.BYTE && iterableDt!= DataType.ARRAY_B)
|
||||
@ -146,6 +162,7 @@ internal class AstChecker(private val program: Program,
|
||||
super.visit(forLoop)
|
||||
}
|
||||
|
||||
|
||||
override fun visit(jump: Jump) {
|
||||
val ident = jump.identifier
|
||||
if(ident!=null) {
|
||||
|
@ -40,6 +40,13 @@ internal class ForLoopsAsmGen(private val program: Program, private val asmgen:
|
||||
val modifiedLabel2 = asmgen.makeLabel("for_modifiedb")
|
||||
asmgen.loopEndLabels.push(endLabel)
|
||||
val stepsize=range.step.constValue(program)!!.number.toInt()
|
||||
|
||||
if(stepsize < -1) {
|
||||
val limit = range.to.constValue(program)?.number?.toDouble()
|
||||
if(limit==0.0)
|
||||
throw AssemblyError("for unsigned loop variable it's not possible to count down with step != -1 from a non-const value to exactly zero due to value wrapping")
|
||||
}
|
||||
|
||||
when(iterableDt) {
|
||||
DataType.ARRAY_B, DataType.ARRAY_UB -> {
|
||||
if (stepsize==1 || stepsize==-1) {
|
||||
|
@ -7,21 +7,61 @@
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
ubyte num_entries
|
||||
ubyte fromub = 120
|
||||
uword fromuw = 400
|
||||
byte fromb = 120
|
||||
word fromw = 400
|
||||
|
||||
num_entries = 10
|
||||
ubyte ix
|
||||
for ix in (num_entries-1)*2 downto 0 step -2 {
|
||||
txt.print_ub(ix)
|
||||
uword counter
|
||||
byte bc
|
||||
ubyte ubc
|
||||
word wc
|
||||
uword uwc
|
||||
|
||||
counter = 0
|
||||
for bc in fromb to 0 step -1 {
|
||||
counter++
|
||||
txt.print_b(bc)
|
||||
txt.spc()
|
||||
}
|
||||
|
||||
txt.nl()
|
||||
num_entries = 10
|
||||
for ix in num_entries-1 downto 0 {
|
||||
txt.print_ub(ix*2)
|
||||
txt.print_uw(counter)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
|
||||
counter = 0
|
||||
for ubc in fromub to 0 step -1 {
|
||||
counter++
|
||||
txt.print_ub(ubc)
|
||||
txt.spc()
|
||||
}
|
||||
txt.nl()
|
||||
txt.print_uw(counter)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
|
||||
counter = 0
|
||||
for wc in fromw to 0 step -1 {
|
||||
counter++
|
||||
txt.print_w(wc)
|
||||
txt.spc()
|
||||
}
|
||||
txt.nl()
|
||||
txt.print_uw(counter)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
|
||||
; TODO FIX THIS LOOP??
|
||||
counter = 0
|
||||
for uwc in fromuw to 0 step -1 {
|
||||
counter++
|
||||
txt.print_uw(uwc)
|
||||
txt.spc()
|
||||
}
|
||||
txt.nl()
|
||||
txt.print_uw(counter)
|
||||
txt.nl()
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user