mirror of
https://github.com/irmen/prog8.git
synced 2025-01-29 09:31:23 +00:00
fix postincrdecr on array value
This commit is contained in:
parent
3991d23a69
commit
93b2ff2e52
@ -8,7 +8,6 @@ import prog8.ast.base.*
|
||||
import prog8.ast.expressions.*
|
||||
import prog8.ast.statements.*
|
||||
import prog8.compiler.*
|
||||
import prog8.compiler.target.CompilationTarget
|
||||
import prog8.compiler.target.IAssemblyGenerator
|
||||
import prog8.compiler.target.IAssemblyProgram
|
||||
import prog8.compiler.target.c64.AssemblyProgram
|
||||
@ -583,20 +582,6 @@ internal class AsmGen(private val program: Program,
|
||||
}
|
||||
}
|
||||
|
||||
internal fun loadUnscaledArrayIndexIntoA(expr: ArrayIndexedExpression) {
|
||||
when (val index = expr.arrayspec.index) {
|
||||
is NumericLiteralValue -> throw AssemblyError("constant array index should be optimized earlier")
|
||||
is IdentifierReference -> {
|
||||
val indexName = asmIdentifierName(index)
|
||||
out(" lda $indexName")
|
||||
}
|
||||
else -> {
|
||||
expressionsAsmGen.translateExpression(index)
|
||||
out(" inx | lda $ESTACK_LO_HEX,x")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun loadScaledArrayIndexIntoRegister(expr: ArrayIndexedExpression,
|
||||
elementDt: DataType,
|
||||
register: CpuRegister,
|
||||
@ -648,7 +633,17 @@ internal class AsmGen(private val program: Program,
|
||||
}
|
||||
}
|
||||
else {
|
||||
TODO("+1")
|
||||
expressionsAsmGen.translateExpression(index)
|
||||
out("""
|
||||
inc $ESTACK_LO_HEX,x
|
||||
bne +
|
||||
inc $ESTACK_HI_HEX,x
|
||||
+""")
|
||||
when(register) {
|
||||
CpuRegister.A -> out(" inx | lda $ESTACK_LO_HEX,x")
|
||||
CpuRegister.X -> throw AssemblyError("can't use X here")
|
||||
CpuRegister.Y -> out(" inx | ldy $ESTACK_LO_HEX,x")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (index is IdentifierReference) {
|
||||
|
@ -73,71 +73,65 @@ internal class PostIncrDecrAsmGen(private val program: Program, private val asmg
|
||||
}
|
||||
targetArrayIdx!=null -> {
|
||||
val index = targetArrayIdx.arrayspec.index
|
||||
val what = asmgen.asmIdentifierName(targetArrayIdx.identifier)
|
||||
val asmArrayvarname = asmgen.asmIdentifierName(targetArrayIdx.identifier)
|
||||
val elementDt = targetArrayIdx.inferType(program).typeOrElse(DataType.STRUCT)
|
||||
when(index) {
|
||||
is NumericLiteralValue -> {
|
||||
val indexValue = index.number.toInt() * elementDt.memorySize()
|
||||
when(elementDt) {
|
||||
in ByteDatatypes -> asmgen.out(if (incr) " inc $what+$indexValue" else " dec $what+$indexValue")
|
||||
in ByteDatatypes -> asmgen.out(if (incr) " inc $asmArrayvarname+$indexValue" else " dec $asmArrayvarname+$indexValue")
|
||||
in WordDatatypes -> {
|
||||
if(incr)
|
||||
asmgen.out(" inc $what+$indexValue | bne + | inc $what+$indexValue+1 |+")
|
||||
asmgen.out(" inc $asmArrayvarname+$indexValue | bne + | inc $asmArrayvarname+$indexValue+1 |+")
|
||||
else
|
||||
asmgen.out("""
|
||||
lda $what+$indexValue
|
||||
lda $asmArrayvarname+$indexValue
|
||||
bne +
|
||||
dec $what+$indexValue+1
|
||||
+ dec $what+$indexValue
|
||||
dec $asmArrayvarname+$indexValue+1
|
||||
+ dec $asmArrayvarname+$indexValue
|
||||
""")
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
asmgen.out(" lda #<$what+$indexValue | ldy #>$what+$indexValue")
|
||||
asmgen.out(" lda #<$asmArrayvarname+$indexValue | ldy #>$asmArrayvarname+$indexValue")
|
||||
asmgen.out(if(incr) " jsr c64flt.inc_var_f" else " jsr c64flt.dec_var_f")
|
||||
}
|
||||
else -> throw AssemblyError("need numeric type")
|
||||
}
|
||||
}
|
||||
is IdentifierReference -> {
|
||||
// TODO rewrite using scaled?
|
||||
asmgen.loadUnscaledArrayIndexIntoA(targetArrayIdx)
|
||||
incrDecrArrayvalueWithIndexA(incr, elementDt, what) // TODO is this ok for word/float array?
|
||||
}
|
||||
else -> {
|
||||
// TODO rewrite using scaled?
|
||||
asmgen.loadUnscaledArrayIndexIntoA(targetArrayIdx)
|
||||
incrDecrArrayvalueWithIndexA(incr, elementDt, what)// TODO is this ok for word/float array?
|
||||
asmgen.loadScaledArrayIndexIntoRegister(targetArrayIdx, elementDt, CpuRegister.A)
|
||||
asmgen.out(" stx ${C64Zeropage.SCRATCH_REG_X} | tax")
|
||||
when(elementDt) {
|
||||
in ByteDatatypes -> {
|
||||
asmgen.out(if(incr) " inc $asmArrayvarname,x" else " dec $asmArrayvarname,x")
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
if(incr)
|
||||
asmgen.out(" inc $asmArrayvarname,x | bne + | inc $asmArrayvarname+1,x |+")
|
||||
else
|
||||
asmgen.out("""
|
||||
lda $asmArrayvarname,x
|
||||
bne +
|
||||
dec $asmArrayvarname+1,x
|
||||
+ dec $asmArrayvarname
|
||||
""")
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
asmgen.out("""
|
||||
ldy #>$asmArrayvarname
|
||||
clc
|
||||
adc #<$asmArrayvarname
|
||||
bcc +
|
||||
iny
|
||||
+ jsr c64flt.inc_var_f""")
|
||||
}
|
||||
else -> throw AssemblyError("weird array elt dt")
|
||||
}
|
||||
asmgen.out(" ldx ${C64Zeropage.SCRATCH_REG_X}")
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> throw AssemblyError("weird target type ${stmt.target}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun incrDecrArrayvalueWithIndexA(incr: Boolean, elementDt: DataType, arrayVarName: String) {
|
||||
asmgen.out(" stx ${C64Zeropage.SCRATCH_REG_X} | tax")
|
||||
when(elementDt) {
|
||||
in ByteDatatypes -> {
|
||||
asmgen.out(if(incr) " inc $arrayVarName,x" else " dec $arrayVarName,x")
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
if(incr)
|
||||
asmgen.out(" inc $arrayVarName,x | bne + | inc $arrayVarName+1,x |+")
|
||||
else
|
||||
asmgen.out("""
|
||||
lda $arrayVarName,x
|
||||
bne +
|
||||
dec $arrayVarName+1,x
|
||||
+ dec $arrayVarName
|
||||
""")
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
asmgen.out(" lda #<$arrayVarName | ldy #>$arrayVarName")
|
||||
asmgen.out(if(incr) " jsr c64flt.inc_indexed_var_f" else " jsr c64flt.dec_indexed_var_f")
|
||||
}
|
||||
else -> throw AssemblyError("weird array elt dt")
|
||||
}
|
||||
asmgen.out(" ldx ${C64Zeropage.SCRATCH_REG_X}")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
}
|
||||
} else {
|
||||
// TODO rewrite to use Scaled
|
||||
asmgen.loadUnscaledArrayIndexIntoA(value)
|
||||
loadUnscaledArrayIndexIntoA(value)
|
||||
readAndPushArrayvalueWithUnscaledIndexA(elementDt, arrayVarName)
|
||||
}
|
||||
assignStackValue(assign.target)
|
||||
@ -201,9 +201,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
throw AssemblyError("no asm gen for assign address $sourceName to memory word $target")
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
val targetArrayIdx = target.array!!
|
||||
val index = targetArrayIdx.arrayspec.index
|
||||
throw AssemblyError("no asm gen for assign address $sourceName to array ${target.asmVarname} [ $index ]")
|
||||
throw AssemblyError("no asm gen for assign address $sourceName to array ${target.asmVarname}")
|
||||
}
|
||||
TargetStorageKind.REGISTER -> TODO()
|
||||
TargetStorageKind.STACK -> TODO()
|
||||
@ -372,7 +370,6 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
val index = target.array!!.arrayspec.index
|
||||
val targetName = asmgen.asmIdentifierName(target.array.identifier)
|
||||
asmgen.translateExpression(index)
|
||||
asmgen.out("""
|
||||
inx
|
||||
@ -380,9 +377,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
asl a
|
||||
tay
|
||||
lda #<${word.toHex()}
|
||||
sta $targetName,y
|
||||
sta ${target.asmVarname},y
|
||||
lda #>${word.toHex()}
|
||||
sta $targetName+1,y
|
||||
sta ${target.asmVarname}+1,y
|
||||
""")
|
||||
}
|
||||
TargetStorageKind.REGISTER -> TODO()
|
||||
@ -400,13 +397,12 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
val index = target.array!!.arrayspec.index
|
||||
val targetName = asmgen.asmIdentifierName(target.array.identifier)
|
||||
asmgen.translateExpression(index)
|
||||
asmgen.out("""
|
||||
inx
|
||||
ldy $ESTACK_LO_HEX,x
|
||||
lda #${byte.toHex()}
|
||||
sta $targetName,y
|
||||
sta ${target.asmVarname},y
|
||||
""")
|
||||
}
|
||||
else -> throw AssemblyError("no asm gen for assign byte $byte to $target")
|
||||
@ -472,7 +468,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
val index = target.array!!.arrayspec.index
|
||||
val arrayVarName = asmgen.asmIdentifierName(target.array.identifier)
|
||||
val arrayVarName = target.asmVarname
|
||||
if (index is NumericLiteralValue) {
|
||||
val indexValue = index.number.toInt() * DataType.FLOAT.memorySize()
|
||||
asmgen.out("""
|
||||
@ -520,9 +516,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
storeByteViaRegisterAInMemoryAddress(address.toHex(), target.memory!!)
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
val index = target.array!!.arrayspec.index
|
||||
val targetName = asmgen.asmIdentifierName(target.array.identifier)
|
||||
throw AssemblyError("no asm gen for assign memory byte at $address to array $targetName [ $index ]")
|
||||
throw AssemblyError("no asm gen for assign memory byte at $address to array ${target.asmVarname}")
|
||||
}
|
||||
TargetStorageKind.REGISTER -> TODO()
|
||||
TargetStorageKind.STACK -> TODO()
|
||||
@ -544,9 +538,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
storeByteViaRegisterAInMemoryAddress(sourceName, target.memory!!)
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
val index = target.array!!.arrayspec.index
|
||||
val targetName = asmgen.asmIdentifierName(target.array.identifier)
|
||||
throw AssemblyError("no asm gen for assign memory byte $sourceName to array $targetName [ $index ]")
|
||||
throw AssemblyError("no asm gen for assign memory byte $sourceName to array ${target.asmVarname} ")
|
||||
}
|
||||
else -> throw AssemblyError("no asm gen for assign memory byte $target")
|
||||
}
|
||||
@ -646,6 +638,21 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadUnscaledArrayIndexIntoA(expr: ArrayIndexedExpression) {
|
||||
// TODO this is only used once, remove this when that is rewritten using scaled
|
||||
when (val index = expr.arrayspec.index) {
|
||||
is NumericLiteralValue -> throw AssemblyError("constant array index should be optimized earlier")
|
||||
is IdentifierReference -> {
|
||||
val indexName = asmgen.asmIdentifierName(index)
|
||||
asmgen.out(" lda $indexName")
|
||||
}
|
||||
else -> {
|
||||
asmgen.translateExpression(index)
|
||||
asmgen.out(" inx | lda $ESTACK_LO_HEX,x")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun readAndPushArrayvalueWithUnscaledIndexA(elementDt: DataType, asmVarname: String) {
|
||||
// TODO this is only used once, remove this when that is rewritten using scaled
|
||||
when (elementDt) {
|
||||
|
@ -7,27 +7,29 @@ main {
|
||||
|
||||
sub start() {
|
||||
|
||||
; uword[] array=[$1111 ,$2222,$3333]
|
||||
; uword uw = $ee33
|
||||
; ubyte i = 2
|
||||
; array[1] = array[1] as ubyte
|
||||
; array[i] = array[i] as ubyte
|
||||
; c64scr.print_uwhex(array[0], 1)
|
||||
; c64.CHROUT(',')
|
||||
; c64scr.print_uwhex(array[1], 1)
|
||||
; c64.CHROUT(',')
|
||||
; c64scr.print_uwhex(array[2], 1)
|
||||
; c64.CHROUT('\n')
|
||||
|
||||
ubyte[] arr1=[11,22,33]
|
||||
uword[] array=[1111 ,2222,3333]
|
||||
float[] farr = [1.111, 2.222, 3.333]
|
||||
|
||||
ubyte i = 1
|
||||
|
||||
c64scr.print_ub(arr1[1])
|
||||
c64.CHROUT('\n')
|
||||
arr1 [i] ++
|
||||
c64scr.print_ub(arr1[1])
|
||||
c64.CHROUT('\n')
|
||||
|
||||
c64scr.print_uw(array[1])
|
||||
c64.CHROUT('\n')
|
||||
array[i] ++
|
||||
c64scr.print_uw(array[1])
|
||||
c64.CHROUT('\n')
|
||||
|
||||
c64flt.print_f(farr[1])
|
||||
c64.CHROUT('\n')
|
||||
float ff
|
||||
float ff2 = 0
|
||||
ff = ff2 + farr[1] + 99
|
||||
c64flt.print_f(ff)
|
||||
farr[i] ++
|
||||
c64flt.print_f(farr[1])
|
||||
c64.CHROUT('\n')
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user