From 5f1ec80ae054aed059e7590814057b362de86809 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 12 Mar 2020 01:10:19 +0100 Subject: [PATCH] improved array literal datatype handling, fixed some datatype compiler errors related to this --- compiler/src/prog8/ast/antlr/Antr2Kotlin.kt | 2 +- compiler/src/prog8/ast/base/Base.kt | 7 + .../prog8/ast/expressions/AstExpressions.kt | 42 ++++-- .../src/prog8/ast/processing/AstChecker.kt | 22 ++-- .../ast/processing/AstIdentifiersChecker.kt | 91 ++++--------- .../VarInitValueAndAddressOfCreator.kt | 2 +- .../src/prog8/ast/statements/AstStatements.kt | 8 +- .../src/prog8/optimizer/ConstantFolding.kt | 26 ++-- .../prog8/optimizer/SimplifyExpressions.kt | 2 +- .../src/prog8/optimizer/StatementOptimizer.kt | 2 +- compiler/src/prog8/vm/RuntimeValue.kt | 6 +- compiler/test/LiteralValueTests.kt | 7 +- examples/test.p8 | 120 +----------------- examples/testarrays.p8 | 2 +- examples/testforloops.p8 | 4 +- 15 files changed, 114 insertions(+), 229 deletions(-) diff --git a/compiler/src/prog8/ast/antlr/Antr2Kotlin.kt b/compiler/src/prog8/ast/antlr/Antr2Kotlin.kt index 2b483ed53..bff040482 100644 --- a/compiler/src/prog8/ast/antlr/Antr2Kotlin.kt +++ b/compiler/src/prog8/ast/antlr/Antr2Kotlin.kt @@ -476,7 +476,7 @@ private fun prog8Parser.ExpressionContext.toAst() : Expression { val array = litval.arrayliteral().toAst() // the actual type of the arraysize can not yet be determined here (missing namespace & heap) // the ConstantFold takes care of that and converts the type if needed. - ArrayLiteralValue(DataType.ARRAY_UB, array, position = litval.toPosition()) + ArrayLiteralValue(InferredTypes.InferredType.unknown(), array, position = litval.toPosition()) } litval.structliteral()!=null -> { val values = litval.structliteral().expression().map { it.toAst() } diff --git a/compiler/src/prog8/ast/base/Base.kt b/compiler/src/prog8/ast/base/Base.kt index cfe40de75..164c31479 100644 --- a/compiler/src/prog8/ast/base/Base.kt +++ b/compiler/src/prog8/ast/base/Base.kt @@ -126,6 +126,13 @@ val ArrayElementTypes = mapOf( DataType.ARRAY_W to DataType.WORD, DataType.ARRAY_UW to DataType.UWORD, DataType.ARRAY_F to DataType.FLOAT) +val ElementArrayTypes = mapOf( + DataType.BYTE to DataType.ARRAY_B, + DataType.UBYTE to DataType.ARRAY_UB, + DataType.WORD to DataType.ARRAY_W, + DataType.UWORD to DataType.ARRAY_UW, + DataType.FLOAT to DataType.ARRAY_F +) // find the parent node of a specific type or interface // (useful to figure out in what namespace/block something is defined, etc) diff --git a/compiler/src/prog8/ast/expressions/AstExpressions.kt b/compiler/src/prog8/ast/expressions/AstExpressions.kt index 2df0d77eb..882b75fa3 100644 --- a/compiler/src/prog8/ast/expressions/AstExpressions.kt +++ b/compiler/src/prog8/ast/expressions/AstExpressions.kt @@ -5,10 +5,7 @@ import prog8.ast.antlr.escape import prog8.ast.base.* import prog8.ast.processing.IAstModifyingVisitor import prog8.ast.processing.IAstVisitor -import prog8.ast.statements.ArrayIndex -import prog8.ast.statements.BuiltinFunctionStatementPlaceholder -import prog8.ast.statements.Subroutine -import prog8.ast.statements.VarDecl +import prog8.ast.statements.* import prog8.compiler.target.CompilationTarget import prog8.functions.BuiltinFunctions import prog8.functions.NotConstArgumentException @@ -454,7 +451,7 @@ class StringLiteralValue(val value: String, } } -class ArrayLiteralValue(val type: DataType, // only array types +class ArrayLiteralValue(val type: InferredTypes.InferredType, // inferred because not all array literals hava a known type yet val value: Array, override val position: Position) : Expression() { override lateinit var parent: Node @@ -470,7 +467,8 @@ class ArrayLiteralValue(val type: DataType, // only array types override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this) override fun toString(): String = "$value" - override fun inferType(program: Program): InferredTypes.InferredType = InferredTypes.knownFor(type) + override fun inferType(program: Program): InferredTypes.InferredType = if(type.isUnknown) type else guessDatatype(program) + operator fun compareTo(other: ArrayLiteralValue): Int = throw ExpressionError("cannot order compare arrays", position) override fun hashCode(): Int = Objects.hash(value, type) override fun equals(other: Any?): Boolean { @@ -479,8 +477,36 @@ class ArrayLiteralValue(val type: DataType, // only array types return type==other.type && value.contentEquals(other.value) } + fun guessDatatype(program: Program): InferredTypes.InferredType { + // Educated guess of the desired array literal's datatype. + // If it's inside a for loop, assume the data type of the loop variable is what we want. + val forloop = parent as? ForLoop + if(forloop != null) { + val loopvarDt = forloop.loopVarDt(program) + if(loopvarDt.isKnown) { + return if(loopvarDt.typeOrElse(DataType.STRUCT) !in ElementArrayTypes) + InferredTypes.InferredType.unknown() + else + InferredTypes.InferredType.known(ElementArrayTypes.getValue(loopvarDt.typeOrElse(DataType.STRUCT))) + } + } + + // otherwise, select the "biggegst" datatype based on the elements in the array. + val datatypesInArray = value.map { it.inferType(program) } + require(datatypesInArray.isNotEmpty() && datatypesInArray.all { it.isKnown }) { "can't determine type of empty array" } + val dts = datatypesInArray.map { it.typeOrElse(DataType.STRUCT) } + return when { + DataType.FLOAT in dts -> InferredTypes.InferredType.known(DataType.ARRAY_F) + DataType.WORD in dts -> InferredTypes.InferredType.known(DataType.ARRAY_W) + DataType.UWORD in dts -> InferredTypes.InferredType.known(DataType.ARRAY_UW) + DataType.BYTE in dts -> InferredTypes.InferredType.known(DataType.ARRAY_B) + DataType.UBYTE in dts -> InferredTypes.InferredType.known(DataType.ARRAY_UB) + else -> InferredTypes.InferredType.unknown() + } + } + fun cast(targettype: DataType): ArrayLiteralValue? { - if(type==targettype) + if(type.istype(targettype)) return this if(targettype in ArrayDatatypes) { val elementType = ArrayElementTypes.getValue(targettype) @@ -499,7 +525,7 @@ class ArrayLiteralValue(val type: DataType, // only array types } } }.toTypedArray() - return ArrayLiteralValue(targettype, castArray, position = position) + return ArrayLiteralValue(InferredTypes.InferredType.known(targettype), castArray, position = position) } return null // invalid type conversion from $this to $targettype } diff --git a/compiler/src/prog8/ast/processing/AstChecker.kt b/compiler/src/prog8/ast/processing/AstChecker.kt index 06e1febef..ccdd77359 100644 --- a/compiler/src/prog8/ast/processing/AstChecker.kt +++ b/compiler/src/prog8/ast/processing/AstChecker.kt @@ -686,11 +686,13 @@ internal class AstChecker(private val program: Program, } override fun visit(array: ArrayLiteralValue) { - if(!compilerOptions.floats && array.type in setOf(DataType.FLOAT, DataType.ARRAY_F)) { - checkResult.add(SyntaxError("floating point used, but that is not enabled via options", array.position)) + if(array.type.isKnown) { + if (!compilerOptions.floats && array.type.typeOrElse(DataType.STRUCT) in setOf(DataType.FLOAT, DataType.ARRAY_F)) { + checkResult.add(SyntaxError("floating point used, but that is not enabled via options", array.position)) + } + val arrayspec = ArrayIndex.forArray(array) + checkValueTypeAndRangeArray(array.type.typeOrElse(DataType.STRUCT), null, arrayspec, array) } - val arrayspec = ArrayIndex.forArray(array) - checkValueTypeAndRangeArray(array.type, null, arrayspec, array) super.visit(array) } @@ -1064,11 +1066,15 @@ internal class AstChecker(private val program: Program, checkResult.add(ExpressionError(msg, value.position)) return false } + + if(value.type.isUnknown) + return err("attempt to check values of array with as yet unknown datatype") + when (targetDt) { DataType.STR -> return err("string value expected") DataType.ARRAY_UB, DataType.ARRAY_B -> { // value may be either a single byte, or a byte arraysize (of all constant values), or a range - if(value.type==targetDt) { + if(value.type.istype(targetDt)) { if(!checkArrayValues(value, targetDt)) return false val arraySpecSize = arrayspec.size() @@ -1090,7 +1096,7 @@ internal class AstChecker(private val program: Program, } DataType.ARRAY_UW, DataType.ARRAY_W -> { // value may be either a single word, or a word arraysize, or a range - if(value.type==targetDt) { + if(value.type.istype(targetDt)) { if(!checkArrayValues(value, targetDt)) return false val arraySpecSize = arrayspec.size() @@ -1112,7 +1118,7 @@ internal class AstChecker(private val program: Program, } DataType.ARRAY_F -> { // value may be either a single float, or a float arraysize - if(value.type==targetDt) { + if(value.type.istype(targetDt)) { if(!checkArrayValues(value, targetDt)) return false val arraySize = value.value.size @@ -1138,7 +1144,7 @@ internal class AstChecker(private val program: Program, return err("invalid float array initialization value ${value.type}, expected $targetDt") } DataType.STRUCT -> { - if(value.type in ArrayDatatypes) { + if(value.type.typeOrElse(DataType.STRUCT) in ArrayDatatypes) { if(value.value.size != struct!!.numberOfElements) return err("number of values is not the same as the number of members in the struct") for(elt in value.value.zip(struct.statements)) { diff --git a/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt b/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt index 8b87fda0b..41e27c767 100644 --- a/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt +++ b/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt @@ -225,22 +225,34 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi return super.visit(returnStmt) } + override fun visit(arrayLiteral: ArrayLiteralValue): Expression { val array = super.visit(arrayLiteral) if(array is ArrayLiteralValue) { val vardecl = array.parent as? VarDecl - return if(vardecl!=null) - fixupArrayEltDatatypesFromVardecl(array, vardecl) + // adjust the datatype of the array (to an educated guess) + if(vardecl!=null) { + val arrayDt = array.type + if(!arrayDt.istype(vardecl.datatype)) { + val cast = array.cast(vardecl.datatype) + if (cast != null) { + vardecl.value = cast + cast.linkParents(vardecl) + return cast + } + } + return array + } else { - // fix the datatype of the array (also on the heap) to the 'biggest' datatype in the array - // (we don't know the desired datatype here exactly so we guess) - val datatype = determineArrayDt(array.value) - val litval2 = array.cast(datatype) - if(litval2!=null) { - litval2.parent = array.parent - // finally, replace the literal array by a identifier reference. - makeIdentifierFromRefLv(litval2) - } else array + val arrayDt = array.guessDatatype(program) + if(arrayDt.isKnown) { + // this array literal is part of an expression, turn it into an identifier reference + val litval2 = array.cast(arrayDt.typeOrElse(DataType.STRUCT)) + return if (litval2 != null) { + litval2.parent = array.parent + makeIdentifierFromRefLv(litval2) + } else array + } } } return array @@ -261,20 +273,6 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi return string } - private fun determineArrayDt(array: Array): DataType { - val datatypesInArray = array.map { it.inferType(program) } - require(datatypesInArray.isNotEmpty() && datatypesInArray.all { it.isKnown }) { "can't determine type of empty array" } - val dts = datatypesInArray.map { it.typeOrElse(DataType.STRUCT) } - return when { - DataType.FLOAT in dts -> DataType.ARRAY_F - DataType.WORD in dts -> DataType.ARRAY_W - DataType.UWORD in dts -> DataType.ARRAY_UW - DataType.BYTE in dts -> DataType.ARRAY_B - DataType.UBYTE in dts -> DataType.ARRAY_UB - else -> throw IllegalArgumentException("can't determine type of array") - } - } - private fun makeIdentifierFromRefLv(array: ArrayLiteralValue): IdentifierReference { // a referencetype literal value that's not declared as a variable // we need to introduce an auto-generated variable for this to be able to refer to the value @@ -350,46 +348,3 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi } } - -internal fun fixupArrayEltDatatypes(array: ArrayLiteralValue, program: Program): ArrayLiteralValue { - val dts = array.value.map {it.inferType(program).typeOrElse(DataType.STRUCT)}.toSet() - if(dts.any { it !in NumericDatatypes }) { - return array - } - val dt = when { - DataType.FLOAT in dts -> DataType.ARRAY_F - DataType.WORD in dts -> DataType.ARRAY_W - DataType.UWORD in dts -> DataType.ARRAY_UW - DataType.BYTE in dts -> DataType.ARRAY_B - else -> DataType.ARRAY_UB - } - if(dt==array.type) - return array - - // convert values and array type - val elementType = ArrayElementTypes.getValue(dt) - val allNumerics = array.value.all { it is NumericLiteralValue } - if(allNumerics) { - val values = array.value.map { (it as NumericLiteralValue).cast(elementType) as Expression }.toTypedArray() - val array2 = ArrayLiteralValue(dt, values, array.position) - array2.linkParents(array.parent) - return array2 - } - - return array -} - -internal fun fixupArrayEltDatatypesFromVardecl(array: ArrayLiteralValue, vardecl: VarDecl): ArrayLiteralValue { - val arrayDt = array.type - if(arrayDt!=vardecl.datatype) { - // fix the datatype of the array (also on the heap) to match the vardecl - val cast = array.cast(vardecl.datatype) - if (cast != null) { - vardecl.value = cast - cast.linkParents(vardecl) - return cast - } - // can't be casted yet, attempt again later - } - return array -} diff --git a/compiler/src/prog8/ast/processing/VarInitValueAndAddressOfCreator.kt b/compiler/src/prog8/ast/processing/VarInitValueAndAddressOfCreator.kt index b71b6fb26..8e121d135 100644 --- a/compiler/src/prog8/ast/processing/VarInitValueAndAddressOfCreator.kt +++ b/compiler/src/prog8/ast/processing/VarInitValueAndAddressOfCreator.kt @@ -42,7 +42,7 @@ internal class VarInitValueAndAddressOfCreator(private val program: Program): IA if(decl.isArray && decl.value==null) { // array datatype without initialization value, add list of zeros val arraysize = decl.arraysize!!.size()!! - val array = ArrayLiteralValue(decl.datatype, + val array = ArrayLiteralValue(InferredTypes.InferredType.known(decl.datatype), Array(arraysize) { NumericLiteralValue.optimalInteger(0, decl.position) }, decl.position) decl.value = array diff --git a/compiler/src/prog8/ast/statements/AstStatements.kt b/compiler/src/prog8/ast/statements/AstStatements.kt index 7091d5641..92f19b4a9 100644 --- a/compiler/src/prog8/ast/statements/AstStatements.kt +++ b/compiler/src/prog8/ast/statements/AstStatements.kt @@ -199,7 +199,7 @@ class VarDecl(val type: VarDeclType, fun createAuto(array: ArrayLiteralValue): VarDecl { val autoVarName = "auto_heap_value_${++autoHeapValueSequenceNumber}" - val declaredType = ArrayElementTypes.getValue(array.type) + val declaredType = ArrayElementTypes.getValue(array.type.typeOrElse(DataType.STRUCT)) val arraysize = ArrayIndex.forArray(array) return VarDecl(VarDeclType.VAR, declaredType, ZeropageWish.NOT_IN_ZEROPAGE, arraysize, autoVarName, null, array, isArray = true, autogeneratedDontRemove = true, position = array.position) @@ -663,6 +663,12 @@ class ForLoop(val loopRegister: Register?, override fun toString(): String { return "ForLoop(loopVar: $loopVar, loopReg: $loopRegister, iterable: $iterable, pos=$position)" } + + fun loopVarDt(program: Program): InferredTypes.InferredType { + val lv = loopVar + return if(loopRegister!=null) InferredTypes.InferredType.known(DataType.UBYTE) + else lv?.inferType(program) ?: InferredTypes.InferredType.unknown() + } } class WhileLoop(var condition: Expression, diff --git a/compiler/src/prog8/optimizer/ConstantFolding.kt b/compiler/src/prog8/optimizer/ConstantFolding.kt index 7986ff5a5..01b7b506e 100644 --- a/compiler/src/prog8/optimizer/ConstantFolding.kt +++ b/compiler/src/prog8/optimizer/ConstantFolding.kt @@ -5,8 +5,6 @@ import prog8.ast.Program import prog8.ast.base.* import prog8.ast.expressions.* import prog8.ast.processing.IAstModifyingVisitor -import prog8.ast.processing.fixupArrayEltDatatypesFromVardecl -import prog8.ast.processing.fixupArrayEltDatatypes import prog8.ast.statements.* import prog8.compiler.target.CompilationTarget import prog8.functions.BuiltinFunctions @@ -76,11 +74,11 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor { if(constRange!=null) { val eltType = rangeExpr.inferType(program).typeOrElse(DataType.UBYTE) if(eltType in ByteDatatypes) { - decl.value = ArrayLiteralValue(decl.datatype, + decl.value = ArrayLiteralValue(InferredTypes.InferredType.known(decl.datatype), constRange.map { NumericLiteralValue(eltType, it.toShort(), decl.value!!.position) }.toTypedArray(), position = decl.value!!.position) } else { - decl.value = ArrayLiteralValue(decl.datatype, + decl.value = ArrayLiteralValue(InferredTypes.InferredType.known(decl.datatype), constRange.map { NumericLiteralValue(eltType, it, decl.value!!.position) }.toTypedArray(), position = decl.value!!.position) } @@ -116,7 +114,7 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor { } // create the array itself, filled with the fillvalue. val array = Array(size) {fillvalue}.map { NumericLiteralValue.optimalInteger(it, numericLv.position) as Expression}.toTypedArray() - val refValue = ArrayLiteralValue(decl.datatype, array, position = numericLv.position) + val refValue = ArrayLiteralValue(InferredTypes.InferredType.known(decl.datatype), array, position = numericLv.position) decl.value = refValue refValue.parent=decl optimizationsDone++ @@ -137,7 +135,7 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor { else { // create the array itself, filled with the fillvalue. val array = Array(size) {fillvalue}.map { NumericLiteralValue(DataType.FLOAT, it, litval.position) as Expression}.toTypedArray() - val refValue = ArrayLiteralValue(DataType.ARRAY_F, array, position = litval.position) + val refValue = ArrayLiteralValue(InferredTypes.InferredType.known(DataType.ARRAY_F), array, position = litval.position) decl.value = refValue refValue.parent=decl optimizationsDone++ @@ -629,14 +627,18 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor { } override fun visit(arrayLiteral: ArrayLiteralValue): Expression { + // because constant folding can result in arrays that are now suddenly capable + // of telling the type of all their elements (for instance, when they contained -2 which + // was a prefix expression earlier), we recalculate the array's datatype. val array = super.visit(arrayLiteral) if(array is ArrayLiteralValue) { - val vardecl = array.parent as? VarDecl - return if (vardecl!=null) { - fixupArrayEltDatatypesFromVardecl(array, vardecl) - } else { - // it's not an array associated with a vardecl, attempt to guess the data type from the array values - fixupArrayEltDatatypes(array, program) + if(array.type.isKnown) + return array + val arrayDt = array.guessDatatype(program) + if(arrayDt.isKnown) { + val newArray = arrayLiteral.cast(arrayDt.typeOrElse(DataType.STRUCT)) + if(newArray!=null) + return newArray } } return array diff --git a/compiler/src/prog8/optimizer/SimplifyExpressions.kt b/compiler/src/prog8/optimizer/SimplifyExpressions.kt index 89959c632..35cb18583 100644 --- a/compiler/src/prog8/optimizer/SimplifyExpressions.kt +++ b/compiler/src/prog8/optimizer/SimplifyExpressions.kt @@ -22,7 +22,7 @@ internal class SimplifyExpressions(private val program: Program) : IAstModifying override fun visit(assignment: Assignment): Statement { if (assignment.aug_op != null) - throw AstException("augmented assignments should have been converted to normal assignments before this optimizer") + throw AstException("augmented assignments should have been converted to normal assignments before this optimizer: $assignment") return super.visit(assignment) } diff --git a/compiler/src/prog8/optimizer/StatementOptimizer.kt b/compiler/src/prog8/optimizer/StatementOptimizer.kt index e6cb07c5e..d48d91461 100644 --- a/compiler/src/prog8/optimizer/StatementOptimizer.kt +++ b/compiler/src/prog8/optimizer/StatementOptimizer.kt @@ -424,7 +424,7 @@ internal class StatementOptimizer(private val program: Program) : IAstModifyingV override fun visit(assignment: Assignment): Statement { if(assignment.aug_op!=null) - throw AstException("augmented assignments should have been converted to normal assignments before this optimizer") + throw AstException("augmented assignments should have been converted to normal assignments before this optimizer: $assignment") if(assignment.target isSameAs assignment.value) { if(assignment.target.isNotMemory(program.namespace)) { diff --git a/compiler/src/prog8/vm/RuntimeValue.kt b/compiler/src/prog8/vm/RuntimeValue.kt index 0704514bb..a198456d1 100644 --- a/compiler/src/prog8/vm/RuntimeValue.kt +++ b/compiler/src/prog8/vm/RuntimeValue.kt @@ -603,9 +603,9 @@ open class RuntimeValueArray(type: DataType, val array: Array, val heapI companion object { fun fromLv(array: ArrayLiteralValue): RuntimeValueArray { - return if (array.type == DataType.ARRAY_F) { + return if (array.type.istype(DataType.ARRAY_F)) { val doubleArray = array.value.map { (it as NumericLiteralValue).number }.toTypedArray() - RuntimeValueArray(array.type, doubleArray, array.heapId) + RuntimeValueArray(DataType.ARRAY_F, doubleArray, array.heapId) } else { val resultArray = mutableListOf() for (elt in array.value.withIndex()) { @@ -615,7 +615,7 @@ open class RuntimeValueArray(type: DataType, val array: Array, val heapI resultArray.add((elt.hashCode())) // ...poor man's implementation of ADDRESSOF(array), it probably won't work very well } } - RuntimeValueArray(array.type, resultArray.toTypedArray(), array.heapId) + RuntimeValueArray(array.type.typeOrElse(DataType.STRUCT), resultArray.toTypedArray(), array.heapId) } } } diff --git a/compiler/test/LiteralValueTests.kt b/compiler/test/LiteralValueTests.kt index c8d8fbce4..b7192f6cd 100644 --- a/compiler/test/LiteralValueTests.kt +++ b/compiler/test/LiteralValueTests.kt @@ -5,6 +5,7 @@ import org.junit.jupiter.api.TestInstance import prog8.ast.base.DataType import prog8.ast.base.Position import prog8.ast.expressions.ArrayLiteralValue +import prog8.ast.expressions.InferredTypes import prog8.ast.expressions.NumericLiteralValue import prog8.ast.expressions.StringLiteralValue import kotlin.test.assertEquals @@ -96,9 +97,9 @@ class TestParserNumericLiteralValue { val lvTwoR = NumericLiteralValue(DataType.UBYTE, 2, dummyPos) val lvThreeR = NumericLiteralValue(DataType.UBYTE, 3, dummyPos) val lvFour= NumericLiteralValue(DataType.UBYTE, 4, dummyPos) - val lv1 = ArrayLiteralValue(DataType.ARRAY_UB, arrayOf(lvOne, lvTwo, lvThree), dummyPos) - val lv2 = ArrayLiteralValue(DataType.ARRAY_UB, arrayOf(lvOneR, lvTwoR, lvThreeR), dummyPos) - val lv3 = ArrayLiteralValue(DataType.ARRAY_UB, arrayOf(lvOneR, lvTwoR, lvFour), dummyPos) + val lv1 = ArrayLiteralValue(InferredTypes.InferredType.known(DataType.ARRAY_UB), arrayOf(lvOne, lvTwo, lvThree), dummyPos) + val lv2 = ArrayLiteralValue(InferredTypes.InferredType.known(DataType.ARRAY_UB), arrayOf(lvOneR, lvTwoR, lvThreeR), dummyPos) + val lv3 = ArrayLiteralValue(InferredTypes.InferredType.known(DataType.ARRAY_UB), arrayOf(lvOneR, lvTwoR, lvFour), dummyPos) assertEquals(lv1, lv2) assertNotEquals(lv1, lv3) } diff --git a/examples/test.p8 b/examples/test.p8 index bc7ebb60a..5d9b9ecbd 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -5,125 +5,7 @@ main { sub start() { - ubyte[] uba = [1,2,3] - byte[] bba = [1,2,3] - uword[] uwa = [1111,2222,3333] - word[] wwa = [1111,2222,3333] - - ubyte ub - byte bb - uword uw - word ww - - for ub in uba { - c64scr.print_ub(ub) - c64scr.print(",") - } - c64scr.print("\n") - for bb in bba { - c64scr.print_b(bb) - c64scr.print(",") - } - c64scr.print("\n") - for uw in uwa { - c64scr.print_uw(uw) - c64scr.print(",") - } - c64scr.print("\n") - for ww in wwa { - c64scr.print_w(ww) - c64scr.print(",") - } - c64scr.print("\n") - - for ub in [1,2,3] { - c64scr.print_ub(ub) - c64scr.print(",") - } -; c64scr.print("\n") -; for bb in [1,2,3] { ; TODO fix array literal conversion error -; c64scr.print_b(bb) -; c64scr.print(",") -; } - c64scr.print("\n") - for uw in [1111,2222,3333] { - c64scr.print_uw(uw) - c64scr.print(",") - } -; c64scr.print("\n") -; for ww in [1111,2222,3333] { ; TODO fix array literal conversion error -; c64scr.print_w(ww) -; c64scr.print(",") -; } - c64scr.print("\n") - - ubyte[] ubb1 = [ 1 ] - ubyte[] ubb2 = [ 1, 2] - ubyte[] ubb3 = [ 1,2,3 ] - ubyte[] ubb4 = [ 1,2,3,4 ] - uword[] uww1 = [111] - uword[] uww2 = [111,222] - uword[] uww3 = [111,222,333] - uword[] uww4 = [111,222,333,444] - - reverse(ubb1) - reverse(ubb2) - reverse(ubb3) - reverse(ubb4) - reverse(uww1) - reverse(uww2) - reverse(uww3) - reverse(uww4) - for ub in ubb1 { - c64scr.print_ub(ub) - c64scr.print(",") - } - c64scr.print("\n") - for ub in ubb2 { - c64scr.print_ub(ub) - c64scr.print(",") - } - c64scr.print("\n") - for ub in ubb3 { - c64scr.print_ub(ub) - c64scr.print(",") - } - c64scr.print("\n") - for ub in ubb4 { - c64scr.print_ub(ub) - c64scr.print(",") - } - c64scr.print("\n") - for uw in uww1 { - c64scr.print_uw(uw) - c64scr.print(",") - } - c64scr.print("\n") - for uw in uww2 { - c64scr.print_uw(uw) - c64scr.print(",") - } - c64scr.print("\n") - for uw in uww3 { - c64scr.print_uw(uw) - c64scr.print(",") - } - c64scr.print("\n") - for uw in uww4 { - c64scr.print_uw(uw) - c64scr.print(",") - } - c64scr.print("\n") - - float[] fa = [1.1, 2.2, 3.3, 4.4, 5.5] - reverse(fa) - sort(uww3) - sort(fa) - for ub in 0 to len(fa)-1 { - c64flt.print_f(fa[ub]) - c64scr.print(",") - } - c64scr.print("\n") + byte[] barr = [22,-33,-44,55,66] } } diff --git a/examples/testarrays.p8 b/examples/testarrays.p8 index 6bfad28e3..73b0939a3 100644 --- a/examples/testarrays.p8 +++ b/examples/testarrays.p8 @@ -12,7 +12,7 @@ main { return str s1 = "hello" - str s2 = "screencodes" ; TODO as c64sc + str s2 = @"screencodes" &str ms1 = $c000 diff --git a/examples/testforloops.p8 b/examples/testforloops.p8 index c7cddc393..bba3a77c7 100644 --- a/examples/testforloops.p8 +++ b/examples/testforloops.p8 @@ -414,7 +414,7 @@ main { count = 0 total = 0 c64scr.print("byte var in arrayliteral: ") - for bb in [1,3,5,99] { ; TODO now gives compiler error, fix byte var array literal conversion + for bb in [1,3,5,99] { count++ total += bb } @@ -790,7 +790,7 @@ main { count = 0 total = 0 c64scr.print("word var in arrayliteral: ") - for ww in [1111,3333,555,999] { ; TODO now compiler error, fix word var array literal conversion + for ww in [1111,3333,555,999] { count++ total += ww }