clarified isInRegularRAM() by making it an extension method on AssignTarget

This commit is contained in:
Irmen de Jong 2021-10-19 22:36:05 +02:00
parent 5afa7e53f8
commit 804bb06859
6 changed files with 76 additions and 73 deletions

View File

@ -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) {

View File

@ -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
}
}

View File

@ -24,51 +24,6 @@ interface ICompilationTarget: IStringEncoding, IMemSizer {
val machine: IMachineDefinition
override fun encodeString(str: String, altEncoding: Boolean): List<Short>
override fun decodeString(bytes: List<Short>, 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
}
}
}

View File

@ -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

View File

@ -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) {

View File

@ -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))
}
}