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) { if(loopvar==null || loopvar.type== VarDeclType.CONST) {
errors.err("for loop requires a variable to loop with", forLoop.position) errors.err("for loop requires a variable to loop with", forLoop.position)
} else { } else {
fun checkLoopRangeValues() {
}
when (loopvar.datatype) { when (loopvar.datatype) {
DataType.UBYTE -> { DataType.UBYTE -> {
if(iterableDt!= DataType.UBYTE && iterableDt!= DataType.ARRAY_UB && iterableDt != DataType.STR) 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) 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> { 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 fromCast = rangeFrom.cast(targetDt)
val toCast = rangeTo.cast(targetDt) val toCast = rangeTo.cast(targetDt)
if(!fromCast.isValid || !toCast.isValid) if(!fromCast.isValid || !toCast.isValid)
return range return null
val newStep = val newStep =
if(stepLiteral!=null) { if(stepLiteral!=null) {
@ -351,28 +351,32 @@ internal class ConstantFoldingOptimizer(private val program: Program) : AstWalke
if(rangeFrom.type!= DataType.UBYTE) { if(rangeFrom.type!= DataType.UBYTE) {
// attempt to translate the iterable into ubyte values // attempt to translate the iterable into ubyte values
val newIter = adjustRangeDt(rangeFrom, loopvar.datatype, rangeTo, stepLiteral, iterableRange) 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 -> { DataType.BYTE -> {
if(rangeFrom.type!= DataType.BYTE) { if(rangeFrom.type!= DataType.BYTE) {
// attempt to translate the iterable into byte values // attempt to translate the iterable into byte values
val newIter = adjustRangeDt(rangeFrom, loopvar.datatype, rangeTo, stepLiteral, iterableRange) 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 -> { DataType.UWORD -> {
if(rangeFrom.type!= DataType.UWORD) { if(rangeFrom.type!= DataType.UWORD) {
// attempt to translate the iterable into uword values // attempt to translate the iterable into uword values
val newIter = adjustRangeDt(rangeFrom, loopvar.datatype, rangeTo, stepLiteral, iterableRange) 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 -> { DataType.WORD -> {
if(rangeFrom.type!= DataType.WORD) { if(rangeFrom.type!= DataType.WORD) {
// attempt to translate the iterable into word values // attempt to translate the iterable into word values
val newIter = adjustRangeDt(rangeFrom, loopvar.datatype, rangeTo, stepLiteral, iterableRange) 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") else -> throw FatalAstException("invalid loopvar datatype $loopvar")

View File

@ -9,22 +9,32 @@ main {
cx16.screen_set_mode($80) cx16.screen_set_mode($80)
cx16.r0=0 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 uword xx
for xx in 0 to 319 step 32 { ubyte yy
cx16.GRAPH_clear() for yy in 199 downto 0 {
ubyte q for xx in 319 downto 0 { ; TODO fix compiler hang -- should be error message when range is too large
for q in 0 to 31 { cx16.FB_set_pixel( yy+lsb(xx))
cx16.GRAPH_set_colors(q, 2, 0)
cx16.r0 = xx+q
cx16.r1=0
cx16.r2=rnd()
cx16.r3=199
cx16.GRAPH_draw_line()
} }
} }
; 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 { main {
sub start() { 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 b1
byte b2 byte b2
byte b3 byte b3