mirror of
https://github.com/irmen/prog8.git
synced 2024-11-22 00:31:56 +00:00
taking address of a split word array is no longer a fatal error but a warning and the array is turned back into a normal word array.
This commit is contained in:
parent
925b9d845d
commit
89425088ce
@ -4,6 +4,7 @@ import prog8.ast.IFunctionCall
|
||||
import prog8.ast.IStatementContainer
|
||||
import prog8.ast.Node
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.base.FatalAstException
|
||||
import prog8.ast.expressions.*
|
||||
import prog8.ast.statements.*
|
||||
import prog8.ast.walk.AstWalker
|
||||
@ -76,6 +77,23 @@ internal class LiteralsToAutoVars(private val program: Program, private val erro
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(array.type.isArray) {
|
||||
val mods = mutableListOf<IAstModification>()
|
||||
for(elt in array.value.filterIsInstance<IdentifierReference>()) {
|
||||
val decl = elt.targetVarDecl(program)
|
||||
if(decl!=null && decl.splitArray) {
|
||||
// you can't take the adress of a split-word array.
|
||||
// instead of giving a fatal error, we remove the
|
||||
// instead of a fatal error, we give a warning and turn it back into a regular array.
|
||||
errors.warn("cannot take address of split word array - the array is turned back into a regular word array", decl.position)
|
||||
val normalArray = makeNormalArrayFromSplit(decl)
|
||||
mods.add(IAstModification.ReplaceNode(decl, normalArray, decl.parent))
|
||||
}
|
||||
}
|
||||
return mods
|
||||
}
|
||||
|
||||
return noModifications
|
||||
}
|
||||
|
||||
@ -138,4 +156,32 @@ internal class LiteralsToAutoVars(private val program: Program, private val erro
|
||||
// }
|
||||
return noModifications
|
||||
}
|
||||
|
||||
override fun after(addressOf: AddressOf, parent: Node): Iterable<IAstModification> {
|
||||
val variable=addressOf.identifier.targetVarDecl(program)
|
||||
if (variable!=null) {
|
||||
if (variable.splitArray) {
|
||||
// you can't take the adress of a split-word array.
|
||||
// instead of giving a fatal error, we remove the
|
||||
// instead of a fatal error, we give a warning and turn it back into a regular array.
|
||||
errors.warn("cannot take address of split word array - the array is turned back into a regular word array", addressOf.position)
|
||||
val normalArray = makeNormalArrayFromSplit(variable)
|
||||
return listOf(IAstModification.ReplaceNode(variable, normalArray, variable.parent))
|
||||
}
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
|
||||
private fun makeNormalArrayFromSplit(variable: VarDecl): VarDecl {
|
||||
val normalDt = when(variable.datatype) {
|
||||
DataType.ARRAY_UW_SPLIT -> DataType.ARRAY_UW
|
||||
DataType.ARRAY_W_SPLIT -> DataType.ARRAY_W
|
||||
else -> throw FatalAstException("invalid dt")
|
||||
}
|
||||
return VarDecl(
|
||||
variable.type, variable.origin, normalDt, variable.zeropage, variable.arraysize, variable.name, emptyList(),
|
||||
variable.value?.copy(), variable.sharedWithAsm, false, variable.alignment, variable.position
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -795,5 +795,31 @@ txt {
|
||||
errors.errors[0] shouldContain "undefined symbol: txt.print2222"
|
||||
errors.errors[1] shouldContain "undefined symbol: txt.DEFAULT_WIDTH_XXX"
|
||||
}
|
||||
|
||||
test("split arrays back to normal when address is taken") {
|
||||
val src="""
|
||||
main {
|
||||
sub start() {
|
||||
cx16.r0L=0
|
||||
if cx16.r0L==0 {
|
||||
uword[] addresses = [scores2, start]
|
||||
uword[] @split scores1 = [10, 25, 50, 100]
|
||||
uword[] @split scores2 = [100, 250, 500, 1000]
|
||||
|
||||
cx16.r0 = &scores1
|
||||
cx16.r1 = &scores2
|
||||
cx16.r2 = &addresses
|
||||
}
|
||||
}
|
||||
}"""
|
||||
val errors = ErrorReporterForTests(keepMessagesAfterReporting = true)
|
||||
compileText(C64Target(), optimize=false, src, writeAssembly=true, errors=errors) shouldNotBe null
|
||||
errors.errors.size shouldBe 0
|
||||
errors.warnings.size shouldBe 2
|
||||
errors.warnings[0] shouldContain("address")
|
||||
errors.warnings[1] shouldContain("address")
|
||||
errors.warnings[0] shouldContain("split")
|
||||
errors.warnings[1] shouldContain("split")
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -1,9 +1,6 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
"cannot take address of split word array" -> don't make this a fatal error, make it a warning and turn the array into a regular array instead
|
||||
(benchmark program/textelite should then be compilable with -splitarrays)
|
||||
|
||||
merge problem: if 2 library modules both have merge, stuff breaks (math & prog8_math where prog8_math used to have math block.... didn't work)
|
||||
|
||||
for releasenotes: gfx2.width and gfx2.height got renamed as gfx_lores.WIDTH/HEIGHT or gfx_hires4.WIDTH/HEIGTH constants. Screen mode routines also renamed.
|
||||
|
@ -5,10 +5,15 @@
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
cx16.r0L=0
|
||||
if cx16.r0L==0 {
|
||||
uword[] scores = [10, 25, 50, 100] ; can never clear more than 4 lines at once
|
||||
txt.print_uw(scores[1])
|
||||
txt.nl()
|
||||
uword[] addresses = [scores2, start]
|
||||
uword[] @split scores1 = [10, 25, 50, 100] ; can never clear more than 4 lines at once
|
||||
uword[] @split scores2 = [10, 25, 50, 100] ; can never clear more than 4 lines at once
|
||||
|
||||
cx16.r0 = &scores1
|
||||
cx16.r1 = &scores2
|
||||
cx16.r2 = &addresses
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user