mirror of
https://github.com/irmen/prog8.git
synced 2024-11-22 15:33:02 +00:00
fix: array[x] = -value no longer crashes the codegen
This commit is contained in:
parent
e9a4a905ef
commit
b0c7bad391
@ -287,18 +287,36 @@ internal class AssignmentAsmGen(private val program: Program,
|
||||
}
|
||||
}
|
||||
is PrefixExpression -> {
|
||||
// first assign the value to the target then apply the operator in place on the target.
|
||||
translateNormalAssignment(AsmAssignment(
|
||||
AsmAssignSource.fromAstSource(value.expression, program, asmgen),
|
||||
assign.target,
|
||||
false, program.memsizer, assign.position
|
||||
))
|
||||
val target = virtualRegsToVariables(assign.target)
|
||||
when(value.operator) {
|
||||
"+" -> {}
|
||||
"-" -> augmentableAsmGen.inplaceNegate(target, target.datatype)
|
||||
"~" -> augmentableAsmGen.inplaceInvert(target, target.datatype)
|
||||
else -> throw AssemblyError("invalid prefix operator")
|
||||
if(assign.target.array==null) {
|
||||
// First assign the value to the target then apply the operator in place on the target.
|
||||
// This saves a temporary variable
|
||||
translateNormalAssignment(
|
||||
AsmAssignment(
|
||||
AsmAssignSource.fromAstSource(value.expression, program, asmgen),
|
||||
assign.target,
|
||||
false, program.memsizer, assign.position
|
||||
)
|
||||
)
|
||||
val target = virtualRegsToVariables(assign.target)
|
||||
when (value.operator) {
|
||||
"+" -> {}
|
||||
"-" -> augmentableAsmGen.inplaceNegate(target, target.datatype)
|
||||
"~" -> augmentableAsmGen.inplaceInvert(target, target.datatype)
|
||||
else -> throw AssemblyError("invalid prefix operator")
|
||||
}
|
||||
} else {
|
||||
// array[x] = -array[x] ... use a tempvar then store that back into the array.
|
||||
val tempvar = asmgen.getTempVarName(assign.target.datatype).joinToString(".")
|
||||
val assignToTempvar = AsmAssignment(assign.source,
|
||||
AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, assign.target.datatype, assign.target.scope, variableAsmName=tempvar, origAstTarget = assign.target.origAstTarget),
|
||||
false, program.memsizer, assign.position)
|
||||
asmgen.translateNormalAssignment(assignToTempvar)
|
||||
when(assign.target.datatype) {
|
||||
in ByteDatatypes -> assignVariableByte(assign.target, tempvar)
|
||||
in WordDatatypes -> assignVariableWord(assign.target, tempvar)
|
||||
DataType.FLOAT -> assignVariableFloat(assign.target, tempvar)
|
||||
else -> throw AssemblyError("weird dt")
|
||||
}
|
||||
}
|
||||
}
|
||||
is ContainmentCheck -> {
|
||||
|
33
compiler/test/codegeneration/TestArrayInplaceAssign.kt
Normal file
33
compiler/test/codegeneration/TestArrayInplaceAssign.kt
Normal file
@ -0,0 +1,33 @@
|
||||
package prog8tests.codegeneration
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.core.spec.style.StringSpec
|
||||
import io.kotest.matchers.shouldNotBe
|
||||
import prog8.ast.Module
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.expressions.AddressOf
|
||||
import prog8.ast.expressions.IdentifierReference
|
||||
import prog8.ast.expressions.NumericLiteral
|
||||
import prog8.ast.statements.*
|
||||
import prog8.code.core.*
|
||||
import prog8.code.target.C64Target
|
||||
import prog8.code.target.c64.C64Zeropage
|
||||
import prog8.codegen.cpu6502.AsmGen
|
||||
import prog8.compiler.astprocessing.SymbolTableMaker
|
||||
import prog8tests.helpers.*
|
||||
|
||||
class TestArrayInplaceAssign: FunSpec({
|
||||
test("assign prefix var to array should compile fine and is not split into inplace array modification") {
|
||||
val text = """
|
||||
main {
|
||||
sub start() {
|
||||
byte[5] array
|
||||
byte bb
|
||||
array[1] = -bb
|
||||
}
|
||||
}
|
||||
"""
|
||||
compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null
|
||||
}
|
||||
})
|
||||
|
@ -3,10 +3,6 @@ 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
|
||||
|
Loading…
Reference in New Issue
Block a user