diff --git a/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt b/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt index a9894b9ff..5761b5591 100644 --- a/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt +++ b/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt @@ -9,6 +9,7 @@ import prog8.ast.statements.* import prog8.ast.walk.AstWalker import prog8.ast.walk.IAstModification import prog8.ast.walk.IAstVisitor +import prog8.compiler.astprocessing.isInRegularRAMof import prog8.compiler.target.ICompilationTarget @@ -39,7 +40,7 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: I // But it can only be done if the target variable IS NOT OCCURRING AS AN OPERAND ITSELF. if(!assignment.isAugmentable && assignment.target.identifier != null - && compTarget.isInRegularRAM(assignment.target)) { + && assignment.target.isInRegularRAMof(compTarget.machine)) { val binExpr = assignment.value as? BinaryExpression if (binExpr != null && binExpr.operator !in comparisonOperators) { if (binExpr.left !is BinaryExpression) { diff --git a/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt b/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt index fcff410d1..e7fabca4a 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt @@ -3,10 +3,9 @@ package prog8.compiler.astprocessing import prog8.ast.Node import prog8.ast.Program import prog8.ast.base.DataType -import prog8.ast.expressions.CharLiteral -import prog8.ast.expressions.NumericLiteralValue -import prog8.ast.expressions.RangeExpr -import prog8.ast.expressions.StringLiteralValue +import prog8.ast.base.VarDeclType +import prog8.ast.expressions.* +import prog8.ast.statements.AssignTarget import prog8.ast.statements.Directive import prog8.ast.walk.AstWalker import prog8.ast.walk.IAstModification @@ -15,6 +14,7 @@ import prog8.compiler.CompilationOptions import prog8.compiler.IErrorReporter import prog8.compiler.IStringEncoding import prog8.compiler.target.ICompilationTarget +import prog8.compiler.target.IMachineDefinition import kotlin.math.abs @@ -165,3 +165,47 @@ internal fun Program.moveMainAndStartToFirst() { modules[0].statements.add(0, directive) } } + +internal fun AssignTarget.isInRegularRAMof(machine: IMachineDefinition): Boolean { + val memAddr = memoryAddress + val arrayIdx = arrayindexed + val ident = identifier + when { + memAddr != null -> { + return when (memAddr.addressExpression) { + is NumericLiteralValue -> { + machine.isRegularRAMaddress((memAddr.addressExpression as NumericLiteralValue).number.toInt()) + } + is IdentifierReference -> { + val program = definingModule.program + val decl = (memAddr.addressExpression as IdentifierReference).targetVarDecl(program) + if ((decl?.type == VarDeclType.VAR || decl?.type == VarDeclType.CONST) && decl.value is NumericLiteralValue) + machine.isRegularRAMaddress((decl.value as NumericLiteralValue).number.toInt()) + else + false + } + else -> false + } + } + arrayIdx != null -> { + val program = definingModule.program + val targetStmt = arrayIdx.arrayvar.targetVarDecl(program) + return if (targetStmt?.type == VarDeclType.MEMORY) { + val addr = targetStmt.value as? NumericLiteralValue + if (addr != null) + machine.isRegularRAMaddress(addr.number.toInt()) + else + false + } else true + } + ident != null -> { + val program = definingModule.program + val decl = ident.targetVarDecl(program)!! + return if (decl.type == VarDeclType.MEMORY && decl.value is NumericLiteralValue) + machine.isRegularRAMaddress((decl.value as NumericLiteralValue).number.toInt()) + else + true + } + else -> return true + } +} diff --git a/compiler/src/prog8/compiler/target/ICompilationTarget.kt b/compiler/src/prog8/compiler/target/ICompilationTarget.kt index 9522ed26f..4fea51cd9 100644 --- a/compiler/src/prog8/compiler/target/ICompilationTarget.kt +++ b/compiler/src/prog8/compiler/target/ICompilationTarget.kt @@ -24,51 +24,6 @@ interface ICompilationTarget: IStringEncoding, IMemSizer { val machine: IMachineDefinition override fun encodeString(str: String, altEncoding: Boolean): List override fun decodeString(bytes: List, altEncoding: Boolean): String - - // TODO: rename param target, and also AST node AssignTarget - *different meaning of "target"!* - fun isInRegularRAM(target: AssignTarget): Boolean { - val memAddr = target.memoryAddress - val arrayIdx = target.arrayindexed - val ident = target.identifier - when { - memAddr != null -> { - return when (memAddr.addressExpression) { - is NumericLiteralValue -> { - machine.isRegularRAMaddress((memAddr.addressExpression as NumericLiteralValue).number.toInt()) - } - is IdentifierReference -> { - val program = target.definingModule.program - val decl = (memAddr.addressExpression as IdentifierReference).targetVarDecl(program) - if ((decl?.type == VarDeclType.VAR || decl?.type == VarDeclType.CONST) && decl.value is NumericLiteralValue) - machine.isRegularRAMaddress((decl.value as NumericLiteralValue).number.toInt()) - else - false - } - else -> false - } - } - arrayIdx != null -> { - val program = target.definingModule.program - val targetStmt = arrayIdx.arrayvar.targetVarDecl(program) - return if (targetStmt?.type == VarDeclType.MEMORY) { - val addr = targetStmt.value as? NumericLiteralValue - if (addr != null) - machine.isRegularRAMaddress(addr.number.toInt()) - else - false - } else true - } - ident != null -> { - val program = target.definingModule.program - val decl = ident.targetVarDecl(program)!! - return if (decl.type == VarDeclType.MEMORY && decl.value is NumericLiteralValue) - machine.isRegularRAMaddress((decl.value as NumericLiteralValue).number.toInt()) - else - true - } - else -> return true - } - } } diff --git a/compiler/src/prog8/optimizer/BinExprSplitter.kt b/compiler/src/prog8/optimizer/BinExprSplitter.kt index fd18ac561..4eada5f08 100644 --- a/compiler/src/prog8/optimizer/BinExprSplitter.kt +++ b/compiler/src/prog8/optimizer/BinExprSplitter.kt @@ -9,6 +9,7 @@ import prog8.ast.statements.AssignTarget import prog8.ast.statements.Assignment import prog8.ast.walk.AstWalker import prog8.ast.walk.IAstModification +import prog8.compiler.astprocessing.isInRegularRAMof import prog8.compiler.target.ICompilationTarget @@ -79,7 +80,7 @@ X = BinExpr X = LeftExpr private fun isSimpleTarget(target: AssignTarget) = if (target.identifier!=null || target.memoryAddress!=null) - compTarget.isInRegularRAM(target) + target.isInRegularRAMof(compTarget.machine) else false diff --git a/compiler/src/prog8/optimizer/UnusedCodeRemover.kt b/compiler/src/prog8/optimizer/UnusedCodeRemover.kt index 7f9dd7ce2..1e362606e 100644 --- a/compiler/src/prog8/optimizer/UnusedCodeRemover.kt +++ b/compiler/src/prog8/optimizer/UnusedCodeRemover.kt @@ -10,6 +10,7 @@ import prog8.ast.statements.* import prog8.ast.walk.AstWalker import prog8.ast.walk.IAstModification import prog8.compiler.IErrorReporter +import prog8.compiler.astprocessing.isInRegularRAMof import prog8.compiler.target.ICompilationTarget @@ -122,7 +123,7 @@ internal class UnusedCodeRemover(private val program: Program, val assign1 = stmtPairs[0] as? Assignment val assign2 = stmtPairs[1] as? Assignment if (assign1 != null && assign2 != null && !assign2.isAugmentable) { - if (assign1.target.isSameAs(assign2.target, program) && compTarget.isInRegularRAM(assign1.target)) { + if (assign1.target.isSameAs(assign2.target, program) && assign1.target.isInRegularRAMof(compTarget.machine)) { if(assign2.target.identifier==null || !assign2.value.referencesIdentifier(*(assign2.target.identifier!!.nameInSource.toTypedArray()))) // only remove the second assignment if its value is a simple expression! when(assign2.value) { diff --git a/compiler/test/TestMemory.kt b/compiler/test/TestMemory.kt index 3310dd911..6906e63f8 100644 --- a/compiler/test/TestMemory.kt +++ b/compiler/test/TestMemory.kt @@ -12,6 +12,7 @@ import prog8.ast.expressions.IdentifierReference import prog8.ast.expressions.NumericLiteralValue import prog8.ast.expressions.PrefixExpression import prog8.ast.statements.* +import prog8.compiler.astprocessing.isInRegularRAMof import prog8.compiler.target.C64Target import prog8.parser.SourceCode import prog8tests.helpers.DummyFunctions @@ -28,23 +29,23 @@ class TestMemory { var memexpr = NumericLiteralValue.optimalInteger(0x0000, Position.DUMMY) var target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertTrue(C64Target.isInRegularRAM(target)) + assertTrue(target.isInRegularRAMof(C64Target.machine)) memexpr = NumericLiteralValue.optimalInteger(0x1000, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertTrue(C64Target.isInRegularRAM(target)) + assertTrue(target.isInRegularRAMof(C64Target.machine)) memexpr = NumericLiteralValue.optimalInteger(0x9fff, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertTrue(C64Target.isInRegularRAM(target)) + assertTrue(target.isInRegularRAMof(C64Target.machine)) memexpr = NumericLiteralValue.optimalInteger(0xc000, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertTrue(C64Target.isInRegularRAM(target)) + assertTrue(target.isInRegularRAMof(C64Target.machine)) memexpr = NumericLiteralValue.optimalInteger(0xcfff, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertTrue(C64Target.isInRegularRAM(target)) + assertTrue(target.isInRegularRAMof(C64Target.machine)) } @Test @@ -52,19 +53,19 @@ class TestMemory { var memexpr = NumericLiteralValue.optimalInteger(0xa000, Position.DUMMY) var target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertFalse(C64Target.isInRegularRAM(target)) + assertFalse(target.isInRegularRAMof(C64Target.machine)) memexpr = NumericLiteralValue.optimalInteger(0xafff, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertFalse(C64Target.isInRegularRAM(target)) + assertFalse(target.isInRegularRAMof(C64Target.machine)) memexpr = NumericLiteralValue.optimalInteger(0xd000, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertFalse(C64Target.isInRegularRAM(target)) + assertFalse(target.isInRegularRAMof(C64Target.machine)) memexpr = NumericLiteralValue.optimalInteger(0xffff, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertFalse(C64Target.isInRegularRAM(target)) + assertFalse(target.isInRegularRAMof(C64Target.machine)) } @Test @@ -72,15 +73,15 @@ class TestMemory { val program = Program("test", DummyFunctions, DummyMemsizer) var target = createTestProgramForMemoryRefViaVar(program, 0x1000, VarDeclType.VAR) - assertTrue(C64Target.isInRegularRAM(target)) + assertTrue(target.isInRegularRAMof(C64Target.machine)) target = createTestProgramForMemoryRefViaVar(program, 0xd020, VarDeclType.VAR) - assertFalse(C64Target.isInRegularRAM(target)) + assertFalse(target.isInRegularRAMof(C64Target.machine)) target = createTestProgramForMemoryRefViaVar(program, 0x1000, VarDeclType.CONST) - assertTrue(C64Target.isInRegularRAM(target)) + assertTrue(target.isInRegularRAMof(C64Target.machine)) target = createTestProgramForMemoryRefViaVar(program, 0xd020, VarDeclType.CONST) - assertFalse(C64Target.isInRegularRAM(target)) + assertFalse(target.isInRegularRAMof(C64Target.machine)) target = createTestProgramForMemoryRefViaVar(program, 0x1000, VarDeclType.MEMORY) - assertFalse(C64Target.isInRegularRAM(target)) + assertFalse(target.isInRegularRAMof(C64Target.machine)) } private fun createTestProgramForMemoryRefViaVar(program: Program, address: Int, vartype: VarDeclType): AssignTarget { @@ -98,7 +99,7 @@ class TestMemory { fun testInValidRamC64_memory_expression() { val memexpr = PrefixExpression("+", NumericLiteralValue.optimalInteger(0x1000, Position.DUMMY), Position.DUMMY) val target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertFalse(C64Target.isInRegularRAM(target)) + assertFalse(target.isInRegularRAMof(C64Target.machine)) } @Test @@ -111,7 +112,7 @@ class TestMemory { val program = Program("test", DummyFunctions, DummyMemsizer) .addModule(module) module.linkIntoProgram(program) - assertTrue(C64Target.isInRegularRAM(target)) + assertTrue(target.isInRegularRAMof(C64Target.machine)) } @Test @@ -125,7 +126,7 @@ class TestMemory { val program = Program("test", DummyFunctions, DummyMemsizer) .addModule(module) module.linkIntoProgram(program) - assertTrue(C64Target.isInRegularRAM(target)) + assertTrue(target.isInRegularRAMof(C64Target.machine)) } @Test @@ -139,7 +140,7 @@ class TestMemory { val program = Program("test", DummyFunctions, DummyMemsizer) .addModule(module) module.linkIntoProgram(program) - assertFalse(C64Target.isInRegularRAM(target)) + assertFalse(target.isInRegularRAMof(C64Target.machine)) } @Test @@ -153,7 +154,7 @@ class TestMemory { val program = Program("test", DummyFunctions, DummyMemsizer) .addModule(module) module.linkIntoProgram(program) - assertTrue(C64Target.isInRegularRAM(target)) + assertTrue(target.isInRegularRAMof(C64Target.machine)) } @Test @@ -168,7 +169,7 @@ class TestMemory { val program = Program("test", DummyFunctions, DummyMemsizer) .addModule(module) module.linkIntoProgram(program) - assertTrue(C64Target.isInRegularRAM(target)) + assertTrue(target.isInRegularRAMof(C64Target.machine)) } @Test @@ -183,6 +184,6 @@ class TestMemory { val program = Program("test", DummyFunctions, DummyMemsizer) .addModule(module) module.linkIntoProgram(program) - assertFalse(C64Target.isInRegularRAM(target)) + assertFalse(target.isInRegularRAMof(C64Target.machine)) } }