fix boolean array with initialization value

This commit is contained in:
Irmen de Jong 2023-04-04 22:11:51 +02:00
parent 4861973899
commit b6a837cbea
4 changed files with 45 additions and 6 deletions

View File

@ -242,6 +242,17 @@ internal class ConstantIdentifierReplacer(private val program: Program, private
}
}
}
DataType.ARRAY_BOOL -> {
val numericLv = decl.value as? NumericLiteral
val size = decl.arraysize?.constIndex() ?: return noModifications
if(numericLv!=null) {
// arraysize initializer is a single int, and we know the size.
val fillvalue = if(numericLv.number==0.0) 0.0 else 1.0
val array = Array(size) {fillvalue}.map { NumericLiteral(DataType.UBYTE, fillvalue, numericLv.position) }.toTypedArray<Expression>()
val refValue = ArrayLiteral(InferredTypes.InferredType.known(DataType.ARRAY_BOOL), array, position = numericLv.position)
return listOf(IAstModification.ReplaceNode(decl.value!!, refValue, decl))
}
}
else -> {
// nothing to do for this type
}

View File

@ -656,9 +656,12 @@ internal class AstChecker(private val program: Program,
if (iDt isnot decl.datatype) {
if(decl.datatype in ArrayDatatypes) {
val eltDt = ArrayToElementTypes.getValue(decl.datatype)
if(iDt isnot eltDt)
if(iDt isnot eltDt) {
if(!(iDt.isBool && eltDt==DataType.UBYTE || iDt.istype(DataType.UBYTE) && eltDt==DataType.BOOL))
err("initialisation value has incompatible type (${declValue.inferType(program)}) for the variable (${decl.datatype})")
}
} else {
if(!(iDt.isBool && decl.datatype==DataType.UBYTE || iDt.istype(DataType.UBYTE) && decl.datatype==DataType.BOOL))
err("initialisation value has incompatible type (${declValue.inferType(program)}) for the variable (${decl.datatype})")
}
}

View File

@ -23,9 +23,19 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
val valueDt = declValue.inferType(program)
if(valueDt isnot decl.datatype) {
// don't add a typecast on an array initializer value
if(valueDt.isInteger && decl.datatype in ArrayDatatypes)
// don't add a typecast on an array initializer value, unless booleans
if(valueDt.isInteger && decl.datatype in ArrayDatatypes) {
if(decl.datatype == DataType.ARRAY_BOOL) {
val integer = declValue.constValue(program)?.number
if(integer!=null) {
val num = NumericLiteral(DataType.UBYTE, if(integer==0.0) 0.0 else 1.0, declValue.position)
num.parent = decl
decl.value = num
}
} else {
return noModifications
}
}
// don't add a typecast if the initializer value is inherently not assignable
if(valueDt isNotAssignableTo decl.datatype)

View File

@ -80,4 +80,19 @@ class TestVariables: FunSpec({
compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null
}
test("initialization of boolean array with single value") {
val text = """
main {
sub start() {
bool[10] sieve0 = false
bool[10] sieve1 = true
bool[10] sieve2 = 42
sieve0[0] = true
sieve1[0] = true
sieve2[0] = true
}
}
"""
compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null
}
})