mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
make isArray a computed property by simply checking the datatype
This commit is contained in:
parent
5179562fb2
commit
4bb2b8ca9b
@ -174,7 +174,7 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
|
||||
// }
|
||||
// VarDeclType.MEMORY -> {
|
||||
// val numElements =
|
||||
// if(decl.datatype in ArrayDatatypes)
|
||||
// if(decl.isArray)
|
||||
// decl.arraysize!!.constIndex()
|
||||
// else null
|
||||
// val astNode = PtVariable(decl.name, decl.datatype, null, null, decl.position)
|
||||
|
@ -167,7 +167,7 @@ class StatementOptimizer(private val program: Program,
|
||||
return listOf(IAstModification.ReplaceNode(forLoop, scope, parent))
|
||||
}
|
||||
}
|
||||
else if(iterable.datatype in ArrayDatatypes) {
|
||||
else if(iterable.isArray) {
|
||||
val size = iterable.arraysize!!.constIndex()
|
||||
if(size==1) {
|
||||
// loop over array of length 1 -> just assign the single value
|
||||
|
@ -697,7 +697,7 @@ internal class AstChecker(private val program: Program,
|
||||
if(declValue!=null && decl.type==VarDeclType.VAR) {
|
||||
val iDt = declValue.inferType(program)
|
||||
if (iDt isnot decl.datatype) {
|
||||
if(decl.datatype in ArrayDatatypes) {
|
||||
if(decl.isArray) {
|
||||
val eltDt = ArrayToElementTypes.getValue(decl.datatype)
|
||||
if(iDt isnot eltDt) {
|
||||
if(!(iDt.isBool && eltDt==DataType.UBYTE || iDt.istype(DataType.UBYTE) && eltDt==DataType.BOOL))
|
||||
|
@ -197,7 +197,7 @@ class AstPreprocessor(val program: Program,
|
||||
private fun makeSplitArray(decl: VarDecl): Iterable<IAstModification> {
|
||||
val newDecl = VarDecl(
|
||||
decl.type, decl.origin, decl.datatype, decl.zeropage, decl.arraysize, decl.name, emptyList(),
|
||||
decl.value, true, decl.sharedWithAsm, true, decl.position
|
||||
decl.value, decl.sharedWithAsm, true, decl.position
|
||||
)
|
||||
return listOf(IAstModification.ReplaceNode(decl, newDecl, decl.parent))
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ internal class BoolRemover(val program: Program) : AstWalker() {
|
||||
newvalue = NumericLiteral(DataType.UBYTE, 1.0, newvalue.position)
|
||||
}
|
||||
val ubyteDecl = VarDecl(decl.type, decl.origin, DataType.UBYTE, decl.zeropage, null, decl.name, emptyList(),
|
||||
newvalue, false, decl.sharedWithAsm, false, decl.position)
|
||||
newvalue, decl.sharedWithAsm, false, decl.position)
|
||||
return listOf(IAstModification.ReplaceNode(decl, ubyteDecl, parent))
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ internal class BoolRemover(val program: Program) : AstWalker() {
|
||||
newarray = ArrayLiteral(InferredTypes.InferredType.known(DataType.ARRAY_UB), convertedArray, decl.position)
|
||||
}
|
||||
val ubyteArrayDecl = VarDecl(decl.type, decl.origin, DataType.ARRAY_UB, decl.zeropage, decl.arraysize, decl.name, emptyList(),
|
||||
newarray, true, decl.sharedWithAsm, decl.splitArray, decl.position)
|
||||
newarray, decl.sharedWithAsm, decl.splitArray, decl.position)
|
||||
return listOf(IAstModification.ReplaceNode(decl, ubyteArrayDecl, parent))
|
||||
}
|
||||
|
||||
|
@ -489,7 +489,7 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
|
||||
when(srcVar.type) {
|
||||
VarDeclType.VAR -> {
|
||||
val value = if(srcVar.value!=null) transformExpression(srcVar.value!!) else null
|
||||
if(srcVar.datatype in ArrayDatatypes) {
|
||||
if(srcVar.isArray) {
|
||||
if(value==null) {
|
||||
val blockOptions = srcVar.definingBlock.options()
|
||||
if("align_page" in blockOptions || "align_word" in blockOptions) {
|
||||
|
@ -80,7 +80,7 @@ internal class StatementReorderer(
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(decl.datatype in ArrayDatatypes) {
|
||||
else if(decl.isArray) {
|
||||
// only if the initializer expression is a reference to another array, split it into a separate assignment.
|
||||
// this is so that it later can be changed into a memcopy.
|
||||
// (that code only triggers on regular assignment, not on variable initializers)
|
||||
@ -157,7 +157,6 @@ internal class StatementReorderer(
|
||||
it.name,
|
||||
emptyList(),
|
||||
null,
|
||||
false,
|
||||
it.sharedWithAsm,
|
||||
it.splitArray,
|
||||
it.position
|
||||
|
@ -25,7 +25,7 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
||||
if(valueDt isnot decl.datatype) {
|
||||
|
||||
// don't add a typecast on an array initializer value, unless booleans
|
||||
if(valueDt.isInteger && decl.datatype in ArrayDatatypes) {
|
||||
if(valueDt.isInteger && decl.isArray) {
|
||||
if(decl.datatype == DataType.ARRAY_BOOL) {
|
||||
val integer = declValue.constValue(program)?.number
|
||||
if(integer!=null) {
|
||||
|
@ -112,7 +112,7 @@ class TestMemory: FunSpec({
|
||||
}
|
||||
|
||||
fun createTestProgramForMemoryRefViaVar(address: UInt, vartype: VarDeclType): AssignTarget {
|
||||
val decl = VarDecl(vartype, VarDeclOrigin.USERCODE, DataType.BYTE, ZeropageWish.DONTCARE, null, "address", emptyList(), NumericLiteral.optimalInteger(address, Position.DUMMY), false, false, false, Position.DUMMY)
|
||||
val decl = VarDecl(vartype, VarDeclOrigin.USERCODE, DataType.BYTE, ZeropageWish.DONTCARE, null, "address", emptyList(), NumericLiteral.optimalInteger(address, Position.DUMMY), false, false, Position.DUMMY)
|
||||
val memexpr = IdentifierReference(listOf("address"), Position.DUMMY)
|
||||
val target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY)
|
||||
val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
||||
@ -150,7 +150,7 @@ class TestMemory: FunSpec({
|
||||
}
|
||||
|
||||
test("regular variable not in mapped IO ram on C64") {
|
||||
val decl = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.BYTE, ZeropageWish.DONTCARE, null, "address", emptyList(), null, false, false, false, Position.DUMMY)
|
||||
val decl = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.BYTE, ZeropageWish.DONTCARE, null, "address", emptyList(), null, false, false, Position.DUMMY)
|
||||
val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, Position.DUMMY)
|
||||
val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
||||
val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, false, mutableListOf(decl, assignment), Position.DUMMY)
|
||||
@ -162,7 +162,7 @@ class TestMemory: FunSpec({
|
||||
|
||||
test("memory mapped variable not in mapped IO ram on C64") {
|
||||
val address = 0x1000u
|
||||
val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.UBYTE, ZeropageWish.DONTCARE, null, "address", emptyList(), NumericLiteral.optimalInteger(address, Position.DUMMY), false, false, false, Position.DUMMY)
|
||||
val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.UBYTE, ZeropageWish.DONTCARE, null, "address", emptyList(), NumericLiteral.optimalInteger(address, Position.DUMMY), false, false, Position.DUMMY)
|
||||
val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, Position.DUMMY)
|
||||
val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
||||
val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, false, mutableListOf(decl, assignment), Position.DUMMY)
|
||||
@ -174,7 +174,7 @@ class TestMemory: FunSpec({
|
||||
|
||||
test("memory mapped variable in mapped IO ram on C64") {
|
||||
val address = 0xd020u
|
||||
val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.UBYTE, ZeropageWish.DONTCARE, null, "address", emptyList(), NumericLiteral.optimalInteger(address, Position.DUMMY), false, false, false, Position.DUMMY)
|
||||
val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.UBYTE, ZeropageWish.DONTCARE, null, "address", emptyList(), NumericLiteral.optimalInteger(address, Position.DUMMY), false, false, Position.DUMMY)
|
||||
val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, Position.DUMMY)
|
||||
val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
||||
val subroutine = Subroutine("test", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, false, mutableListOf(decl, assignment), Position.DUMMY)
|
||||
@ -185,7 +185,7 @@ class TestMemory: FunSpec({
|
||||
}
|
||||
|
||||
test("array not in mapped IO ram") {
|
||||
val decl = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.ARRAY_UB, ZeropageWish.DONTCARE, null, "address", emptyList(), null, true, false, false, Position.DUMMY)
|
||||
val decl = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.ARRAY_UB, ZeropageWish.DONTCARE, null, "address", emptyList(), null, false, false, Position.DUMMY)
|
||||
val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), ArrayIndex(NumericLiteral.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY)
|
||||
val target = AssignTarget(null, arrayindexed, null, Position.DUMMY)
|
||||
val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
||||
@ -198,7 +198,7 @@ class TestMemory: FunSpec({
|
||||
|
||||
test("memory mapped array not in mapped IO ram") {
|
||||
val address = 0x1000u
|
||||
val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.ARRAY_UB, ZeropageWish.DONTCARE, null, "address", emptyList(), NumericLiteral.optimalInteger(address, Position.DUMMY), true, false, false, Position.DUMMY)
|
||||
val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.ARRAY_UB, ZeropageWish.DONTCARE, null, "address", emptyList(), NumericLiteral.optimalInteger(address, Position.DUMMY), false, false, Position.DUMMY)
|
||||
val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), ArrayIndex(NumericLiteral.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY)
|
||||
val target = AssignTarget(null, arrayindexed, null, Position.DUMMY)
|
||||
val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
||||
@ -211,7 +211,7 @@ class TestMemory: FunSpec({
|
||||
|
||||
test("memory mapped array in mapped IO ram") {
|
||||
val address = 0xd800u
|
||||
val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.ARRAY_UB, ZeropageWish.DONTCARE, null, "address", emptyList(), NumericLiteral.optimalInteger(address, Position.DUMMY), true, false, false, Position.DUMMY)
|
||||
val decl = VarDecl(VarDeclType.MEMORY, VarDeclOrigin.USERCODE, DataType.ARRAY_UB, ZeropageWish.DONTCARE, null, "address", emptyList(), NumericLiteral.optimalInteger(address, Position.DUMMY), false, false, Position.DUMMY)
|
||||
val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), ArrayIndex(NumericLiteral.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY)
|
||||
val target = AssignTarget(null, arrayindexed, null, Position.DUMMY)
|
||||
val assignment = Assignment(target, NumericLiteral.optimalInteger(0, Position.DUMMY), AssignmentOrigin.USERCODE, Position.DUMMY)
|
||||
|
@ -46,8 +46,8 @@ class TestAsmGenSymbols: StringSpec({
|
||||
}
|
||||
|
||||
*/
|
||||
val varInSub = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.UWORD, ZeropageWish.DONTCARE, null, "localvar", emptyList(), NumericLiteral.optimalInteger(1234, Position.DUMMY), false, false, false, Position.DUMMY)
|
||||
val var2InSub = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.UWORD, ZeropageWish.DONTCARE, null, "tgt", emptyList(), null, false, false, false, Position.DUMMY)
|
||||
val varInSub = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.UWORD, ZeropageWish.DONTCARE, null, "localvar", emptyList(), NumericLiteral.optimalInteger(1234, Position.DUMMY), false, false, Position.DUMMY)
|
||||
val var2InSub = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.UWORD, ZeropageWish.DONTCARE, null, "tgt", emptyList(), null, false, false, Position.DUMMY)
|
||||
val labelInSub = Label("locallabel", Position.DUMMY)
|
||||
|
||||
val tgt = AssignTarget(IdentifierReference(listOf("tgt"), Position.DUMMY), null, null, Position.DUMMY)
|
||||
@ -63,7 +63,7 @@ class TestAsmGenSymbols: StringSpec({
|
||||
val statements = mutableListOf(varInSub, var2InSub, labelInSub, assign1, assign2, assign3, assign4, assign5, assign6, assign7, assign8)
|
||||
val subroutine = Subroutine("start", mutableListOf(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, false, statements, Position.DUMMY)
|
||||
val labelInBlock = Label("label_outside", Position.DUMMY)
|
||||
val varInBlock = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.UWORD, ZeropageWish.DONTCARE, null, "var_outside", emptyList(),null, false, false, false, Position.DUMMY)
|
||||
val varInBlock = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.UWORD, ZeropageWish.DONTCARE, null, "var_outside", emptyList(),null, false, false, Position.DUMMY)
|
||||
val block = Block("main", null, mutableListOf(labelInBlock, varInBlock, subroutine), false, Position.DUMMY)
|
||||
|
||||
val module = Module(mutableListOf(block), Position.DUMMY, SourceCode.Generated("test"))
|
||||
|
@ -87,7 +87,7 @@ class Program(val name: String,
|
||||
val varName = "string_${internedStringsBlock.statements.size}"
|
||||
val decl = VarDecl(
|
||||
VarDeclType.VAR, VarDeclOrigin.STRINGLITERAL, DataType.STR, ZeropageWish.NOT_IN_ZEROPAGE, null, varName, emptyList(), string,
|
||||
isArray = false, sharedWithAsm = false, splitArray = false, position = string.position
|
||||
sharedWithAsm = false, splitArray = false, position = string.position
|
||||
)
|
||||
internedStringsBlock.statements.add(decl)
|
||||
decl.linkParents(internedStringsBlock)
|
||||
|
@ -676,7 +676,6 @@ private fun VardeclContext.toAst(type: VarDeclType, value: Expression?): VarDecl
|
||||
name,
|
||||
if(identifiers.size==1) emptyList() else identifiers.map { it.NAME().text },
|
||||
value,
|
||||
isArray,
|
||||
options.SHARED().isNotEmpty(),
|
||||
split,
|
||||
toPosition()
|
||||
|
@ -209,7 +209,6 @@ class VarDecl(val type: VarDeclType,
|
||||
override val name: String,
|
||||
val names: List<String>,
|
||||
var value: Expression?,
|
||||
val isArray: Boolean,
|
||||
val sharedWithAsm: Boolean,
|
||||
val splitArray: Boolean,
|
||||
override val position: Position) : Statement(), INamedStatement {
|
||||
@ -217,10 +216,8 @@ class VarDecl(val type: VarDeclType,
|
||||
var allowInitializeWithZero = true
|
||||
|
||||
init {
|
||||
if(isArray)
|
||||
if(splitArray)
|
||||
require(datatype in ArrayDatatypes) { "array dt mismatch" }
|
||||
else
|
||||
require(datatype !in ArrayDatatypes) { "array dt mismatch" }
|
||||
}
|
||||
|
||||
companion object {
|
||||
@ -229,7 +226,6 @@ class VarDecl(val type: VarDeclType,
|
||||
fun fromParameter(param: SubroutineParameter): VarDecl {
|
||||
val dt = if(param.type in ArrayDatatypes) DataType.UWORD else param.type
|
||||
return VarDecl(VarDeclType.VAR, VarDeclOrigin.SUBROUTINEPARAM, dt, ZeropageWish.DONTCARE, null, param.name, emptyList(), null,
|
||||
isArray = false,
|
||||
sharedWithAsm = false,
|
||||
splitArray = false,
|
||||
position = param.position
|
||||
@ -241,10 +237,13 @@ class VarDecl(val type: VarDeclType,
|
||||
val arrayDt = array.type.getOrElse { throw FatalAstException("unknown dt") }
|
||||
val arraysize = ArrayIndex.forArray(array)
|
||||
return VarDecl(VarDeclType.VAR, VarDeclOrigin.ARRAYLITERAL, arrayDt, ZeropageWish.NOT_IN_ZEROPAGE, arraysize, autoVarName, emptyList(), array,
|
||||
isArray = true, sharedWithAsm = false, splitArray = splitArray, position = array.position)
|
||||
sharedWithAsm = false, splitArray = splitArray, position = array.position)
|
||||
}
|
||||
}
|
||||
|
||||
val isArray: Boolean
|
||||
get() = datatype in ArrayDatatypes
|
||||
|
||||
override fun linkParents(parent: Node) {
|
||||
this.parent = parent
|
||||
arraysize?.linkParents(this)
|
||||
@ -264,7 +263,7 @@ class VarDecl(val type: VarDeclType,
|
||||
|
||||
fun zeroElementValue(): NumericLiteral {
|
||||
if(allowInitializeWithZero) {
|
||||
return if(isArray) defaultZero(ArrayToElementTypes.getValue(datatype), position)
|
||||
return if(datatype in ArrayDatatypes) defaultZero(ArrayToElementTypes.getValue(datatype), position)
|
||||
else defaultZero(datatype, position)
|
||||
}
|
||||
else
|
||||
@ -275,7 +274,7 @@ class VarDecl(val type: VarDeclType,
|
||||
if(names.size>1)
|
||||
throw FatalAstException("should not copy a vardecl that still has multiple names")
|
||||
val copy = VarDecl(type, origin, datatype, zeropage, arraysize?.copy(), name, names, value?.copy(),
|
||||
isArray, sharedWithAsm, splitArray, position)
|
||||
sharedWithAsm, splitArray, position)
|
||||
copy.allowInitializeWithZero = this.allowInitializeWithZero
|
||||
return copy
|
||||
}
|
||||
@ -295,19 +294,19 @@ class VarDecl(val type: VarDeclType,
|
||||
// just copy the initialization value to a separata vardecl for each component
|
||||
return names.map {
|
||||
val copy = VarDecl(type, origin, datatype, zeropage, arraysize?.copy(), it, emptyList(), value?.copy(),
|
||||
isArray, sharedWithAsm, splitArray, position)
|
||||
sharedWithAsm, splitArray, position)
|
||||
copy.allowInitializeWithZero = this.allowInitializeWithZero
|
||||
copy
|
||||
}
|
||||
} else {
|
||||
// evaluate the value once in the vardecl for the first component, and set the other components to the first
|
||||
val first = VarDecl(type, origin, datatype, zeropage, arraysize?.copy(), names[0], emptyList(), value?.copy(),
|
||||
isArray, sharedWithAsm, splitArray, position)
|
||||
sharedWithAsm, splitArray, position)
|
||||
first.allowInitializeWithZero = this.allowInitializeWithZero
|
||||
val firstVar = firstVarAsValue(first)
|
||||
return listOf(first) + names.drop(1 ).map {
|
||||
val copy = VarDecl(type, origin, datatype, zeropage, arraysize?.copy(), it, emptyList(), firstVar.copy(),
|
||||
isArray, sharedWithAsm, splitArray, position)
|
||||
sharedWithAsm, splitArray, position)
|
||||
copy.allowInitializeWithZero = this.allowInitializeWithZero
|
||||
copy
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user