mirror of
https://github.com/irmen/prog8.git
synced 2024-12-27 05:29:38 +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")
|
||||
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")
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
||||
...
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user