diff --git a/compiler/src/prog8/compiler/astprocessing/TypecastsAdder.kt b/compiler/src/prog8/compiler/astprocessing/TypecastsAdder.kt index 310e614e3..3bf84c872 100644 --- a/compiler/src/prog8/compiler/astprocessing/TypecastsAdder.kt +++ b/compiler/src/prog8/compiler/astprocessing/TypecastsAdder.kt @@ -341,14 +341,33 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val } return noModifications } - override fun after(range: RangeExpression, parent: Node): Iterable { + val fromDt = range.from.inferType(program).getOr(DataType.UNDEFINED) + val toDt = range.to.inferType(program).getOr(DataType.UNDEFINED) val fromConst = range.from.constValue(program) val toConst = range.to.constValue(program) + val varDt = if (parent is ContainmentCheck) + parent.element.inferType(program) + else if (parent is ForLoop) + parent.loopVarDt(program) + else + InferredTypes.InferredType.unknown() + return adjustRangeDts(range, fromConst, fromDt, toConst, toDt, varDt.getOr(DataType.UNDEFINED), parent) + } + + private fun adjustRangeDts( + range: RangeExpression, + fromConst: NumericLiteral?, + fromDt: DataType, + toConst: NumericLiteral?, + toDt: DataType, + varDt: DataType, + parent: Node + ): List { if(fromConst!=null) { val smaller = NumericLiteral.optimalInteger(fromConst.number.toInt(), fromConst.position) - if(fromConst.type.largerThan(smaller.type)) { + if(fromDt.largerThan(smaller.type)) { val toType = range.to.inferType(program) if(toType isnot smaller.type) { if(toConst!=null) { @@ -367,7 +386,7 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val } if(toConst!=null) { val smaller = NumericLiteral.optimalInteger(toConst.number.toInt(), toConst.position) - if(toConst.type.largerThan(smaller.type)) { + if(toDt.largerThan(smaller.type)) { val fromType = range.from.inferType(program) if(fromType isnot smaller.type) { if(fromConst!=null) { @@ -386,8 +405,6 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val } val modifications = mutableListOf() - val fromDt = range.from.inferType(program).getOr(DataType.UNDEFINED) - val toDt = range.to.inferType(program).getOr(DataType.UNDEFINED) val (commonDt, toChange) = BinaryExpression.commonDatatype(fromDt, toDt, range.from, range.to) if(toChange!=null) addTypecastOrCastedValueModification(modifications, toChange, commonDt, range) diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 0f3d45291..4e4ce449c 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,9 +1,7 @@ TODO ==== -word starw; for starw in 50 downto 0 -> compiler error word loop variable can only loop over bytes or words - -chess prg got bigger again. why? +word starw; for starw in 50 downto 0 -> compiler error word loop variable can only loop over bytes or words FIX in adjustRangeDts() most likely Regenerate skeleton doc files. diff --git a/examples/test.p8 b/examples/test.p8 index 06cc5485b..65c0af508 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -4,22 +4,42 @@ main { sub start() { - uword uw - for uw in 50 downto 10 { - cx16.r0++ - } + bool[256] cells word starw + byte bb + uword uw + ubyte ub + for starw in 50 downto 10 { ; TODO fix compiler error + add unit test for this cx16.r0++ } + for starw in cx16.r0L downto 10 { ; TODO fix compiler error + add unit test for this + cx16.r0++ + } + + for ub in 0 to len(cells)-1 { + cx16.r0++ + } + for ub in cx16.r0L to len(cells)-1 { + cx16.r0++ + } + for bb in 50 downto 10 { + cx16.r0++ + } + for bb in cx16.r0sL downto 10 { + cx16.r0++ + } - ubyte[] stuff1=[1,2,3] - ubyte [] stuff2=[1,2,3] - ubyte[ ] stuff3=[1,2,3] - stuff1[1]++ - stuff2[1]++ - stuff3[1]++ +; for starw in 500 downto 10 { +; cx16.r0++ +; } +; for uw in 50 downto 10 { +; cx16.r0++ +; } +; for uw in 500 downto 10 { +; cx16.r0++ +; } } }