mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
improved array literal datatype handling, fixed some datatype compiler errors related to this
This commit is contained in:
parent
fbecedaf41
commit
5f1ec80ae0
@ -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() }
|
||||
|
@ -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)
|
||||
|
@ -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<Expression>,
|
||||
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
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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<Expression>): 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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -603,9 +603,9 @@ open class RuntimeValueArray(type: DataType, val array: Array<Number>, 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<Number>()
|
||||
for (elt in array.value.withIndex()) {
|
||||
@ -615,7 +615,7 @@ open class RuntimeValueArray(type: DataType, val array: Array<Number>, 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
120
examples/test.p8
120
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]
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ main {
|
||||
return
|
||||
|
||||
str s1 = "hello"
|
||||
str s2 = "screencodes" ; TODO as c64sc
|
||||
str s2 = @"screencodes"
|
||||
|
||||
&str ms1 = $c000
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user