From 48d3abc1feef35d81e4155a137f3390e30741ebb Mon Sep 17 00:00:00 2001 From: meisl Date: Sat, 17 Jul 2021 20:45:17 +0200 Subject: [PATCH] * 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) --- .../target/cpu6502/codegen/ForLoopsAsmGen.kt | 2 +- .../optimizer/ConstantFoldingOptimizer.kt | 2 +- .../optimizer/ConstantIdentifierReplacer.kt | 8 +++---- .../src/prog8/optimizer/StatementOptimizer.kt | 2 +- compiler/test/TestCompilerOnRanges.kt | 21 ++++++++++--------- compilerAst/src/prog8/ast/AstToplevel.kt | 3 --- .../src/prog8/ast/antlr/Antlr2Kotlin.kt | 8 ++----- .../prog8/ast/expressions/AstExpressions.kt | 7 +++---- 8 files changed, 23 insertions(+), 30 deletions(-) diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/ForLoopsAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/ForLoopsAsmGen.kt index 24e5229ec..1aa1a8bff 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/ForLoopsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/ForLoopsAsmGen.kt @@ -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 { diff --git a/compiler/src/prog8/optimizer/ConstantFoldingOptimizer.kt b/compiler/src/prog8/optimizer/ConstantFoldingOptimizer.kt index d0315a620..abe9ce509 100644 --- a/compiler/src/prog8/optimizer/ConstantFoldingOptimizer.kt +++ b/compiler/src/prog8/optimizer/ConstantFoldingOptimizer.kt @@ -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. diff --git a/compiler/src/prog8/optimizer/ConstantIdentifierReplacer.kt b/compiler/src/prog8/optimizer/ConstantIdentifierReplacer.kt index aae516238..f45bfd4a1 100644 --- a/compiler/src/prog8/optimizer/ConstantIdentifierReplacer.kt +++ b/compiler/src/prog8/optimizer/ConstantIdentifierReplacer.kt @@ -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(), diff --git a/compiler/src/prog8/optimizer/StatementOptimizer.kt b/compiler/src/prog8/optimizer/StatementOptimizer.kt index 413b6e2fd..af7455e22 100644 --- a/compiler/src/prog8/optimizer/StatementOptimizer.kt +++ b/compiler/src/prog8/optimizer/StatementOptimizer.kt @@ -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) diff --git a/compiler/test/TestCompilerOnRanges.kt b/compiler/test/TestCompilerOnRanges.kt index ee11c39ff..18e7bd16f 100644 --- a/compiler/test/TestCompilerOnRanges.kt +++ b/compiler/test/TestCompilerOnRanges.kt @@ -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()[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()[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) } diff --git a/compilerAst/src/prog8/ast/AstToplevel.kt b/compilerAst/src/prog8/ast/AstToplevel.kt index 81436cdac..dfbf16310 100644 --- a/compilerAst/src/prog8/ast/AstToplevel.kt +++ b/compilerAst/src/prog8/ast/AstToplevel.kt @@ -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" diff --git a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt index c2c81dd1c..ed6a10c2c 100644 --- a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt +++ b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt @@ -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() return WhenStatement(condition, choices, toPosition()) } diff --git a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt index d9aa47362..48205ff30 100644 --- a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt +++ b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt @@ -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