preparing to fix the array indexing compiler issue

This commit is contained in:
Irmen de Jong 2022-10-26 23:53:17 +02:00
parent 7b6cd0cfbe
commit e9a4a905ef
5 changed files with 75 additions and 52 deletions

View File

@ -1840,7 +1840,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
}
}
TargetStorageKind.STACK -> TODO("no asm gen for byte stack invert")
else -> throw AssemblyError("no asm gen for in-place invert ubyte for ${target.kind}")
else -> TODO("no asm gen for in-place invert ubyte for ${target.kind}")
}
}
DataType.UWORD -> {
@ -1864,7 +1864,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
}
}
TargetStorageKind.STACK -> TODO("no asm gen for word stack invert")
else -> throw AssemblyError("no asm gen for in-place invert uword for ${target.kind}")
else -> TODO("no asm gen for in-place invert uword for ${target.kind}")
}
}
else -> throw AssemblyError("invert of invalid type")
@ -1898,7 +1898,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
}
TargetStorageKind.MEMORY -> throw AssemblyError("memory is ubyte, can't in-place negate")
TargetStorageKind.STACK -> TODO("no asm gen for byte stack negate")
else -> throw AssemblyError("no asm gen for in-place negate byte")
else -> TODO("no asm gen for in-place negate byte")
}
}
DataType.WORD -> {
@ -1956,7 +1956,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
}
}
TargetStorageKind.STACK -> TODO("no asm gen for word stack negate")
else -> throw AssemblyError("no asm gen for in-place negate word")
else -> TODO("no asm gen for in-place negate word")
}
}
DataType.FLOAT -> {
@ -1970,7 +1970,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
""")
}
TargetStorageKind.STACK -> TODO("no asm gen for float stack negate")
else -> throw AssemblyError("weird target kind for inplace negate float ${target.kind}")
else -> TODO("no asmgen for inplace negate float ${target.kind}")
}
}
else -> throw AssemblyError("negate of invalid type $dt")

View File

@ -16,11 +16,35 @@ import prog8.code.target.VMTarget
internal class AstOnetimeTransforms(private val program: Program, private val options: CompilationOptions) : AstWalker() {
override fun after(assignment: Assignment, parent: Node): Iterable<IAstModification> {
if(options.compTarget.name != VMTarget.NAME) {
// The 6502 code-gen doesn't contain code to deal with arr[0] = -arr[0] and arr[0] = ~arr[0].
// Replace this by assignment, operation, assignment.
// TODO make the codegen better so this work around can be removed
// if (assignment.isAugmentable) {
// val arrayIdx = assignment.target.arrayindexed
// if (arrayIdx != null) {
// val prefixed = assignment.value as? PrefixExpression
// if (prefixed != null) {
// println("array self-assignment, operator = ${prefixed.operator}")
// if (prefixed.operator == "-") {
// TODO("array in-place -")
// } else if (prefixed.operator == "~") {
// TODO("array in-place ~")
// }
// }
// }
// }
}
return noModifications
}
override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
if(parent !is VarDecl) {
// TODO move this / remove this, and make the codegen better instead.
// If the expression is pointervar[idx] where pointervar is uword and not a real array,
// replace it by a @(pointervar+idx) expression.
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)
@ -29,15 +53,16 @@ internal class AstOnetimeTransforms(private val program: Program, private val op
}
private fun replacePointerVarIndexWithMemreadOrMemwrite(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
if(options.compTarget.name==VMTarget.NAME)
return noModifications // vm codegen deals correctly with all cases
// 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.
// TODO make the 6502 codegen better so this work around 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) {
// ONLY for a constant assignment, or direct variable assignment, the codegen contains correct optimized code.
// 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.

View File

@ -10,8 +10,7 @@ import prog8.code.core.IErrorReporter
import prog8.code.core.Position
internal class CodeDesugarer(val program: Program,
private val errors: IErrorReporter) : AstWalker() {
internal class CodeDesugarer(val program: Program, private val errors: IErrorReporter) : AstWalker() {
// Some more code shuffling to simplify the Ast that the codegenerator has to process.
// Several changes have already been done by the StatementReorderer !
@ -138,7 +137,8 @@ _after:
}
override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
// replace pointervar[word] by @(pointervar+word)
// replace pointervar[word] by @(pointervar+word) to avoid the
// "array indexing is limited to byte size 0..255" error for pointervariables.
val indexExpr = arrayIndexedExpression.indexer.indexExpr
val indexerDt = indexExpr.inferType(program)
if(indexerDt.isWords) {

View File

@ -3,6 +3,12 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- improve prefix expression codgen in AssignmentAsmGen.assignExpression():
don't do this for complex assign targets such as array elements: "first assign the value to the target then apply the operator in place on the target."
this triggers foo[x] = -b to be a 2-step assignment with array in-place modification...
- fix the array in place assignment issue, see AstOnetimeTransforms
- ir: asmsub contents remains blank in IR file
...

View File

@ -1,45 +1,37 @@
%import textio
%import math
%import floats
%import textio
%zeropage basicsafe
main {
byte[10] foo
ubyte[10] foou
word[10] foow
uword[10] foowu
float[10] flt
byte d
sub printnumbers() {
txt.print_ub(math.rnd())
txt.spc()
txt.print_ub(math.rnd())
txt.spc()
txt.print_ub(math.rnd())
txt.nl()
txt.print_uw(math.rndw())
txt.spc()
txt.print_uw(math.rndw())
txt.spc()
txt.print_uw(math.rndw())
txt.nl()
floats.print_f(floats.rndf())
txt.spc()
floats.print_f(floats.rndf())
txt.spc()
floats.print_f(floats.rndf())
txt.nl()
}
sub start() {
; foo[0] = -d ; TODO fix codegen in assignExpression that splits this up
uword pointer = $1000
uword index
foou[1] = 42
pointer[$40] = 24
pointer[$40] = foou[1]+10
txt.print_ub(@($1040))
txt.nl()
pointer[index+$100] = foou[1]
pointer[index+$1000] = foou[1]+1
txt.print_ub(@($1100))
txt.nl()
txt.print_ub(@($2000))
txt.nl()
sub start() {
txt.print("initial:\n")
math.rndseed($a55a, $7653)
floats.rndseedf(11,22,33)
printnumbers()
txt.print("\nsame seeds:\n")
math.rndseed($a55a, $7653)
floats.rndseedf(11,22,33)
printnumbers()
txt.print("\ndifferent seeds:\n")
math.rndseed($1234, $5678)
floats.rndseedf(44,55,66)
printnumbers()
txt.nl()
}
; foo[0] = -foo[0]
; foou[0] = ~foou[0]
; foow[0] = -foow[0]
; foowu[0] = ~foowu[0]
; flt[0] = -flt[0] ; TODO also fix crash when selecting vm target: fpReg1 out of bounds
}
}