mirror of
https://github.com/irmen/prog8.git
synced 2024-10-25 00:24:16 +00:00
preparing to fix the array indexing compiler issue
This commit is contained in:
parent
7b6cd0cfbe
commit
e9a4a905ef
@ -1840,7 +1840,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TargetStorageKind.STACK -> TODO("no asm gen for byte stack invert")
|
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 -> {
|
DataType.UWORD -> {
|
||||||
@ -1864,7 +1864,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TargetStorageKind.STACK -> TODO("no asm gen for word stack invert")
|
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")
|
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.MEMORY -> throw AssemblyError("memory is ubyte, can't in-place negate")
|
||||||
TargetStorageKind.STACK -> TODO("no asm gen for byte stack 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 -> {
|
DataType.WORD -> {
|
||||||
@ -1956,7 +1956,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TargetStorageKind.STACK -> TODO("no asm gen for word stack negate")
|
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 -> {
|
DataType.FLOAT -> {
|
||||||
@ -1970,7 +1970,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
TargetStorageKind.STACK -> TODO("no asm gen for float stack negate")
|
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")
|
else -> throw AssemblyError("negate of invalid type $dt")
|
||||||
|
@ -16,11 +16,35 @@ import prog8.code.target.VMTarget
|
|||||||
|
|
||||||
internal class AstOnetimeTransforms(private val program: Program, private val options: CompilationOptions) : AstWalker() {
|
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> {
|
override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
|
||||||
if(parent !is VarDecl) {
|
if(parent !is VarDecl) {
|
||||||
// TODO move this / remove this, and make the codegen better instead.
|
if(options.compTarget.name == VMTarget.NAME)
|
||||||
// If the expression is pointervar[idx] where pointervar is uword and not a real array,
|
return noModifications // vm codegen deals correctly with all cases
|
||||||
// replace it by a @(pointervar+idx) expression.
|
|
||||||
// Don't replace the initializer value in a vardecl - this will be moved to a separate
|
// Don't replace the initializer value in a vardecl - this will be moved to a separate
|
||||||
// assignment statement soon in after(VarDecl)
|
// assignment statement soon in after(VarDecl)
|
||||||
return replacePointerVarIndexWithMemreadOrMemwrite(arrayIndexedExpression, parent)
|
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> {
|
private fun replacePointerVarIndexWithMemreadOrMemwrite(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
|
||||||
if(options.compTarget.name==VMTarget.NAME)
|
// note: The CodeDesugarer already does something similar, but that is meant ONLY to take
|
||||||
return noModifications // vm codegen deals correctly with all cases
|
// 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)
|
val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program)
|
||||||
if(arrayVar!=null && arrayVar.datatype == DataType.UWORD) {
|
if(arrayVar!=null && arrayVar.datatype == DataType.UWORD) {
|
||||||
if(parent is AssignTarget) {
|
if(parent is AssignTarget) {
|
||||||
val assignment = parent.parent as? Assignment
|
val assignment = parent.parent as? Assignment
|
||||||
if(assignment?.value is NumericLiteral || assignment?.value is IdentifierReference) {
|
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
|
return noModifications
|
||||||
}
|
}
|
||||||
// Other cases aren't covered correctly by the 6502 codegen, and there are a LOT of cases.
|
// Other cases aren't covered correctly by the 6502 codegen, and there are a LOT of cases.
|
||||||
|
@ -10,8 +10,7 @@ import prog8.code.core.IErrorReporter
|
|||||||
import prog8.code.core.Position
|
import prog8.code.core.Position
|
||||||
|
|
||||||
|
|
||||||
internal class CodeDesugarer(val program: Program,
|
internal class CodeDesugarer(val program: Program, private val errors: IErrorReporter) : AstWalker() {
|
||||||
private val errors: IErrorReporter) : AstWalker() {
|
|
||||||
|
|
||||||
// Some more code shuffling to simplify the Ast that the codegenerator has to process.
|
// Some more code shuffling to simplify the Ast that the codegenerator has to process.
|
||||||
// Several changes have already been done by the StatementReorderer !
|
// Several changes have already been done by the StatementReorderer !
|
||||||
@ -138,7 +137,8 @@ _after:
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
|
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 indexExpr = arrayIndexedExpression.indexer.indexExpr
|
||||||
val indexerDt = indexExpr.inferType(program)
|
val indexerDt = indexExpr.inferType(program)
|
||||||
if(indexerDt.isWords) {
|
if(indexerDt.isWords) {
|
||||||
|
@ -3,6 +3,12 @@ TODO
|
|||||||
|
|
||||||
For next release
|
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
|
- ir: asmsub contents remains blank in IR file
|
||||||
|
|
||||||
...
|
...
|
||||||
|
@ -1,45 +1,37 @@
|
|||||||
%import textio
|
|
||||||
%import math
|
|
||||||
%import floats
|
%import floats
|
||||||
|
%import textio
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
byte[10] foo
|
||||||
sub printnumbers() {
|
ubyte[10] foou
|
||||||
txt.print_ub(math.rnd())
|
word[10] foow
|
||||||
txt.spc()
|
uword[10] foowu
|
||||||
txt.print_ub(math.rnd())
|
float[10] flt
|
||||||
txt.spc()
|
byte d
|
||||||
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() {
|
sub start() {
|
||||||
txt.print("initial:\n")
|
; foo[0] = -d ; TODO fix codegen in assignExpression that splits this up
|
||||||
math.rndseed($a55a, $7653)
|
|
||||||
floats.rndseedf(11,22,33)
|
uword pointer = $1000
|
||||||
printnumbers()
|
uword index
|
||||||
txt.print("\nsame seeds:\n")
|
foou[1] = 42
|
||||||
math.rndseed($a55a, $7653)
|
pointer[$40] = 24
|
||||||
floats.rndseedf(11,22,33)
|
pointer[$40] = foou[1]+10
|
||||||
printnumbers()
|
txt.print_ub(@($1040))
|
||||||
txt.print("\ndifferent seeds:\n")
|
|
||||||
math.rndseed($1234, $5678)
|
|
||||||
floats.rndseedf(44,55,66)
|
|
||||||
printnumbers()
|
|
||||||
txt.nl()
|
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()
|
||||||
|
|
||||||
|
|
||||||
|
; 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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user