* refactor RangeExpr, step 1: remove IStringEncoding as ctor arg and instead put it as arg to the two methods that actually depend on it: toConstantIntegerRange and size (as *it* calls the former)

This commit is contained in:
meisl 2021-07-17 20:45:17 +02:00
parent 3f6f25e06f
commit 48d3abc1fe
8 changed files with 23 additions and 30 deletions

View File

@ -19,7 +19,7 @@ internal class ForLoopsAsmGen(private val program: Program, private val asmgen:
throw AssemblyError("unknown dt")
when(stmt.iterable) {
is RangeExpr -> {
val range = (stmt.iterable as RangeExpr).toConstantIntegerRange()
val range = (stmt.iterable as RangeExpr).toConstantIntegerRange(asmgen.options.compTarget)
if(range==null) {
translateForOverNonconstRange(stmt, iterableDt.typeOrElse(DataType.UNDEFINED), stmt.iterable as RangeExpr)
} else {

View File

@ -223,7 +223,7 @@ internal class ConstantFoldingOptimizer(private val program: Program, private va
range.step
}
return RangeExpr(fromCast.valueOrZero(), toCast.valueOrZero(), newStep, compTarget, range.position)
return RangeExpr(fromCast.valueOrZero(), toCast.valueOrZero(), newStep, range.position)
}
// adjust the datatype of a range expression in for loops to the loop variable.

View File

@ -129,9 +129,9 @@ internal class ConstantIdentifierReplacer(private val program: Program, private
if(rangeExpr!=null) {
// convert the initializer range expression to an actual array
val declArraySize = decl.arraysize?.constIndex()
if(declArraySize!=null && declArraySize!=rangeExpr.size())
if(declArraySize!=null && declArraySize!=rangeExpr.size(compTarget))
errors.err("range expression size doesn't match declared array size", decl.value?.position!!)
val constRange = rangeExpr.toConstantIntegerRange()
val constRange = rangeExpr.toConstantIntegerRange(compTarget)
if(constRange!=null) {
val eltType = rangeExpr.inferType(program).typeOrElse(DataType.UBYTE)
val newValue = if(eltType in ByteDatatypes) {
@ -184,9 +184,9 @@ internal class ConstantIdentifierReplacer(private val program: Program, private
if(rangeExpr!=null) {
// convert the initializer range expression to an actual array of floats
val declArraySize = decl.arraysize?.constIndex()
if(declArraySize!=null && declArraySize!=rangeExpr.size())
if(declArraySize!=null && declArraySize!=rangeExpr.size(compTarget))
errors.err("range expression size doesn't match declared array size", decl.value?.position!!)
val constRange = rangeExpr.toConstantIntegerRange()
val constRange = rangeExpr.toConstantIntegerRange(compTarget)
if(constRange!=null) {
val newValue = ArrayLiteralValue(InferredTypes.InferredType.known(DataType.ARRAY_F),
constRange.map { NumericLiteralValue(DataType.FLOAT, it.toDouble(), decl.value!!.position) }.toTypedArray(),

View File

@ -162,7 +162,7 @@ internal class StatementOptimizer(private val program: Program,
val range = forLoop.iterable as? RangeExpr
if(range!=null) {
if(range.size()==1) {
if (range.size(compTarget) == 1) {
// for loop over a (constant) range of just a single value-- optimize the loop away
// loopvar/reg = range value , follow by block
val scope = AnonymousScope(mutableListOf(), forLoop.position)

View File

@ -16,7 +16,6 @@ import prog8.ast.statements.Subroutine
import prog8.ast.statements.VarDecl
import prog8.compiler.target.C64Target
import prog8.compiler.target.Cx16Target
import prog8.optimizer.ConstantIdentifierReplacer
/**
@ -146,7 +145,7 @@ class TestCompilerOnRanges {
@Test
fun testForLoopWithRange_char_to_char() {
val platform = Cx16Target
val result = compileText(platform, true, """
val result = compileText(platform, optimize = true, """
main {
sub start() {
ubyte i
@ -168,15 +167,16 @@ class TestCompilerOnRanges {
val expectedEnd = platform.encodeString("f", false)[0].toInt()
val expectedStr = "$expectedStart .. $expectedEnd"
val intProgression = rangeExpr.toConstantIntegerRange()
val intProgression = rangeExpr.toConstantIntegerRange(platform)
val actualStr = "${intProgression?.first} .. ${intProgression?.last}"
assertEquals(expectedStr, actualStr,".first .. .last")
assertEquals(expectedEnd - expectedStart + 1, rangeExpr.size(), "rangeExpr.size()")
assertEquals(expectedEnd - expectedStart + 1, rangeExpr.size(platform), "rangeExpr.size()")
}
@Test
fun testForLoopWithRange_bool_to_bool() {
val result = compileText(Cx16Target, true, """
val platform = Cx16Target
val result = compileText(platform, optimize = true, """
main {
sub start() {
ubyte i
@ -194,15 +194,16 @@ class TestCompilerOnRanges {
.map { it.iterable }
.filterIsInstance<RangeExpr>()[0]
assertEquals(2, rangeExpr.size())
val intProgression = rangeExpr.toConstantIntegerRange()
assertEquals(2, rangeExpr.size(platform))
val intProgression = rangeExpr.toConstantIntegerRange(platform)
assertEquals(0, intProgression?.first)
assertEquals(1, intProgression?.last)
}
@Test
fun testForLoopWithRange_ubyte_to_ubyte() {
val result = compileText(Cx16Target, true, """
val platform = Cx16Target
val result = compileText(platform, optimize = true, """
main {
sub start() {
ubyte i
@ -220,8 +221,8 @@ class TestCompilerOnRanges {
.map { it.iterable }
.filterIsInstance<RangeExpr>()[0]
assertEquals(9, rangeExpr.size())
val intProgression = rangeExpr.toConstantIntegerRange()
assertEquals(9, rangeExpr.size(platform))
val intProgression = rangeExpr.toConstantIntegerRange(platform)
assertEquals(1, intProgression?.first)
assertEquals(9, intProgression?.last)
}

View File

@ -6,9 +6,6 @@ import prog8.ast.statements.*
import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstVisitor
import prog8.parser.SourceCode
import java.nio.file.Path
import java.nio.file.Paths
import kotlin.io.path.name
import kotlin.math.abs
const val internedStringsModuleName = "prog8_interned_strings"

View File

@ -1,6 +1,5 @@
package prog8.ast.antlr
import org.antlr.v4.runtime.IntStream
import org.antlr.v4.runtime.ParserRuleContext
import org.antlr.v4.runtime.tree.TerminalNode
import prog8.ast.IStringEncoding
@ -10,9 +9,6 @@ import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.parser.Prog8ANTLRParser
import prog8.parser.SourceCode
import java.io.CharConversionException
import java.io.File
import java.nio.file.Path
/***************** Antlr Extension methods to create AST ****************/
@ -462,7 +458,7 @@ private fun Prog8ANTLRParser.ExpressionContext.toAst(encoding: IStringEncoding)
if (rangefrom!=null && rangeto!=null) {
val defaultstep = if(rto.text == "to") 1 else -1
val step = rangestep?.toAst(encoding) ?: NumericLiteralValue(DataType.UBYTE, defaultstep, toPosition())
return RangeExpr(rangefrom.toAst(encoding), rangeto.toAst(encoding), step, encoding, toPosition())
return RangeExpr(rangefrom.toAst(encoding), rangeto.toAst(encoding), step, toPosition())
}
if(childCount==3 && children[0].text=="(" && children[2].text==")")
@ -581,7 +577,7 @@ private fun Prog8ANTLRParser.UntilloopContext.toAst(encoding: IStringEncoding):
private fun Prog8ANTLRParser.WhenstmtContext.toAst(encoding: IStringEncoding): WhenStatement {
val condition = expression().toAst(encoding)
val choices = this.when_choice()?.map { it.toAst(encoding) }?.toMutableList() ?: mutableListOf()
val choices = this.when_choice()?.map { it.toAst(encoding) }?.toMutableList() ?: mutableListOf<WhenChoice>()
return WhenStatement(condition, choices, toPosition())
}

View File

@ -667,7 +667,6 @@ class ArrayLiteralValue(val type: InferredTypes.InferredType, // inferred be
class RangeExpr(var from: Expression,
var to: Expression,
var step: Expression,
private val encoding: IStringEncoding,
override val position: Position) : Expression() {
override lateinit var parent: Node
@ -720,15 +719,15 @@ class RangeExpr(var from: Expression,
return "RangeExpr(from $from, to $to, step $step, pos=$position)"
}
fun size(): Int? {
fun size(encoding: IStringEncoding): Int? {
val fromLv = (from as? NumericLiteralValue)
val toLv = (to as? NumericLiteralValue)
if(fromLv==null || toLv==null)
return null
return toConstantIntegerRange()?.count()
return toConstantIntegerRange(encoding)?.count()
}
fun toConstantIntegerRange(): IntProgression? {
fun toConstantIntegerRange(encoding: IStringEncoding): IntProgression? {
val fromVal: Int
val toVal: Int
val fromString = from as? StringLiteralValue