From 8618ba1b60b23087a11bc217ae6d9f4d2684a36c Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 4 Jun 2022 18:46:16 +0200 Subject: [PATCH] fix 6502 expression codegen for pointer indexing --- .../codegen/cpu6502/ExpressionsAsmGen.kt | 19 +++++++++++++++++ .../compiler/astprocessing/AstExtensions.kt | 2 +- .../astprocessing/AstOnetimeTransforms.kt | 21 +++++++++++-------- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt index bb0912afb..fd51c8b4e 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt @@ -692,6 +692,25 @@ internal class ExpressionsAsmGen(private val program: Program, throw AssemblyError("unknown dt") val elementDt = elementIDt.getOr(DataType.UNDEFINED) val arrayVarName = asmgen.asmVariableName(arrayExpr.arrayvar) + + val arrayVarDecl = arrayExpr.arrayvar.targetVarDecl(program)!! + if(arrayVarDecl.datatype==DataType.UWORD) { + // indexing a pointer var instead of a real array or string + if(elementDt !in ByteDatatypes) + throw AssemblyError("non-array var indexing requires bytes dt") + if(arrayExpr.inferType(program) isnot DataType.UBYTE) + throw AssemblyError("non-array var indexing requires bytes index") + asmgen.loadScaledArrayIndexIntoRegister(arrayExpr, elementDt, CpuRegister.Y) + if(asmgen.isZpVar(arrayExpr.arrayvar)) { + asmgen.out(" lda ($arrayVarName),y") + } else { + asmgen.out(" lda $arrayVarName | sta P8ZP_SCRATCH_W1 | lda $arrayVarName+1 | sta P8ZP_SCRATCH_W1+1") + asmgen.out(" lda (P8ZP_SCRATCH_W1),y") + } + asmgen.out(" sta P8ESTACK_LO,x | dex") + return + } + val constIndexNum = arrayExpr.indexer.constIndex() if(constIndexNum!=null) { val indexValue = constIndexNum * program.memsizer.memorySize(elementDt) diff --git a/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt b/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt index f2660e928..0d8c14398 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt @@ -94,7 +94,7 @@ internal fun Program.checkIdentifiers(errors: IErrorReporter, options: Compilati checker2.visit(this) if(errors.noErrors()) { - val transforms = AstOnetimeTransforms(this) + val transforms = AstOnetimeTransforms(this, options) transforms.visit(this) transforms.applyModifications() val lit2decl = LiteralsToAutoVars(this, options.compTarget, errors) diff --git a/compiler/src/prog8/compiler/astprocessing/AstOnetimeTransforms.kt b/compiler/src/prog8/compiler/astprocessing/AstOnetimeTransforms.kt index d3a836961..aa8886073 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstOnetimeTransforms.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstOnetimeTransforms.kt @@ -11,11 +11,13 @@ import prog8.ast.statements.DirectMemoryWrite import prog8.ast.statements.VarDecl import prog8.ast.walk.AstWalker import prog8.ast.walk.IAstModification +import prog8.code.core.CompilationOptions import prog8.code.core.DataType +import prog8.code.target.VMTarget import prog8.compiler.InplaceModifyingBuiltinFunctions -internal class AstOnetimeTransforms(private val program: Program) : AstWalker() { +internal class AstOnetimeTransforms(private val program: Program, private val options: CompilationOptions) : AstWalker() { override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable { if(parent !is VarDecl) { @@ -42,18 +44,19 @@ internal class AstOnetimeTransforms(private val program: Program) : AstWalker() return listOf(IAstModification.ReplaceNode(parent, newtarget, parent.parent)) } else { val fcall = parent as? IFunctionCall - return if(fcall!=null) { - val fname = fcall.target.nameInSource - if(fname.size==1 && fname[0] in InplaceModifyingBuiltinFunctions) { + if(fcall!=null) { + if(fcall.target.nameInSource.size==1 && fcall.target.nameInSource[0] in InplaceModifyingBuiltinFunctions) { // TODO for now, swap() etc don't work on pointer var indexed args, so still replace this val memread = DirectMemoryRead(add, arrayIndexedExpression.position) - listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent)) + return listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent)) } else { - noModifications + println("PTR INDEX 1: $arrayIndexedExpression PARENT=${parent.javaClass}") // TODO + return noModifications } - } else { - val memread = DirectMemoryRead(add, arrayIndexedExpression.position) - listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent)) + } + else { + println("PTR INDEX 2: $arrayIndexedExpression PARENT=${parent.javaClass}") // TODO + return noModifications } } }