mirror of
https://github.com/irmen/prog8.git
synced 2025-11-02 13:16:07 +00:00
allow integer range as when choice value
This commit is contained in:
@@ -319,4 +319,35 @@ _after:
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
|
||||
override fun after(whenChoice: WhenChoice, parent: Node): Iterable<IAstModification> {
|
||||
// replace a range expression in a when by the actual list of numbers it represents
|
||||
val values = whenChoice.values
|
||||
if(values!=null && values.size==1) {
|
||||
val conditionType = (whenChoice.parent as When).condition.inferType(program)
|
||||
val intRange = (values[0] as? RangeExpression)?.toConstantIntegerRange()
|
||||
if(conditionType.isKnown && intRange != null) {
|
||||
if(intRange.count()>255)
|
||||
errors.err("values list too long", values[0].position)
|
||||
else {
|
||||
val dt = conditionType.getOrUndef().base
|
||||
val newValues = intRange.map {
|
||||
val num = NumericLiteral(BaseDataType.LONG, it.toDouble(), values[0].position)
|
||||
num.linkParents(whenChoice)
|
||||
val cast = num.cast(dt, true)
|
||||
if (cast.isValid) cast.valueOrZero() else null
|
||||
}
|
||||
if(null !in newValues) {
|
||||
if(newValues.size>=10)
|
||||
errors.warn("long list of values, checking will not be very efficient", values[0].position)
|
||||
values.clear()
|
||||
for(num in newValues)
|
||||
values.add(num!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return noModifications
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import io.kotest.assertions.throwables.shouldThrow
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.engine.spec.tempdir
|
||||
import io.kotest.matchers.comparables.shouldBeGreaterThan
|
||||
import io.kotest.matchers.nulls.shouldNotBeNull
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.kotest.matchers.shouldNotBe
|
||||
import io.kotest.matchers.string.shouldContain
|
||||
@@ -684,6 +685,40 @@ main
|
||||
errors.errors[0] shouldContain "use if"
|
||||
}
|
||||
|
||||
test("when on range expressions is ok") {
|
||||
val src="""
|
||||
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
when cx16.r0L {
|
||||
21 to 29 step 2 -> cx16.r1L++
|
||||
else -> cx16.r1L--
|
||||
}
|
||||
}
|
||||
}"""
|
||||
compileText(VMTarget(), optimize=false, src, outputDir, writeAssembly=false).shouldNotBeNull()
|
||||
}
|
||||
|
||||
test("when on range expressions outside value datatype is error") {
|
||||
val src="""
|
||||
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
when cx16.r0L {
|
||||
300 to 400 -> cx16.r1L++
|
||||
else -> cx16.r1L--
|
||||
}
|
||||
}
|
||||
}"""
|
||||
val errors = ErrorReporterForTests()
|
||||
compileText(VMTarget(), optimize=false, src, outputDir, writeAssembly=false, errors = errors) shouldBe null
|
||||
errors.errors.size shouldBe 1
|
||||
errors.errors[0] shouldContain "values must be constant numbers"
|
||||
}
|
||||
|
||||
|
||||
test("sizeof number const evaluation in vardecl") {
|
||||
val src="""
|
||||
main {
|
||||
|
||||
Reference in New Issue
Block a user