fixed float array indexing with an expression

This commit is contained in:
Irmen de Jong 2023-11-27 20:54:49 +01:00
parent 2fa1d8f2e8
commit 6d8fbe0877
3 changed files with 69 additions and 100 deletions

View File

@ -2612,19 +2612,13 @@ internal class AssignmentAsmGen(private val program: PtProgram,
""")
}
TargetStorageKind.ARRAY -> {
asmgen.assignExpressionToRegister(target.array!!.index, RegisterOrPair.A, false)
asmgen.out("""
lda #<${target.asmVarname}
ldy #<${target.asmVarname}
sty P8ZP_SCRATCH_W1
ldy #>${target.asmVarname}
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1""")
val constIndex = target.array!!.index.asConstInteger()
if(constIndex!=null) {
asmgen.out(" lda #$constIndex")
} else {
val asmvarname = asmgen.asmVariableName(target.array.index as PtIdentifier) // TODO index could also be a binexpr
asmgen.out(" lda $asmvarname")
}
asmgen.out(" jsr floats.set_array_float_from_fac1")
sty P8ZP_SCRATCH_W1+1
jsr floats.set_array_float_from_fac1""")
}
TargetStorageKind.MEMORY -> throw AssemblyError("can't assign float to mem byte")
TargetStorageKind.REGISTER -> {
@ -2647,21 +2641,19 @@ internal class AssignmentAsmGen(private val program: PtProgram,
jsr floats.copy_float""")
}
TargetStorageKind.ARRAY -> {
asmgen.saveRegisterStack(CpuRegister.A, false)
asmgen.saveRegisterStack(CpuRegister.Y, false)
asmgen.assignExpressionToRegister(target.array!!.index, RegisterOrPair.A, false)
asmgen.restoreRegisterStack(CpuRegister.Y, false)
asmgen.restoreRegisterStack(CpuRegister.A, false)
asmgen.out("""
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda #<${target.asmVarname}
ldy #>${target.asmVarname}
sta P8ZP_SCRATCH_W2
sty P8ZP_SCRATCH_W2+1""")
val constIndex = target.array!!.index.asConstInteger()
if(constIndex!=null) {
asmgen.out(" lda #$constIndex")
} else {
val asmvarname = asmgen.asmVariableName(target.array.index as PtIdentifier) // TODO index could also be a binexpr
asmgen.out(" lda $asmvarname")
}
asmgen.out(" jsr floats.set_array_float")
sty P8ZP_SCRATCH_W2+1
jsr floats.set_array_float""")
}
TargetStorageKind.MEMORY -> throw AssemblyError("can't assign float to mem byte")
TargetStorageKind.REGISTER -> {
@ -2687,23 +2679,17 @@ internal class AssignmentAsmGen(private val program: PtProgram,
jsr floats.copy_float""")
}
TargetStorageKind.ARRAY -> {
asmgen.assignExpressionToRegister(target.array!!.index, RegisterOrPair.A, false)
asmgen.out("""
lda #<$sourceName
ldy #<$sourceName
sty P8ZP_SCRATCH_W1
ldy #>$sourceName
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda #<${target.asmVarname}
ldy #<${target.asmVarname}
sty P8ZP_SCRATCH_W2
ldy #>${target.asmVarname}
sta P8ZP_SCRATCH_W2
sty P8ZP_SCRATCH_W2+1""")
val constIndex = target.array!!.index.asConstInteger()
if(constIndex!=null) {
asmgen.out(" lda #$constIndex")
} else {
val asmvarname = asmgen.asmVariableName(target.array.index as PtIdentifier) // TODO index could also be a binexpr
asmgen.out(" lda $asmvarname")
}
asmgen.out(" jsr floats.set_array_float")
sty P8ZP_SCRATCH_W2+1
jsr floats.set_array_float""")
}
TargetStorageKind.MEMORY -> throw AssemblyError("can't assign float to mem byte")
TargetStorageKind.REGISTER -> {
@ -3641,37 +3627,13 @@ internal class AssignmentAsmGen(private val program: PtProgram,
""")
}
TargetStorageKind.ARRAY -> {
val constIndex = target.array!!.index.asConstInteger()
if (constIndex!=null) {
val indexValue = constIndex * program.memsizer.memorySize(DataType.FLOAT)
if(asmgen.isTargetCpu(CpuType.CPU65c02))
asmgen.out("""
stz ${target.asmVarname}+$indexValue
stz ${target.asmVarname}+$indexValue+1
stz ${target.asmVarname}+$indexValue+2
stz ${target.asmVarname}+$indexValue+3
stz ${target.asmVarname}+$indexValue+4
""")
else
asmgen.out("""
lda #0
sta ${target.asmVarname}+$indexValue
sta ${target.asmVarname}+$indexValue+1
sta ${target.asmVarname}+$indexValue+2
sta ${target.asmVarname}+$indexValue+3
sta ${target.asmVarname}+$indexValue+4
""")
} else {
val asmvarname = asmgen.asmVariableName(target.array.index as PtIdentifier) // TODO index could also be a binexpr
asmgen.out("""
lda #<${target.asmVarname}
sta P8ZP_SCRATCH_W1
lda #>${target.asmVarname}
sta P8ZP_SCRATCH_W1+1
lda $asmvarname
jsr floats.set_0_array_float
""")
}
asmgen.assignExpressionToRegister(target.array!!.index, RegisterOrPair.A, false)
asmgen.out("""
ldy #<${target.asmVarname}
sty P8ZP_SCRATCH_W1
ldy #>${target.asmVarname}
sty P8ZP_SCRATCH_W1+1
jsr floats.set_0_array_float""")
}
TargetStorageKind.MEMORY -> throw AssemblyError("can't assign float to memory byte")
TargetStorageKind.REGISTER -> {
@ -3698,33 +3660,18 @@ internal class AssignmentAsmGen(private val program: PtProgram,
jsr floats.copy_float""")
}
TargetStorageKind.ARRAY -> {
val arrayVarName = target.asmVarname
val constIndex = target.array!!.index.asConstInteger()
if (constIndex!=null) {
val indexValue = constIndex * program.memsizer.memorySize(DataType.FLOAT)
asmgen.out("""
lda #<$constFloat
ldy #>$constFloat
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda #<($arrayVarName+$indexValue)
ldy #>($arrayVarName+$indexValue)
jsr floats.copy_float""")
} else {
val asmvarname = asmgen.asmVariableName(target.array.index as PtIdentifier) // TODO index could also be a binexpr
asmgen.out("""
lda #<${constFloat}
sta P8ZP_SCRATCH_W1
lda #>${constFloat}
sta P8ZP_SCRATCH_W1+1
lda #<${arrayVarName}
sta P8ZP_SCRATCH_W2
lda #>${arrayVarName}
sta P8ZP_SCRATCH_W2+1
lda $asmvarname
jsr floats.set_array_float
""")
}
asmgen.assignExpressionToRegister(target.array!!.index, RegisterOrPair.A, false)
asmgen.out("""
ldy #<${constFloat}
sty P8ZP_SCRATCH_W1
ldy #>${constFloat}
sty P8ZP_SCRATCH_W1+1
ldy #<${target.asmVarname}
sty P8ZP_SCRATCH_W2
ldy #>${target.asmVarname}
sty P8ZP_SCRATCH_W2+1
jsr floats.set_array_float
""")
}
TargetStorageKind.MEMORY -> throw AssemblyError("can't assign float to memory byte")
TargetStorageKind.REGISTER -> {

View File

@ -20,7 +20,6 @@ Compiler:
- Currently "320*240/8/8" gives integer overflow, so: allow constant integer subexpressions to contain out of range integers (>65535 etc) as long as the final constant value is within byte/word range.
- Multidimensional arrays and chained indexing, purely as syntactic sugar over regular arrays.
- fix the other cases of "TODO index could also be a binexpr" (in AssignmentAsmGen), but these are for float arrays so rarely used.
- make a form of "manual generics" possible like: varsub routine(T arg)->T where T is expanded to a specific type
(this is already done hardcoded for several of the builtin functions)

View File

@ -1,17 +1,40 @@
%import textio
%import string
%import floats
%zeropage basicsafe
main {
sub start() {
str[] names = ["a", "aa", "harry", "the Quick Brown Fox jumps Over the LAZY dog!"]
float[51] p1
float[51] p2
float[51] p3
float[51] p4
uword name
for name in names {
txt.print_ub(string.hash(name))
txt.spc()
txt.print(name)
txt.nl()
ubyte idx = 2
float fl = 3.455
p1[idx+1] = fl
floats.print_f(p1[idx+1])
p1[idx+1] = 0.0
floats.print_f(p1[idx+1])
store_prime(1, 2.987654321)
store_prime(52, 3.14159)
floats.print_f(p1[1])
txt.nl()
floats.print_f(p2[2])
txt.nl()
sub store_prime(ubyte idx, float pr) {
if idx >= 150 {
p4[idx - 150] = pr
} else if idx >= 100 {
p3[idx - 100] = pr
} else if idx >= 50 {
p2[idx - 50] = pr
} else {
p1[idx] = pr
}
}
}
}