mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
* 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:
parent
3f6f25e06f
commit
48d3abc1fe
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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(),
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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())
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user