mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
fix byte in array assignment,
remove no longer needed array assignment ast transformation
This commit is contained in:
parent
c5219dfb3f
commit
46c12a8899
@ -2487,41 +2487,66 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
TargetStorageKind.ARRAY -> {
|
||||
if(assignAsWord)
|
||||
TODO("assign register as word into Array not yet supported")
|
||||
if (target.constArrayIndexValue!=null) {
|
||||
when (register) {
|
||||
CpuRegister.A -> {}
|
||||
CpuRegister.X -> asmgen.out(" txa")
|
||||
CpuRegister.Y -> asmgen.out(" tya")
|
||||
if(target.array!!.splitWords)
|
||||
TODO("assign register into split words ${target.position}")
|
||||
if(target.origAstTarget?.array?.variable?.type==DataType.UWORD) {
|
||||
// assigning an indexed pointer var
|
||||
if (target.constArrayIndexValue!=null) {
|
||||
when (register) {
|
||||
CpuRegister.A -> {}
|
||||
CpuRegister.X -> asmgen.out(" txa")
|
||||
CpuRegister.Y -> asmgen.out(" tya")
|
||||
}
|
||||
if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) {
|
||||
asmgen.out(" ldy #${target.constArrayIndexValue} | sta (${target.asmVarname}),y")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
ldy ${target.asmVarname}
|
||||
sty P8ZP_SCRATCH_W1
|
||||
ldy ${target.asmVarname}+1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
ldy #${target.constArrayIndexValue}
|
||||
sta (P8ZP_SCRATCH_W1),y""")
|
||||
}
|
||||
}
|
||||
if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) {
|
||||
asmgen.out(" ldy #${target.constArrayIndexValue} | sta (${target.asmVarname}),y")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
ldy ${target.asmVarname}
|
||||
sty P8ZP_SCRATCH_W1
|
||||
ldy ${target.asmVarname}+1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
ldy #${target.constArrayIndexValue}
|
||||
sta (P8ZP_SCRATCH_W1),y""")
|
||||
else {
|
||||
when (register) {
|
||||
CpuRegister.A -> {}
|
||||
CpuRegister.X -> asmgen.out(" txa")
|
||||
CpuRegister.Y -> asmgen.out(" tya")
|
||||
}
|
||||
val indexVar = target.array!!.index as PtIdentifier
|
||||
if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) {
|
||||
asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta (${target.asmVarname}),y")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
ldy ${target.asmVarname}
|
||||
sty P8ZP_SCRATCH_W1
|
||||
ldy ${target.asmVarname}+1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
ldy ${asmgen.asmVariableName(indexVar)}
|
||||
sta (P8ZP_SCRATCH_W1),y""")
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
when (register) {
|
||||
CpuRegister.A -> {}
|
||||
CpuRegister.X -> asmgen.out(" txa")
|
||||
CpuRegister.Y -> asmgen.out(" tya")
|
||||
return
|
||||
} else {
|
||||
// assign regular array indexing
|
||||
if (target.constArrayIndexValue!=null) {
|
||||
when (register) {
|
||||
CpuRegister.A -> {}
|
||||
CpuRegister.X -> asmgen.out(" txa")
|
||||
CpuRegister.Y -> asmgen.out(" tya")
|
||||
}
|
||||
asmgen.out(" sta ${target.asmVarname}+${target.constArrayIndexValue}")
|
||||
}
|
||||
val indexVar = target.array!!.index as PtIdentifier
|
||||
if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) {
|
||||
asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta (${target.asmVarname}),y")
|
||||
} else {
|
||||
asmgen.out("""
|
||||
ldy ${target.asmVarname}
|
||||
sty P8ZP_SCRATCH_W1
|
||||
ldy ${target.asmVarname}+1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
ldy ${asmgen.asmVariableName(indexVar)}
|
||||
sta (P8ZP_SCRATCH_W1),y""")
|
||||
else {
|
||||
when (register) {
|
||||
CpuRegister.A -> {}
|
||||
CpuRegister.X -> asmgen.out(" txa")
|
||||
CpuRegister.Y -> asmgen.out(" tya")
|
||||
}
|
||||
val indexVar = target.array!!.index as PtIdentifier
|
||||
asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta ${target.asmVarname},y")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -108,9 +108,6 @@ internal fun Program.checkIdentifiers(errors: IErrorReporter, options: Compilati
|
||||
checker2.visit(this)
|
||||
|
||||
if(errors.noErrors()) {
|
||||
val transforms = AstOnetimeTransforms(this, options)
|
||||
transforms.visit(this)
|
||||
transforms.applyModifications()
|
||||
val lit2decl = LiteralsToAutoVars(this, options.compTarget, errors)
|
||||
lit2decl.visit(this)
|
||||
if(errors.noErrors())
|
||||
|
@ -1,62 +0,0 @@
|
||||
package prog8.compiler.astprocessing
|
||||
|
||||
import prog8.ast.Node
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.expressions.*
|
||||
import prog8.ast.statements.AssignTarget
|
||||
import prog8.ast.statements.Assignment
|
||||
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
|
||||
|
||||
|
||||
internal class AstOnetimeTransforms(private val program: Program, private val options: CompilationOptions) : AstWalker() {
|
||||
|
||||
override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
|
||||
if(parent !is VarDecl) {
|
||||
if(options.compTarget.name == VMTarget.NAME)
|
||||
return noModifications // vm codegen deals correctly with all cases
|
||||
// Don't replace the initializer value in a vardecl - this will be moved to a separate
|
||||
// assignment statement soon in after(VarDecl)
|
||||
return replacePointerVarIndexWithMemreadOrMemwrite(arrayIndexedExpression, parent)
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
|
||||
private fun replacePointerVarIndexWithMemreadOrMemwrite(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
|
||||
// note: The CodeDesugarer already does something similar, but that is meant ONLY to take
|
||||
// into account the case where the index value is a word type.
|
||||
// The replacement here is to fix missing cases in the 6502 codegen. (VM codegen doesn't use this workaround)
|
||||
// TODO make the 6502 codegen better so this workaround can be removed
|
||||
val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program)
|
||||
if(arrayVar!=null && arrayVar.datatype == DataType.UWORD) {
|
||||
if(parent is AssignTarget) {
|
||||
val assignment = parent.parent as? Assignment
|
||||
if(assignment?.value is NumericLiteral || assignment?.value is IdentifierReference) {
|
||||
// the codegen contains correct optimized code ONLY for a constant assignment, or direct variable assignment.
|
||||
return noModifications
|
||||
}
|
||||
// Other cases aren't covered correctly by the 6502 codegen, and there are a LOT of cases.
|
||||
// So rewrite assignment target pointervar[index] into @(pointervar+index)
|
||||
// (the 6502 codegen covers all cases correctly for a direct memory assignment).
|
||||
val indexer = arrayIndexedExpression.indexer
|
||||
val add: Expression =
|
||||
if(indexer.indexExpr.constValue(program)?.number==0.0)
|
||||
arrayIndexedExpression.arrayvar.copy()
|
||||
else
|
||||
BinaryExpression(arrayIndexedExpression.arrayvar.copy(), "+", indexer.indexExpr, arrayIndexedExpression.position)
|
||||
val memwrite = DirectMemoryWrite(add, arrayIndexedExpression.position)
|
||||
val newtarget = AssignTarget(null, null, memwrite, arrayIndexedExpression.position)
|
||||
return listOf(IAstModification.ReplaceNode(parent, newtarget, parent.parent))
|
||||
}
|
||||
}
|
||||
|
||||
return noModifications
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- bugfixes: assem crashing, imageviewer not loading past boat image, rockrunner music borked.
|
||||
- stackless: describe the changes in the manual.
|
||||
|
||||
- IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction
|
||||
|
Loading…
x
Reference in New Issue
Block a user