mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 23:29:55 +00:00
fix compiler loop and missing type checks on for loop range values
This commit is contained in:
parent
e112dfd910
commit
a18de75da9
@ -118,6 +118,11 @@ internal class AstChecker(private val program: Program,
|
||||
if(loopvar==null || loopvar.type== VarDeclType.CONST) {
|
||||
errors.err("for loop requires a variable to loop with", forLoop.position)
|
||||
} else {
|
||||
|
||||
fun checkLoopRangeValues() {
|
||||
|
||||
}
|
||||
|
||||
when (loopvar.datatype) {
|
||||
DataType.UBYTE -> {
|
||||
if(iterableDt!= DataType.UBYTE && iterableDt!= DataType.ARRAY_UB && iterableDt != DataType.STR)
|
||||
@ -142,6 +147,22 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
else -> errors.err("loop variable must be numeric type", forLoop.position)
|
||||
}
|
||||
if(errors.isEmpty()) {
|
||||
// check loop range values
|
||||
val range = forLoop.iterable as? RangeExpr
|
||||
if(range!=null) {
|
||||
val from = range.from as? NumericLiteralValue
|
||||
val to = range.to as? NumericLiteralValue
|
||||
if(from != null)
|
||||
checkValueTypeAndRange(loopvar.datatype, from)
|
||||
else if(!range.from.inferType(program).istype(loopvar.datatype))
|
||||
errors.err("range start value is incompatible with loop variable type", range.position)
|
||||
if(to != null)
|
||||
checkValueTypeAndRange(loopvar.datatype, to)
|
||||
else if(!range.to.inferType(program).istype(loopvar.datatype))
|
||||
errors.err("range end value is incompatible with loop variable type", range.position)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -318,11 +318,11 @@ internal class ConstantFoldingOptimizer(private val program: Program) : AstWalke
|
||||
}
|
||||
|
||||
override fun after(forLoop: ForLoop, parent: Node): Iterable<IAstModification> {
|
||||
fun adjustRangeDt(rangeFrom: NumericLiteralValue, targetDt: DataType, rangeTo: NumericLiteralValue, stepLiteral: NumericLiteralValue?, range: RangeExpr): RangeExpr {
|
||||
fun adjustRangeDt(rangeFrom: NumericLiteralValue, targetDt: DataType, rangeTo: NumericLiteralValue, stepLiteral: NumericLiteralValue?, range: RangeExpr): RangeExpr? {
|
||||
val fromCast = rangeFrom.cast(targetDt)
|
||||
val toCast = rangeTo.cast(targetDt)
|
||||
if(!fromCast.isValid || !toCast.isValid)
|
||||
return range
|
||||
return null
|
||||
|
||||
val newStep =
|
||||
if(stepLiteral!=null) {
|
||||
@ -351,28 +351,32 @@ internal class ConstantFoldingOptimizer(private val program: Program) : AstWalke
|
||||
if(rangeFrom.type!= DataType.UBYTE) {
|
||||
// attempt to translate the iterable into ubyte values
|
||||
val newIter = adjustRangeDt(rangeFrom, loopvar.datatype, rangeTo, stepLiteral, iterableRange)
|
||||
return listOf(IAstModification.ReplaceNode(forLoop.iterable, newIter, forLoop))
|
||||
if(newIter!=null)
|
||||
return listOf(IAstModification.ReplaceNode(forLoop.iterable, newIter, forLoop))
|
||||
}
|
||||
}
|
||||
DataType.BYTE -> {
|
||||
if(rangeFrom.type!= DataType.BYTE) {
|
||||
// attempt to translate the iterable into byte values
|
||||
val newIter = adjustRangeDt(rangeFrom, loopvar.datatype, rangeTo, stepLiteral, iterableRange)
|
||||
return listOf(IAstModification.ReplaceNode(forLoop.iterable, newIter, forLoop))
|
||||
if(newIter!=null)
|
||||
return listOf(IAstModification.ReplaceNode(forLoop.iterable, newIter, forLoop))
|
||||
}
|
||||
}
|
||||
DataType.UWORD -> {
|
||||
if(rangeFrom.type!= DataType.UWORD) {
|
||||
// attempt to translate the iterable into uword values
|
||||
val newIter = adjustRangeDt(rangeFrom, loopvar.datatype, rangeTo, stepLiteral, iterableRange)
|
||||
return listOf(IAstModification.ReplaceNode(forLoop.iterable, newIter, forLoop))
|
||||
if(newIter!=null)
|
||||
return listOf(IAstModification.ReplaceNode(forLoop.iterable, newIter, forLoop))
|
||||
}
|
||||
}
|
||||
DataType.WORD -> {
|
||||
if(rangeFrom.type!= DataType.WORD) {
|
||||
// attempt to translate the iterable into word values
|
||||
val newIter = adjustRangeDt(rangeFrom, loopvar.datatype, rangeTo, stepLiteral, iterableRange)
|
||||
return listOf(IAstModification.ReplaceNode(forLoop.iterable, newIter, forLoop))
|
||||
if(newIter!=null)
|
||||
return listOf(IAstModification.ReplaceNode(forLoop.iterable, newIter, forLoop))
|
||||
}
|
||||
}
|
||||
else -> throw FatalAstException("invalid loopvar datatype $loopvar")
|
||||
|
@ -9,22 +9,32 @@ main {
|
||||
|
||||
cx16.screen_set_mode($80)
|
||||
cx16.r0=0
|
||||
cx16.GRAPH_init()
|
||||
cx16.GRAPH_set_colors(0, 0, 0)
|
||||
|
||||
cx16.FB_init()
|
||||
cx16.r0 = 0
|
||||
cx16.r1 = 0
|
||||
cx16.FB_cursor_position()
|
||||
uword xx
|
||||
for xx in 0 to 319 step 32 {
|
||||
cx16.GRAPH_clear()
|
||||
ubyte q
|
||||
for q in 0 to 31 {
|
||||
cx16.GRAPH_set_colors(q, 2, 0)
|
||||
cx16.r0 = xx+q
|
||||
cx16.r1=0
|
||||
cx16.r2=rnd()
|
||||
cx16.r3=199
|
||||
cx16.GRAPH_draw_line()
|
||||
ubyte yy
|
||||
for yy in 199 downto 0 {
|
||||
for xx in 319 downto 0 { ; TODO fix compiler hang -- should be error message when range is too large
|
||||
cx16.FB_set_pixel( yy+lsb(xx))
|
||||
}
|
||||
}
|
||||
|
||||
; uword xx
|
||||
; for xx in 0 to 319 step 32 {
|
||||
; cx16.GRAPH_clear()
|
||||
; ubyte q
|
||||
; for q in 0 to 31 {
|
||||
; cx16.GRAPH_set_colors(q, 2, 0)
|
||||
; cx16.r0 = xx+q
|
||||
; cx16.r1=0
|
||||
; cx16.r2=rnd()
|
||||
; cx16.r3=199
|
||||
; cx16.GRAPH_draw_line()
|
||||
; }
|
||||
; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,17 @@
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
|
||||
ubyte xx
|
||||
ubyte yy
|
||||
for yy in 199 downto 0 {
|
||||
for xx in 255 downto 0 {
|
||||
; TODO also fix that the asm is invalid for word iterator variable.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
byte b1
|
||||
byte b2
|
||||
byte b3
|
||||
|
Loading…
Reference in New Issue
Block a user