mirror of
https://github.com/irmen/prog8.git
synced 2024-09-07 19:54:26 +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")
|
throw AssemblyError("unknown dt")
|
||||||
when(stmt.iterable) {
|
when(stmt.iterable) {
|
||||||
is RangeExpr -> {
|
is RangeExpr -> {
|
||||||
val range = (stmt.iterable as RangeExpr).toConstantIntegerRange()
|
val range = (stmt.iterable as RangeExpr).toConstantIntegerRange(asmgen.options.compTarget)
|
||||||
if(range==null) {
|
if(range==null) {
|
||||||
translateForOverNonconstRange(stmt, iterableDt.typeOrElse(DataType.UNDEFINED), stmt.iterable as RangeExpr)
|
translateForOverNonconstRange(stmt, iterableDt.typeOrElse(DataType.UNDEFINED), stmt.iterable as RangeExpr)
|
||||||
} else {
|
} else {
|
||||||
|
@ -223,7 +223,7 @@ internal class ConstantFoldingOptimizer(private val program: Program, private va
|
|||||||
range.step
|
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.
|
// 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) {
|
if(rangeExpr!=null) {
|
||||||
// convert the initializer range expression to an actual array
|
// convert the initializer range expression to an actual array
|
||||||
val declArraySize = decl.arraysize?.constIndex()
|
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!!)
|
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) {
|
if(constRange!=null) {
|
||||||
val eltType = rangeExpr.inferType(program).typeOrElse(DataType.UBYTE)
|
val eltType = rangeExpr.inferType(program).typeOrElse(DataType.UBYTE)
|
||||||
val newValue = if(eltType in ByteDatatypes) {
|
val newValue = if(eltType in ByteDatatypes) {
|
||||||
@ -184,9 +184,9 @@ internal class ConstantIdentifierReplacer(private val program: Program, private
|
|||||||
if(rangeExpr!=null) {
|
if(rangeExpr!=null) {
|
||||||
// convert the initializer range expression to an actual array of floats
|
// convert the initializer range expression to an actual array of floats
|
||||||
val declArraySize = decl.arraysize?.constIndex()
|
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!!)
|
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) {
|
if(constRange!=null) {
|
||||||
val newValue = ArrayLiteralValue(InferredTypes.InferredType.known(DataType.ARRAY_F),
|
val newValue = ArrayLiteralValue(InferredTypes.InferredType.known(DataType.ARRAY_F),
|
||||||
constRange.map { NumericLiteralValue(DataType.FLOAT, it.toDouble(), decl.value!!.position) }.toTypedArray(),
|
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
|
val range = forLoop.iterable as? RangeExpr
|
||||||
if(range!=null) {
|
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
|
// for loop over a (constant) range of just a single value-- optimize the loop away
|
||||||
// loopvar/reg = range value , follow by block
|
// loopvar/reg = range value , follow by block
|
||||||
val scope = AnonymousScope(mutableListOf(), forLoop.position)
|
val scope = AnonymousScope(mutableListOf(), forLoop.position)
|
||||||
|
@ -16,7 +16,6 @@ import prog8.ast.statements.Subroutine
|
|||||||
import prog8.ast.statements.VarDecl
|
import prog8.ast.statements.VarDecl
|
||||||
import prog8.compiler.target.C64Target
|
import prog8.compiler.target.C64Target
|
||||||
import prog8.compiler.target.Cx16Target
|
import prog8.compiler.target.Cx16Target
|
||||||
import prog8.optimizer.ConstantIdentifierReplacer
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,7 +145,7 @@ class TestCompilerOnRanges {
|
|||||||
@Test
|
@Test
|
||||||
fun testForLoopWithRange_char_to_char() {
|
fun testForLoopWithRange_char_to_char() {
|
||||||
val platform = Cx16Target
|
val platform = Cx16Target
|
||||||
val result = compileText(platform, true, """
|
val result = compileText(platform, optimize = true, """
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
ubyte i
|
ubyte i
|
||||||
@ -168,15 +167,16 @@ class TestCompilerOnRanges {
|
|||||||
val expectedEnd = platform.encodeString("f", false)[0].toInt()
|
val expectedEnd = platform.encodeString("f", false)[0].toInt()
|
||||||
val expectedStr = "$expectedStart .. $expectedEnd"
|
val expectedStr = "$expectedStart .. $expectedEnd"
|
||||||
|
|
||||||
val intProgression = rangeExpr.toConstantIntegerRange()
|
val intProgression = rangeExpr.toConstantIntegerRange(platform)
|
||||||
val actualStr = "${intProgression?.first} .. ${intProgression?.last}"
|
val actualStr = "${intProgression?.first} .. ${intProgression?.last}"
|
||||||
assertEquals(expectedStr, actualStr,".first .. .last")
|
assertEquals(expectedStr, actualStr,".first .. .last")
|
||||||
assertEquals(expectedEnd - expectedStart + 1, rangeExpr.size(), "rangeExpr.size()")
|
assertEquals(expectedEnd - expectedStart + 1, rangeExpr.size(platform), "rangeExpr.size()")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testForLoopWithRange_bool_to_bool() {
|
fun testForLoopWithRange_bool_to_bool() {
|
||||||
val result = compileText(Cx16Target, true, """
|
val platform = Cx16Target
|
||||||
|
val result = compileText(platform, optimize = true, """
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
ubyte i
|
ubyte i
|
||||||
@ -194,15 +194,16 @@ class TestCompilerOnRanges {
|
|||||||
.map { it.iterable }
|
.map { it.iterable }
|
||||||
.filterIsInstance<RangeExpr>()[0]
|
.filterIsInstance<RangeExpr>()[0]
|
||||||
|
|
||||||
assertEquals(2, rangeExpr.size())
|
assertEquals(2, rangeExpr.size(platform))
|
||||||
val intProgression = rangeExpr.toConstantIntegerRange()
|
val intProgression = rangeExpr.toConstantIntegerRange(platform)
|
||||||
assertEquals(0, intProgression?.first)
|
assertEquals(0, intProgression?.first)
|
||||||
assertEquals(1, intProgression?.last)
|
assertEquals(1, intProgression?.last)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testForLoopWithRange_ubyte_to_ubyte() {
|
fun testForLoopWithRange_ubyte_to_ubyte() {
|
||||||
val result = compileText(Cx16Target, true, """
|
val platform = Cx16Target
|
||||||
|
val result = compileText(platform, optimize = true, """
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
ubyte i
|
ubyte i
|
||||||
@ -220,8 +221,8 @@ class TestCompilerOnRanges {
|
|||||||
.map { it.iterable }
|
.map { it.iterable }
|
||||||
.filterIsInstance<RangeExpr>()[0]
|
.filterIsInstance<RangeExpr>()[0]
|
||||||
|
|
||||||
assertEquals(9, rangeExpr.size())
|
assertEquals(9, rangeExpr.size(platform))
|
||||||
val intProgression = rangeExpr.toConstantIntegerRange()
|
val intProgression = rangeExpr.toConstantIntegerRange(platform)
|
||||||
assertEquals(1, intProgression?.first)
|
assertEquals(1, intProgression?.first)
|
||||||
assertEquals(9, intProgression?.last)
|
assertEquals(9, intProgression?.last)
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,6 @@ import prog8.ast.statements.*
|
|||||||
import prog8.ast.walk.AstWalker
|
import prog8.ast.walk.AstWalker
|
||||||
import prog8.ast.walk.IAstVisitor
|
import prog8.ast.walk.IAstVisitor
|
||||||
import prog8.parser.SourceCode
|
import prog8.parser.SourceCode
|
||||||
import java.nio.file.Path
|
|
||||||
import java.nio.file.Paths
|
|
||||||
import kotlin.io.path.name
|
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
|
||||||
const val internedStringsModuleName = "prog8_interned_strings"
|
const val internedStringsModuleName = "prog8_interned_strings"
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package prog8.ast.antlr
|
package prog8.ast.antlr
|
||||||
|
|
||||||
import org.antlr.v4.runtime.IntStream
|
|
||||||
import org.antlr.v4.runtime.ParserRuleContext
|
import org.antlr.v4.runtime.ParserRuleContext
|
||||||
import org.antlr.v4.runtime.tree.TerminalNode
|
import org.antlr.v4.runtime.tree.TerminalNode
|
||||||
import prog8.ast.IStringEncoding
|
import prog8.ast.IStringEncoding
|
||||||
@ -10,9 +9,6 @@ import prog8.ast.expressions.*
|
|||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.parser.Prog8ANTLRParser
|
import prog8.parser.Prog8ANTLRParser
|
||||||
import prog8.parser.SourceCode
|
import prog8.parser.SourceCode
|
||||||
import java.io.CharConversionException
|
|
||||||
import java.io.File
|
|
||||||
import java.nio.file.Path
|
|
||||||
|
|
||||||
|
|
||||||
/***************** Antlr Extension methods to create AST ****************/
|
/***************** Antlr Extension methods to create AST ****************/
|
||||||
@ -462,7 +458,7 @@ private fun Prog8ANTLRParser.ExpressionContext.toAst(encoding: IStringEncoding)
|
|||||||
if (rangefrom!=null && rangeto!=null) {
|
if (rangefrom!=null && rangeto!=null) {
|
||||||
val defaultstep = if(rto.text == "to") 1 else -1
|
val defaultstep = if(rto.text == "to") 1 else -1
|
||||||
val step = rangestep?.toAst(encoding) ?: NumericLiteralValue(DataType.UBYTE, defaultstep, toPosition())
|
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==")")
|
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 {
|
private fun Prog8ANTLRParser.WhenstmtContext.toAst(encoding: IStringEncoding): WhenStatement {
|
||||||
val condition = expression().toAst(encoding)
|
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())
|
return WhenStatement(condition, choices, toPosition())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -667,7 +667,6 @@ class ArrayLiteralValue(val type: InferredTypes.InferredType, // inferred be
|
|||||||
class RangeExpr(var from: Expression,
|
class RangeExpr(var from: Expression,
|
||||||
var to: Expression,
|
var to: Expression,
|
||||||
var step: Expression,
|
var step: Expression,
|
||||||
private val encoding: IStringEncoding,
|
|
||||||
override val position: Position) : Expression() {
|
override val position: Position) : Expression() {
|
||||||
override lateinit var parent: Node
|
override lateinit var parent: Node
|
||||||
|
|
||||||
@ -720,15 +719,15 @@ class RangeExpr(var from: Expression,
|
|||||||
return "RangeExpr(from $from, to $to, step $step, pos=$position)"
|
return "RangeExpr(from $from, to $to, step $step, pos=$position)"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun size(): Int? {
|
fun size(encoding: IStringEncoding): Int? {
|
||||||
val fromLv = (from as? NumericLiteralValue)
|
val fromLv = (from as? NumericLiteralValue)
|
||||||
val toLv = (to as? NumericLiteralValue)
|
val toLv = (to as? NumericLiteralValue)
|
||||||
if(fromLv==null || toLv==null)
|
if(fromLv==null || toLv==null)
|
||||||
return null
|
return null
|
||||||
return toConstantIntegerRange()?.count()
|
return toConstantIntegerRange(encoding)?.count()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toConstantIntegerRange(): IntProgression? {
|
fun toConstantIntegerRange(encoding: IStringEncoding): IntProgression? {
|
||||||
val fromVal: Int
|
val fromVal: Int
|
||||||
val toVal: Int
|
val toVal: Int
|
||||||
val fromString = from as? StringLiteralValue
|
val fromString = from as? StringLiteralValue
|
||||||
|
Loading…
Reference in New Issue
Block a user