fix compiler loop and missing type checks on for loop range values

This commit is contained in:
Irmen de Jong 2020-08-29 01:44:20 +02:00
parent e112dfd910
commit a18de75da9
4 changed files with 64 additions and 18 deletions

View File

@ -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)
}
}
}
}

View File

@ -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")

View File

@ -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()
; }
; }
}
}

View File

@ -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