fix split array possible compiler loop (due to wrong datatype replacement)

This commit is contained in:
Irmen de Jong 2024-11-01 19:04:11 +01:00
parent ad074076c2
commit 925b9d845d
6 changed files with 32 additions and 16 deletions

View File

@ -112,6 +112,8 @@ class AstPreprocessor(val program: Program,
val replacements = mutableListOf<IAstModification>()
for(decl in vars) {
if(shouldSplitArray(decl))
continue // splitting must be done first
if(decl.type != VarDeclType.VAR) {
movements.add(IAstModification.InsertFirst(decl, parentscope))
replacements.add(IAstModification.Remove(decl, scope))
@ -179,9 +181,8 @@ class AstPreprocessor(val program: Program,
}
}
if(options.splitWordArrays && (decl.datatype==DataType.ARRAY_W || decl.datatype==DataType.ARRAY_UW)) {
if(!decl.definingBlock.isInLibrary)
return makeSplitArray(decl)
if(shouldSplitArray(decl)) {
return makeSplitArray(decl)
}
if(decl.datatype==DataType.ARRAY_W || decl.datatype==DataType.ARRAY_UW) {
@ -194,10 +195,18 @@ class AstPreprocessor(val program: Program,
return noModifications
}
private fun shouldSplitArray(decl: VarDecl): Boolean =
options.splitWordArrays && (decl.datatype==DataType.ARRAY_W || decl.datatype==DataType.ARRAY_UW) && !decl.definingBlock.isInLibrary
private fun makeSplitArray(decl: VarDecl): Iterable<IAstModification> {
val splitDt = when(decl.datatype) {
DataType.ARRAY_UW, DataType.ARRAY_UW_SPLIT -> DataType.ARRAY_UW_SPLIT
DataType.ARRAY_W,DataType.ARRAY_W_SPLIT -> DataType.ARRAY_W_SPLIT
else -> throw FatalAstException("invalid dt")
}
val newDecl = VarDecl(
decl.type, decl.origin, decl.datatype, decl.zeropage, decl.arraysize, decl.name, emptyList(),
decl.value, decl.sharedWithAsm, true, decl.alignment, decl.position
decl.type, decl.origin, splitDt, decl.zeropage, decl.arraysize, decl.name, emptyList(),
decl.value?.copy(), decl.sharedWithAsm, true, decl.alignment, decl.position
)
return listOf(IAstModification.ReplaceNode(decl, newDecl, decl.parent))
}

View File

@ -744,9 +744,15 @@ private fun VardeclContext.toAst(type: VarDeclType, value: Expression?): VarDecl
} else arrayDt
} else origDt
val datatype = if(!split) dt else when(dt) {
DataType.ARRAY_UW, DataType.ARRAY_UW_SPLIT -> DataType.ARRAY_UW_SPLIT
DataType.ARRAY_W,DataType.ARRAY_W_SPLIT -> DataType.ARRAY_W_SPLIT
else -> dt
}
return VarDecl(
type, VarDeclOrigin.USERCODE,
dt,
datatype,
zp,
arrayindex()?.toAst(),
name,

View File

@ -892,7 +892,7 @@ class ArrayLiteral(val type: InferredTypes.InferredType, // inferred because
value.forEach {it.linkParents(this)}
}
override fun copy() = throw NotImplementedError("no support for duplicating a ArrayLiteralValue")
override fun copy(): ArrayLiteral = ArrayLiteral(type, value.map { it.copy() }.toTypedArray(), position)
override val isSimple = true
override fun replaceChildNode(node: Node, replacement: Node) {

View File

@ -274,6 +274,11 @@ class VarDecl(val type: VarDeclType,
}
}
init {
if(datatype in SplitWordArrayTypes)
require(splitArray)
}
val isArray: Boolean
get() = datatype in ArrayDatatypes

View File

@ -1,7 +1,8 @@
TODO
====
-splitarrays option gets the compiler in an infinite loop sometimes (on examples/animals.p8 for example)
"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)

View File

@ -1,4 +1,3 @@
%import math
%import textio
%option no_sysinit
%zeropage basicsafe
@ -6,15 +5,11 @@
main {
sub start() {
ubyte v1 = 100
ubyte v2 = 200
for cx16.r0L in 0 to 255 step 16 {
txt.print_ub(math.lerp(v1, v2, cx16.r0L))
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()
}
txt.print_ub(math.lerp(v1, v2, 255))
txt.nl()
}
}