From af99173cd78357c35c1927eb74e617cabbdf5bbb Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 6 Sep 2021 21:52:14 +0200 Subject: [PATCH] range expressions are on integers only --- .../optimizer/ConstantIdentifierReplacer.kt | 30 +++++++++++++++++++ docs/source/syntaxreference.rst | 4 +-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/compiler/src/prog8/optimizer/ConstantIdentifierReplacer.kt b/compiler/src/prog8/optimizer/ConstantIdentifierReplacer.kt index aae516238..17d34933d 100644 --- a/compiler/src/prog8/optimizer/ConstantIdentifierReplacer.kt +++ b/compiler/src/prog8/optimizer/ConstantIdentifierReplacer.kt @@ -12,6 +12,7 @@ import prog8.compiler.IErrorReporter import prog8.compiler.target.ICompilationTarget // Fix up the literal value's type to match that of the vardecl +// (also check range literal operands types before they get expanded to arrays for instance) internal class VarConstantValueTypeAdjuster(private val program: Program, private val errors: IErrorReporter) : AstWalker() { override fun after(decl: VarDecl, parent: Node): Iterable { @@ -52,6 +53,35 @@ internal class VarConstantValueTypeAdjuster(private val program: Program, privat } return noModifications } + + override fun after(range: RangeExpr, parent: Node): Iterable { + val from = range.from.constValue(program)?.number?.toDouble() + val to = range.to.constValue(program)?.number?.toDouble() + val step = range.step.constValue(program)?.number?.toDouble() + + if(from==null) { + if(!range.from.inferType(program).isInteger()) + errors.err("range expression from value must be integer", range.from.position) + } else if(from-from.toInt()>0) { + errors.err("range expression from value must be integer", range.from.position) + } + + if(to==null) { + if(!range.to.inferType(program).isInteger()) + errors.err("range expression to value must be integer", range.to.position) + } else if(to-to.toInt()>0) { + errors.err("range expression to value must be integer", range.to.position) + } + + if(step==null) { + if(!range.step.inferType(program).isInteger()) + errors.err("range expression step value must be integer", range.step.position) + } else if(step-step.toInt()>0) { + errors.err("range expression step value must be integer", range.step.position) + } + + return noModifications + } } diff --git a/docs/source/syntaxreference.rst b/docs/source/syntaxreference.rst index e403afe8b..e97adb971 100644 --- a/docs/source/syntaxreference.rst +++ b/docs/source/syntaxreference.rst @@ -396,7 +396,7 @@ The following names are reserved, they have a special meaning:: Range expression ^^^^^^^^^^^^^^^^ -A special value is the *range expression* which represents a range of numbers or characters, +A special value is the *range expression* which represents a range of integer numbers or characters, from the starting value to (and including) the ending value:: to [ step ] @@ -406,7 +406,7 @@ You an provide a step value if you need something else than the default incremen in case of downto, a decrement of one). Because a step of minus one is so common you can just use the downto variant to avoid having to specify the step as well. -If used in the place of a literal value, it expands into the actual array of values:: +If used in the place of a literal value, it expands into the actual array of integer values:: byte[] array = 100 to 199 ; initialize array with [100, 101, ..., 198, 199]