diff --git a/compiler/src/prog8/compiler/astprocessing/AstVariousTransforms.kt b/compiler/src/prog8/compiler/astprocessing/AstVariousTransforms.kt index 09033b56d..14b541c32 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstVariousTransforms.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstVariousTransforms.kt @@ -3,19 +3,16 @@ package prog8.compiler.astprocessing import prog8.ast.Node import prog8.ast.Program import prog8.ast.expressions.ArrayIndexedExpression -import prog8.ast.expressions.BinaryExpression -import prog8.ast.expressions.DirectMemoryRead -import prog8.ast.statements.AssignTarget -import prog8.ast.statements.DirectMemoryWrite import prog8.ast.statements.Subroutine import prog8.ast.statements.VarDecl import prog8.ast.walk.AstWalker import prog8.ast.walk.IAstModification -import prog8.code.core.DataType internal class AstVariousTransforms(private val program: Program) : AstWalker() { + // TODO can this be integrated in another walker + override fun after(subroutine: Subroutine, parent: Node): Iterable { // For non-kernal subroutines and non-asm parameters: // inject subroutine params as local variables (if they're not there yet). @@ -38,29 +35,8 @@ internal class AstVariousTransforms(private val program: Program) : AstWalker() return noModifications } + // TODO move this / remove this. Needed here atm otherwise a replacement error occurs later in StatementReorderer override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable { return replacePointerVarIndexWithMemreadOrMemwrite(program, arrayIndexedExpression, parent) } } - - - -internal fun replacePointerVarIndexWithMemreadOrMemwrite(program: Program, arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable { - val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program) - if(arrayVar!=null && arrayVar.datatype == DataType.UWORD) { - // rewrite pointervar[index] into @(pointervar+index) - val indexer = arrayIndexedExpression.indexer - val add = BinaryExpression(arrayIndexedExpression.arrayvar.copy(), "+", indexer.indexExpr, arrayIndexedExpression.position) - return if(parent is AssignTarget) { - // we're part of the target of an assignment, we have to actually change the assign target itself - val memwrite = DirectMemoryWrite(add, arrayIndexedExpression.position) - val newtarget = AssignTarget(null, null, memwrite, arrayIndexedExpression.position) - listOf(IAstModification.ReplaceNode(parent, newtarget, parent.parent)) - } else { - val memread = DirectMemoryRead(add, arrayIndexedExpression.position) - listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent)) - } - } - - return emptyList() -} diff --git a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt index 27dd70eda..811d5da46 100644 --- a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt +++ b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt @@ -576,3 +576,25 @@ private fun makeGosubWithArgsViaCpuStack( } return listOf(IAstModification.ReplaceNode(call as Node, scope, parent)) } + + + +internal fun replacePointerVarIndexWithMemreadOrMemwrite(program: Program, arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable { + val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program) + if(arrayVar!=null && arrayVar.datatype == DataType.UWORD) { + // rewrite pointervar[index] into @(pointervar+index) + val indexer = arrayIndexedExpression.indexer + val add = BinaryExpression(arrayIndexedExpression.arrayvar.copy(), "+", indexer.indexExpr, arrayIndexedExpression.position) + return if(parent is AssignTarget) { + // we're part of the target of an assignment, we have to actually change the assign target itself + val memwrite = DirectMemoryWrite(add, arrayIndexedExpression.position) + val newtarget = AssignTarget(null, null, memwrite, arrayIndexedExpression.position) + listOf(IAstModification.ReplaceNode(parent, newtarget, parent.parent)) + } else { + val memread = DirectMemoryRead(add, arrayIndexedExpression.position) + listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent)) + } + } + + return emptyList() +} diff --git a/compiler/test/TestOptimization.kt b/compiler/test/TestOptimization.kt index f0244d6a0..0b08a4e22 100644 --- a/compiler/test/TestOptimization.kt +++ b/compiler/test/TestOptimization.kt @@ -757,4 +757,19 @@ class TestOptimization: FunSpec({ val ifStmt = stmts[4] as IfElse ifStmt.condition shouldBe instanceOf() } + + test("pointer indexing inside other expression ok") { + val src=""" + main{ + sub start () { + uword eRef + if eRef[3] and 10 { + return + } + } + }""" + val result = compileText(C64Target(), optimize=true, src, writeAssembly=false)!! + val stmts = result.program.entrypoint.statements + stmts.size shouldBe 3 + } }) diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 1c5502c7c..921d87836 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,6 +3,7 @@ TODO For next release ^^^^^^^^^^^^^^^^ +- try to integrated AstVariousTransforms into another walker - why is this code so much larger: uword xx for xx in 0 to size-1 { diff --git a/examples/test.p8 b/examples/test.p8 index 761c02fa6..1011a76c1 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -28,6 +28,13 @@ main { ; txt.spc() ; } + sub crash () { + uword eRef + if eRef[3] and 10 { + return + } + } + sub start() { ; mcCarthy()