From 3e6d16a7a8a4bcdecce3323b329c525b49406d68 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Fri, 11 Aug 2023 02:14:54 +0200 Subject: [PATCH] add error message for invalid step size in range expression --- .../prog8/codegen/intermediate/IRCodeGen.kt | 11 ++--- .../optimizer/ConstantIdentifierReplacer.kt | 8 ++- compiler/test/TestCompilerOnRanges.kt | 10 +++- examples/test.p8 | 49 +++++++++++++++++-- 4 files changed, 66 insertions(+), 12 deletions(-) diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt index da0782ded..21030ce2a 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt @@ -589,22 +589,21 @@ class IRCodeGen( val iterable = forLoop.iterable as PtRange val step = iterable.step.number.toInt() val rangeStart = (iterable.from as PtNumber).number.toInt() - val rangeEndUntyped = (iterable.to as PtNumber).number.toInt() + step + val rangeEndExclusiveUntyped = (iterable.to as PtNumber).number.toInt() + step if(step==0) throw AssemblyError("step 0") - if(step>0 && rangeEndUntypedrangeStart) + if(step>0 && rangeEndExclusiveUntypedrangeStart) throw AssemblyError("empty range") - val rangeEndWrapped = if(loopvarDtIr==IRDataType.BYTE) rangeEndUntyped and 255 else rangeEndUntyped and 65535 + val rangeEndExclusiveWrapped = if(loopvarDtIr==IRDataType.BYTE) rangeEndExclusiveUntyped and 255 else rangeEndExclusiveUntyped and 65535 val result = mutableListOf() val chunk = IRCodeChunk(null, null) chunk += IRInstruction(Opcode.LOAD, loopvarDtIr, reg1=indexReg, immediate = rangeStart) chunk += IRInstruction(Opcode.STOREM, loopvarDtIr, reg1=indexReg, labelSymbol=loopvarSymbol) result += chunk result += labelFirstChunk(translateNode(forLoop.statements), loopLabel) - result += addConstMem(loopvarDtIr, null, loopvarSymbol, step) - val chunk2 = IRCodeChunk(null, null) + val chunk2 = addConstMem(loopvarDtIr, null, loopvarSymbol, step) chunk2 += IRInstruction(Opcode.LOADM, loopvarDtIr, reg1 = indexReg, labelSymbol = loopvarSymbol) - chunk2 += IRInstruction(Opcode.BNE, loopvarDtIr, reg1 = indexReg, immediate = rangeEndWrapped, labelSymbol = loopLabel) + chunk2 += IRInstruction(Opcode.BNE, loopvarDtIr, reg1 = indexReg, immediate = rangeEndExclusiveWrapped, labelSymbol = loopLabel) result += chunk2 return result } diff --git a/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt b/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt index 0d9bd7700..3c932cc05 100644 --- a/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt +++ b/codeOptimizers/src/prog8/optimizer/ConstantIdentifierReplacer.kt @@ -280,10 +280,16 @@ internal class ConstantIdentifierReplacer(private val program: Program, private val rangeExpr = decl.value as? RangeExpression if(rangeExpr!=null) { // convert the initializer range expression to an actual array + val constRange = rangeExpr.toConstantIntegerRange() + if(constRange?.isEmpty()==true) { + if(constRange.first>constRange.last && constRange.step>=0) + errors.err("descending range with positive step", decl.value?.position!!) + else if(constRange.first