mirror of
https://github.com/irmen/prog8.git
synced 2024-11-22 15:33:02 +00:00
fixed some type cast compiler errors in for loops
This commit is contained in:
parent
9afe451b8d
commit
772e48105e
@ -1,2 +1,2 @@
|
|||||||
1.61
|
1.62
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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: ")
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user