fix 6502 expression codegen for pointer indexing

This commit is contained in:
Irmen de Jong 2022-06-04 18:46:16 +02:00
parent 3c8c44155d
commit 8618ba1b60
3 changed files with 32 additions and 10 deletions

View File

@ -692,6 +692,25 @@ internal class ExpressionsAsmGen(private val program: Program,
throw AssemblyError("unknown dt") throw AssemblyError("unknown dt")
val elementDt = elementIDt.getOr(DataType.UNDEFINED) val elementDt = elementIDt.getOr(DataType.UNDEFINED)
val arrayVarName = asmgen.asmVariableName(arrayExpr.arrayvar) 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() val constIndexNum = arrayExpr.indexer.constIndex()
if(constIndexNum!=null) { if(constIndexNum!=null) {
val indexValue = constIndexNum * program.memsizer.memorySize(elementDt) val indexValue = constIndexNum * program.memsizer.memorySize(elementDt)

View File

@ -94,7 +94,7 @@ internal fun Program.checkIdentifiers(errors: IErrorReporter, options: Compilati
checker2.visit(this) checker2.visit(this)
if(errors.noErrors()) { if(errors.noErrors()) {
val transforms = AstOnetimeTransforms(this) val transforms = AstOnetimeTransforms(this, options)
transforms.visit(this) transforms.visit(this)
transforms.applyModifications() transforms.applyModifications()
val lit2decl = LiteralsToAutoVars(this, options.compTarget, errors) val lit2decl = LiteralsToAutoVars(this, options.compTarget, errors)

View File

@ -11,11 +11,13 @@ import prog8.ast.statements.DirectMemoryWrite
import prog8.ast.statements.VarDecl import prog8.ast.statements.VarDecl
import prog8.ast.walk.AstWalker import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification import prog8.ast.walk.IAstModification
import prog8.code.core.CompilationOptions
import prog8.code.core.DataType import prog8.code.core.DataType
import prog8.code.target.VMTarget
import prog8.compiler.InplaceModifyingBuiltinFunctions 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<IAstModification> { override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
if(parent !is VarDecl) { if(parent !is VarDecl) {
@ -42,18 +44,19 @@ internal class AstOnetimeTransforms(private val program: Program) : AstWalker()
return listOf(IAstModification.ReplaceNode(parent, newtarget, parent.parent)) return listOf(IAstModification.ReplaceNode(parent, newtarget, parent.parent))
} else { } else {
val fcall = parent as? IFunctionCall val fcall = parent as? IFunctionCall
return if(fcall!=null) { if(fcall!=null) {
val fname = fcall.target.nameInSource if(fcall.target.nameInSource.size==1 && fcall.target.nameInSource[0] in InplaceModifyingBuiltinFunctions) {
if(fname.size==1 && fname[0] in InplaceModifyingBuiltinFunctions) {
// TODO for now, swap() etc don't work on pointer var indexed args, so still replace this // TODO for now, swap() etc don't work on pointer var indexed args, so still replace this
val memread = DirectMemoryRead(add, arrayIndexedExpression.position) val memread = DirectMemoryRead(add, arrayIndexedExpression.position)
listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent)) return listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent))
} else { } else {
noModifications println("PTR INDEX 1: $arrayIndexedExpression PARENT=${parent.javaClass}") // TODO
return noModifications
} }
} else { }
val memread = DirectMemoryRead(add, arrayIndexedExpression.position) else {
listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent)) println("PTR INDEX 2: $arrayIndexedExpression PARENT=${parent.javaClass}") // TODO
return noModifications
} }
} }
} }