fixed some type cast compiler errors in for loops

This commit is contained in:
Irmen de Jong 2019-08-26 23:38:59 +02:00
parent 9afe451b8d
commit 772e48105e
5 changed files with 66 additions and 58 deletions

View File

@ -1,2 +1,2 @@
1.61 1.62

View File

@ -562,49 +562,79 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor {
} catch (x: ExpressionError) { } catch (x: ExpressionError) {
return range return range
} }
val newStep: Expression = stepLiteral?.cast(targetDt) ?: range.step val newStep: Expression = try {
stepLiteral?.cast(targetDt)?: range.step
} catch(ee: ExpressionError) {
range.step
}
return RangeExpr(newFrom, newTo, newStep, range.position) return RangeExpr(newFrom, newTo, newStep, range.position)
} }
val forLoop2 = super.visit(forLoop) as ForLoop
// check if we need to adjust an array literal to the loop variable's datatype
val array = forLoop2.iterable as? ArrayLiteralValue
if(array!=null) {
val loopvarDt: DataType = when {
forLoop.loopVar!=null -> forLoop.loopVar!!.inferType(program).typeOrElse(DataType.UBYTE)
forLoop.loopRegister!=null -> DataType.UBYTE
else -> throw FatalAstException("weird for loop")
}
val arrayType = when(loopvarDt) {
DataType.UBYTE -> DataType.ARRAY_UB
DataType.BYTE -> DataType.ARRAY_B
DataType.UWORD -> DataType.ARRAY_UW
DataType.WORD -> DataType.ARRAY_W
DataType.FLOAT -> DataType.ARRAY_F
else -> throw FatalAstException("invalid array elt type")
}
val array2 = array.cast(arrayType)
if(array2!=null && array2!==array) {
forLoop2.iterable = array2
array2.linkParents(forLoop2)
array2.addToHeap()
}
}
// adjust the datatype of a range expression in for loops to the loop variable. // adjust the datatype of a range expression in for loops to the loop variable.
val resultStmt = super.visit(forLoop) as ForLoop val iterableRange = forLoop2.iterable as? RangeExpr ?: return forLoop2
val iterableRange = resultStmt.iterable as? RangeExpr ?: return resultStmt
val rangeFrom = iterableRange.from as? NumericLiteralValue val rangeFrom = iterableRange.from as? NumericLiteralValue
val rangeTo = iterableRange.to as? NumericLiteralValue val rangeTo = iterableRange.to as? NumericLiteralValue
if(rangeFrom==null || rangeTo==null) return resultStmt if(rangeFrom==null || rangeTo==null) return forLoop2
val loopvar = resultStmt.loopVar?.targetVarDecl(program.namespace) val loopvar = forLoop2.loopVar?.targetVarDecl(program.namespace)
if(loopvar!=null) { if(loopvar!=null) {
val stepLiteral = iterableRange.step as? NumericLiteralValue val stepLiteral = iterableRange.step as? NumericLiteralValue
when(loopvar.datatype) { when(loopvar.datatype) {
DataType.UBYTE -> { DataType.UBYTE -> {
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
resultStmt.iterable = adjustRangeDt(rangeFrom, loopvar.datatype, rangeTo, stepLiteral, iterableRange) forLoop2.iterable = adjustRangeDt(rangeFrom, loopvar.datatype, rangeTo, stepLiteral, iterableRange)
} }
} }
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
resultStmt.iterable = adjustRangeDt(rangeFrom, loopvar.datatype, rangeTo, stepLiteral, iterableRange) forLoop2.iterable = adjustRangeDt(rangeFrom, loopvar.datatype, rangeTo, stepLiteral, iterableRange)
} }
} }
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
resultStmt.iterable = adjustRangeDt(rangeFrom, loopvar.datatype, rangeTo, stepLiteral, iterableRange) forLoop2.iterable = adjustRangeDt(rangeFrom, loopvar.datatype, rangeTo, stepLiteral, iterableRange)
} }
} }
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
resultStmt.iterable = adjustRangeDt(rangeFrom, loopvar.datatype, rangeTo, stepLiteral, iterableRange) forLoop2.iterable = adjustRangeDt(rangeFrom, loopvar.datatype, rangeTo, stepLiteral, iterableRange)
} }
} }
else -> throw FatalAstException("invalid loopvar datatype $loopvar") else -> throw FatalAstException("invalid loopvar datatype $loopvar")
} }
} }
return resultStmt return forLoop2
} }
override fun visit(arrayLiteral: ArrayLiteralValue): Expression { override fun visit(arrayLiteral: ArrayLiteralValue): Expression {

View File

@ -46,11 +46,7 @@ without having to to index into the stack?
Bugs Bugs
^^^^ ^^^^
There are a few erroneous compiler errors when dealing with certain for loops:: Ofcourse there are still bugs to fix ;)
for bb in [1,2,3] ; byte loop variable can only loop over bytes
for ww in [1111,3333,555,999] ; word loop variable can only loop over bytes or words
for uw in 20 to 10 step -1 ; 'can't cast BYTE into UWORD'
Misc Misc

View File

@ -1,10 +1,5 @@
%zeropage basicsafe %zeropage basicsafe
; TODO fix compiler errors:
; for bb in [1,2,3] -> byte loop variable can only loop over bytes
; for ww in [1111,3333,555,999] -> word loop variable can only loop over bytes or words
; for uw in 20 to 10 step -1 -> 'can't cast BYTE into UWORD'
main { main {
sub start() { sub start() {
@ -12,21 +7,16 @@ main {
byte[] barr = [22,-33,-44,55,66] byte[] barr = [22,-33,-44,55,66]
ubyte endub1 ubyte endub1
byte endb1 byte endb1
uword count
ubyte aa ubyte aa
ubyte ub ubyte ub
byte bb byte bb
uword uw
word total word total
uword count
for count in 10 to 20 step 1 {
}
for count in 20 to 10 step -1 { ; @todo fix compiler error
}
; ---------- BYTE var --------- ; ---------- BYTE var ---------
; @todo fix byte loop in arrayliteral 'Error: byte loop variable can only loop over bytes'
count = 0 count = 0
total = 0 total = 0
c64scr.print("byte var in arrayliteral: ") c64scr.print("byte var in arrayliteral: ")
@ -46,7 +36,6 @@ main {
word endw1 word endw1
word ww word ww
; @todo fix compiler error
count = 0 count = 0
total = 0 total = 0
c64scr.print("word var in arrayliteral: ") c64scr.print("word var in arrayliteral: ")

View File

@ -1,10 +1,5 @@
%zeropage basicsafe %zeropage basicsafe
; TODO fix compiler errors:
; for bb in [1,2,3] -> byte loop variable can only loop over bytes
; for ww in [1111,3333,555,999] -> word loop variable can only loop over bytes or words
; for uw in 20 to 10 step -1 -> 'can't cast BYTE into UWORD'
main { main {
sub start() { sub start() {
@ -416,18 +411,17 @@ main {
; ---------- BYTE var --------- ; ---------- BYTE var ---------
; @todo fix byte loop in arrayliteral 'Error: byte loop variable can only loop over bytes' count = 0
; count = 0 total = 0
; total = 0 c64scr.print("byte var in arrayliteral: ")
; c64scr.print("byte var in arrayliteral: ") for bb in [1,3,5,99] {
; for bb in [1,3,5,99] { count++
; count++ total += bb
; total += bb }
; } if count==4 and total==108
; if count==4 and total==108 c64scr.print("ok\n")
; c64scr.print("ok\n") else
; else c64scr.print("fail!!!\n")
; c64scr.print("fail!!!\n")
count = 0 count = 0
total = 0 total = 0
@ -793,18 +787,17 @@ main {
word endw1 word endw1
word ww word ww
; @todo fix compiler error count = 0
; count = 0 total = 0
; total = 0 c64scr.print("word var in arrayliteral: ")
; c64scr.print("word var in arrayliteral: ") for ww in [1111,3333,555,999] {
; for ww in [1111,3333,555,999] { count++
; count++ total += ww
; total += ww }
; } if count==4 and total==5998
; if count==4 and total==5998 c64scr.print("ok\n")
; c64scr.print("ok\n") else
; else c64scr.print("fail!!!\n")
; c64scr.print("fail!!!\n")
count = 0 count = 0
total = 0 total = 0