diff --git a/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt b/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt index 4436e78e9..a9894b9ff 100644 --- a/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt +++ b/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt @@ -39,7 +39,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, program)) { + && compTarget.isInRegularRAM(assignment.target)) { 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/target/ICompilationTarget.kt b/compiler/src/prog8/compiler/target/ICompilationTarget.kt index eb06b9a0f..9522ed26f 100644 --- a/compiler/src/prog8/compiler/target/ICompilationTarget.kt +++ b/compiler/src/prog8/compiler/target/ICompilationTarget.kt @@ -26,8 +26,7 @@ interface ICompilationTarget: IStringEncoding, IMemSizer { override fun decodeString(bytes: List, altEncoding: Boolean): String // TODO: rename param target, and also AST node AssignTarget - *different meaning of "target"!* - // TODO: remove param program - can be obtained from AST node - fun isInRegularRAM(target: AssignTarget, program: Program): Boolean { + fun isInRegularRAM(target: AssignTarget): Boolean { val memAddr = target.memoryAddress val arrayIdx = target.arrayindexed val ident = target.identifier @@ -38,6 +37,7 @@ interface ICompilationTarget: IStringEncoding, IMemSizer { 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()) @@ -48,6 +48,7 @@ interface ICompilationTarget: IStringEncoding, IMemSizer { } } 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 @@ -58,6 +59,7 @@ interface ICompilationTarget: IStringEncoding, IMemSizer { } 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()) diff --git a/compiler/src/prog8/optimizer/BinExprSplitter.kt b/compiler/src/prog8/optimizer/BinExprSplitter.kt index 71631ecfe..fd18ac561 100644 --- a/compiler/src/prog8/optimizer/BinExprSplitter.kt +++ b/compiler/src/prog8/optimizer/BinExprSplitter.kt @@ -54,7 +54,7 @@ X = BinExpr X = LeftExpr */ - if(binExpr.operator in augmentAssignmentOperators && isSimpleTarget(assignment.target, program)) { + if(binExpr.operator in augmentAssignmentOperators && isSimpleTarget(assignment.target)) { if(assignment.target isSameAs binExpr.left || assignment.target isSameAs binExpr.right) return noModifications @@ -77,9 +77,9 @@ X = BinExpr X = LeftExpr return noModifications } - private fun isSimpleTarget(target: AssignTarget, program: Program) = + private fun isSimpleTarget(target: AssignTarget) = if (target.identifier!=null || target.memoryAddress!=null) - compTarget.isInRegularRAM(target, program) + compTarget.isInRegularRAM(target) else false diff --git a/compiler/src/prog8/optimizer/UnusedCodeRemover.kt b/compiler/src/prog8/optimizer/UnusedCodeRemover.kt index 00ba0ddb6..7f9dd7ce2 100644 --- a/compiler/src/prog8/optimizer/UnusedCodeRemover.kt +++ b/compiler/src/prog8/optimizer/UnusedCodeRemover.kt @@ -122,7 +122,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, program)) { + if (assign1.target.isSameAs(assign2.target, program) && compTarget.isInRegularRAM(assign1.target)) { 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/AsmgenTests.kt b/compiler/test/AsmgenTests.kt index c66db1ce6..73d3689d3 100644 --- a/compiler/test/AsmgenTests.kt +++ b/compiler/test/AsmgenTests.kt @@ -71,7 +71,7 @@ locallabel: val module = Module(mutableListOf(block), Position.DUMMY, SourceCode.Generated("test")) val program = Program("test", DummyFunctions, DummyMemsizer) .addModule(module) - module.linkParents(program.namespace) + module.linkIntoProgram(program) return program } diff --git a/compiler/test/TestMemory.kt b/compiler/test/TestMemory.kt index f5e2a5659..3310dd911 100644 --- a/compiler/test/TestMemory.kt +++ b/compiler/test/TestMemory.kt @@ -5,7 +5,6 @@ import org.junit.jupiter.api.TestInstance import prog8.ast.Module import prog8.ast.Program import prog8.ast.base.DataType -import prog8.ast.base.ParentSentinel import prog8.ast.base.Position import prog8.ast.base.VarDeclType import prog8.ast.expressions.ArrayIndexedExpression @@ -29,24 +28,23 @@ class TestMemory { var memexpr = NumericLiteralValue.optimalInteger(0x0000, Position.DUMMY) var target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - val program = Program("test", DummyFunctions, DummyMemsizer) - assertTrue(C64Target.isInRegularRAM(target, program)) + assertTrue(C64Target.isInRegularRAM(target)) memexpr = NumericLiteralValue.optimalInteger(0x1000, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertTrue(C64Target.isInRegularRAM(target, program)) + assertTrue(C64Target.isInRegularRAM(target)) memexpr = NumericLiteralValue.optimalInteger(0x9fff, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertTrue(C64Target.isInRegularRAM(target, program)) + assertTrue(C64Target.isInRegularRAM(target)) memexpr = NumericLiteralValue.optimalInteger(0xc000, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertTrue(C64Target.isInRegularRAM(target, program)) + assertTrue(C64Target.isInRegularRAM(target)) memexpr = NumericLiteralValue.optimalInteger(0xcfff, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertTrue(C64Target.isInRegularRAM(target, program)) + assertTrue(C64Target.isInRegularRAM(target)) } @Test @@ -54,20 +52,19 @@ class TestMemory { var memexpr = NumericLiteralValue.optimalInteger(0xa000, Position.DUMMY) var target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - val program = Program("test", DummyFunctions, DummyMemsizer) - assertFalse(C64Target.isInRegularRAM(target, program)) + assertFalse(C64Target.isInRegularRAM(target)) memexpr = NumericLiteralValue.optimalInteger(0xafff, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertFalse(C64Target.isInRegularRAM(target, program)) + assertFalse(C64Target.isInRegularRAM(target)) memexpr = NumericLiteralValue.optimalInteger(0xd000, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertFalse(C64Target.isInRegularRAM(target, program)) + assertFalse(C64Target.isInRegularRAM(target)) memexpr = NumericLiteralValue.optimalInteger(0xffff, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertFalse(C64Target.isInRegularRAM(target, program)) + assertFalse(C64Target.isInRegularRAM(target)) } @Test @@ -75,15 +72,15 @@ class TestMemory { val program = Program("test", DummyFunctions, DummyMemsizer) var target = createTestProgramForMemoryRefViaVar(program, 0x1000, VarDeclType.VAR) - assertTrue(C64Target.isInRegularRAM(target, program)) + assertTrue(C64Target.isInRegularRAM(target)) target = createTestProgramForMemoryRefViaVar(program, 0xd020, VarDeclType.VAR) - assertFalse(C64Target.isInRegularRAM(target, program)) + assertFalse(C64Target.isInRegularRAM(target)) target = createTestProgramForMemoryRefViaVar(program, 0x1000, VarDeclType.CONST) - assertTrue(C64Target.isInRegularRAM(target, program)) + assertTrue(C64Target.isInRegularRAM(target)) target = createTestProgramForMemoryRefViaVar(program, 0xd020, VarDeclType.CONST) - assertFalse(C64Target.isInRegularRAM(target, program)) + assertFalse(C64Target.isInRegularRAM(target)) target = createTestProgramForMemoryRefViaVar(program, 0x1000, VarDeclType.MEMORY) - assertFalse(C64Target.isInRegularRAM(target, program)) + assertFalse(C64Target.isInRegularRAM(target)) } private fun createTestProgramForMemoryRefViaVar(program: Program, address: Int, vartype: VarDeclType): AssignTarget { @@ -93,7 +90,7 @@ class TestMemory { val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY) val subroutine = Subroutine("test", emptyList(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY) val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) - module.linkParents(program.namespace) + module.linkIntoProgram(program) return target } @@ -101,8 +98,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) - val program = Program("test", DummyFunctions, DummyMemsizer) - assertFalse(C64Target.isInRegularRAM(target, program)) + assertFalse(C64Target.isInRegularRAM(target)) } @Test @@ -114,8 +110,8 @@ class TestMemory { val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) val program = Program("test", DummyFunctions, DummyMemsizer) .addModule(module) - module.linkParents(program.namespace) - assertTrue(C64Target.isInRegularRAM(target, program)) + module.linkIntoProgram(program) + assertTrue(C64Target.isInRegularRAM(target)) } @Test @@ -128,8 +124,8 @@ class TestMemory { val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) val program = Program("test", DummyFunctions, DummyMemsizer) .addModule(module) - module.linkParents(program.namespace) - assertTrue(C64Target.isInRegularRAM(target, program)) + module.linkIntoProgram(program) + assertTrue(C64Target.isInRegularRAM(target)) } @Test @@ -142,8 +138,8 @@ class TestMemory { val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) val program = Program("test", DummyFunctions, DummyMemsizer) .addModule(module) - module.linkParents(program.namespace) - assertFalse(C64Target.isInRegularRAM(target, program)) + module.linkIntoProgram(program) + assertFalse(C64Target.isInRegularRAM(target)) } @Test @@ -156,8 +152,8 @@ class TestMemory { val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) val program = Program("test", DummyFunctions, DummyMemsizer) .addModule(module) - module.linkParents(program.namespace) - assertTrue(C64Target.isInRegularRAM(target, program)) + module.linkIntoProgram(program) + assertTrue(C64Target.isInRegularRAM(target)) } @Test @@ -171,8 +167,8 @@ class TestMemory { val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) val program = Program("test", DummyFunctions, DummyMemsizer) .addModule(module) - module.linkParents(program.namespace) - assertTrue(C64Target.isInRegularRAM(target, program)) + module.linkIntoProgram(program) + assertTrue(C64Target.isInRegularRAM(target)) } @Test @@ -186,7 +182,7 @@ class TestMemory { val module = Module(mutableListOf(subroutine), Position.DUMMY, SourceCode.Generated("test")) val program = Program("test", DummyFunctions, DummyMemsizer) .addModule(module) - module.linkParents(program.namespace) - assertFalse(C64Target.isInRegularRAM(target, program)) + module.linkIntoProgram(program) + assertFalse(C64Target.isInRegularRAM(target)) } } diff --git a/compilerAst/src/prog8/ast/AstToplevel.kt b/compilerAst/src/prog8/ast/AstToplevel.kt index 0d06205d4..f73abdc74 100644 --- a/compilerAst/src/prog8/ast/AstToplevel.kt +++ b/compilerAst/src/prog8/ast/AstToplevel.kt @@ -371,6 +371,12 @@ open class Module(final override var statements: MutableList, statements.forEach {it.linkParents(this)} } + fun linkIntoProgram(program: Program) { + this.program = program + linkParents(program.namespace) + // TODO do this in program.addModule() ? + } + override val definingScope: INameScope get() = program.namespace override fun replaceChildNode(node: Node, replacement: Node) {