mirror of
https://github.com/irmen/prog8.git
synced 2024-11-29 17:50:35 +00:00
simplified heapId for arrayvalues
This commit is contained in:
parent
14a13da7ec
commit
11de3db25f
@ -435,12 +435,10 @@ class StringLiteralValue(val value: String,
|
|||||||
|
|
||||||
class ArrayLiteralValue(val type: DataType, // only array types
|
class ArrayLiteralValue(val type: DataType, // only array types
|
||||||
val value: Array<Expression>,
|
val value: Array<Expression>,
|
||||||
initHeapId: Int? =null,
|
|
||||||
override val position: Position) : Expression() {
|
override val position: Position) : Expression() {
|
||||||
override lateinit var parent: Node
|
override lateinit var parent: Node
|
||||||
|
|
||||||
var heapId = initHeapId
|
val heapId = ++heapIdSequence
|
||||||
private set
|
|
||||||
|
|
||||||
override fun linkParents(parent: Node) {
|
override fun linkParents(parent: Node) {
|
||||||
this.parent = parent
|
this.parent = parent
|
||||||
@ -468,9 +466,9 @@ class ArrayLiteralValue(val type: DataType, // only array types
|
|||||||
val castArray = value.map{
|
val castArray = value.map{
|
||||||
val num = it as? NumericLiteralValue
|
val num = it as? NumericLiteralValue
|
||||||
if(num==null) {
|
if(num==null) {
|
||||||
// an array of UWORDs could possibly also contain AddressOfs
|
// an array of UWORDs could possibly also contain AddressOfs, other stuff can't be casted
|
||||||
if (elementType != DataType.UWORD || it !is AddressOf)
|
if (elementType != DataType.UWORD || it !is AddressOf)
|
||||||
throw FatalAstException("weird array element $it")
|
return null
|
||||||
it
|
it
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
@ -484,11 +482,6 @@ class ArrayLiteralValue(val type: DataType, // only array types
|
|||||||
}
|
}
|
||||||
return null // invalid type conversion from $this to $targettype
|
return null // invalid type conversion from $this to $targettype
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addToHeap() {
|
|
||||||
if(heapId==null)
|
|
||||||
heapId = ++heapIdSequence
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class RangeExpr(var from: Expression,
|
class RangeExpr(var from: Expression,
|
||||||
@ -642,7 +635,7 @@ data class IdentifierReference(val nameInSource: List<String>, override val posi
|
|||||||
return when (value) {
|
return when (value) {
|
||||||
is IdentifierReference -> value.heapId(namespace)
|
is IdentifierReference -> value.heapId(namespace)
|
||||||
is StringLiteralValue -> value.heapId
|
is StringLiteralValue -> value.heapId
|
||||||
is ArrayLiteralValue -> value.heapId ?: throw FatalAstException("array is not on the heap: $value")
|
is ArrayLiteralValue -> value.heapId
|
||||||
else -> throw FatalAstException("requires a reference value")
|
else -> throw FatalAstException("requires a reference value")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -694,9 +694,6 @@ internal class AstChecker(private val program: Program,
|
|||||||
checkValueTypeAndRangeArray(array.type, null, arrayspec, array)
|
checkValueTypeAndRangeArray(array.type, null, arrayspec, array)
|
||||||
|
|
||||||
super.visit(array)
|
super.visit(array)
|
||||||
|
|
||||||
if(array.heapId==null && array.parent !is IFunctionCall)
|
|
||||||
throw FatalAstException("array should have been moved to heap at ${array.position}")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visit(string: StringLiteralValue) {
|
override fun visit(string: StringLiteralValue) {
|
||||||
@ -824,6 +821,7 @@ internal class AstChecker(private val program: Program,
|
|||||||
if(targetStatement!=null)
|
if(targetStatement!=null)
|
||||||
checkFunctionCall(targetStatement, functionCallStatement.args, functionCallStatement.position)
|
checkFunctionCall(targetStatement, functionCallStatement.args, functionCallStatement.position)
|
||||||
if(targetStatement is Subroutine && targetStatement.returntypes.isNotEmpty()) {
|
if(targetStatement is Subroutine && targetStatement.returntypes.isNotEmpty()) {
|
||||||
|
// TODO add 'void' keyword to make this explicit
|
||||||
if(targetStatement.returntypes.size==1)
|
if(targetStatement.returntypes.size==1)
|
||||||
printWarning("result value of subroutine call is discarded", functionCallStatement.position)
|
printWarning("result value of subroutine call is discarded", functionCallStatement.position)
|
||||||
else
|
else
|
||||||
@ -1198,31 +1196,6 @@ internal class AstChecker(private val program: Program,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkArrayValues(value: ArrayLiteralValue, type: DataType): Boolean {
|
private fun checkArrayValues(value: ArrayLiteralValue, type: DataType): Boolean {
|
||||||
if (value.heapId == null) {
|
|
||||||
// hmm weird, array literal that hasn't been moved to the heap yet?
|
|
||||||
val array = value.value.mapNotNull { it.constValue(program) }
|
|
||||||
val correct: Boolean
|
|
||||||
when (type) {
|
|
||||||
DataType.ARRAY_UB -> {
|
|
||||||
correct = array.all { it.type == DataType.UBYTE && it.number.toInt() in 0..255 }
|
|
||||||
}
|
|
||||||
DataType.ARRAY_B -> {
|
|
||||||
correct = array.all { it.type == DataType.BYTE && it.number.toInt() in -128..127 }
|
|
||||||
}
|
|
||||||
DataType.ARRAY_UW -> {
|
|
||||||
correct = array.all { it.type == DataType.UWORD && it.number.toInt() in 0..65535 }
|
|
||||||
}
|
|
||||||
DataType.ARRAY_W -> {
|
|
||||||
correct = array.all { it.type == DataType.WORD && it.number.toInt() in -32768..32767 }
|
|
||||||
}
|
|
||||||
DataType.ARRAY_F -> correct = true
|
|
||||||
else -> throw AstException("invalid array type $type")
|
|
||||||
}
|
|
||||||
if (!correct)
|
|
||||||
checkResult.add(ExpressionError("array value out of range for type $type", value.position))
|
|
||||||
return correct
|
|
||||||
}
|
|
||||||
|
|
||||||
val array = value.value.map {
|
val array = value.value.map {
|
||||||
when (it) {
|
when (it) {
|
||||||
is NumericLiteralValue -> it.number.toInt()
|
is NumericLiteralValue -> it.number.toInt()
|
||||||
|
@ -229,18 +229,16 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi
|
|||||||
val array = super.visit(arrayLiteral)
|
val array = super.visit(arrayLiteral)
|
||||||
if(array is ArrayLiteralValue) {
|
if(array is ArrayLiteralValue) {
|
||||||
val vardecl = array.parent as? VarDecl
|
val vardecl = array.parent as? VarDecl
|
||||||
return when {
|
return if(vardecl!=null)
|
||||||
vardecl!=null -> fixupArrayDatatype(array, vardecl, program)
|
fixupArrayEltDatatypesFromVardecl(array, vardecl)
|
||||||
array.heapId!=null -> {
|
else {
|
||||||
// fix the datatype of the array (also on the heap) to the 'biggest' datatype in the array
|
// 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)
|
// (we don't know the desired datatype here exactly so we guess)
|
||||||
val datatype = determineArrayDt(array.value)
|
val datatype = determineArrayDt(array.value)
|
||||||
val litval2 = array.cast(datatype)!!
|
val litval2 = array.cast(datatype)!!
|
||||||
litval2.parent = array.parent
|
litval2.parent = array.parent
|
||||||
// finally, replace the literal array by a identifier reference.
|
// finally, replace the literal array by a identifier reference.
|
||||||
makeIdentifierFromRefLv(litval2)
|
makeIdentifierFromRefLv(litval2)
|
||||||
}
|
|
||||||
else -> array
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return array
|
return array
|
||||||
@ -279,7 +277,6 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi
|
|||||||
// a referencetype literal value that's not declared as a variable
|
// 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
|
// we need to introduce an auto-generated variable for this to be able to refer to the value
|
||||||
// note: if the var references the same literal value, it is not yet de-duplicated here.
|
// note: if the var references the same literal value, it is not yet de-duplicated here.
|
||||||
array.addToHeap()
|
|
||||||
val scope = array.definingScope()
|
val scope = array.definingScope()
|
||||||
val variable = VarDecl.createAuto(array)
|
val variable = VarDecl.createAuto(array)
|
||||||
return replaceWithIdentifier(variable, scope, array.parent)
|
return replaceWithIdentifier(variable, scope, array.parent)
|
||||||
@ -352,7 +349,7 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun fixupArrayDatatype(array: ArrayLiteralValue, program: Program): ArrayLiteralValue {
|
internal fun fixupArrayEltDatatypes(array: ArrayLiteralValue, program: Program): ArrayLiteralValue {
|
||||||
val dts = array.value.map {it.inferType(program).typeOrElse(DataType.STRUCT)}.toSet()
|
val dts = array.value.map {it.inferType(program).typeOrElse(DataType.STRUCT)}.toSet()
|
||||||
if(dts.any { it !in NumericDatatypes }) {
|
if(dts.any { it !in NumericDatatypes }) {
|
||||||
return array
|
return array
|
||||||
@ -370,50 +367,22 @@ internal fun fixupArrayDatatype(array: ArrayLiteralValue, program: Program): Arr
|
|||||||
// convert values and array type
|
// convert values and array type
|
||||||
val elementType = ArrayElementTypes.getValue(dt)
|
val elementType = ArrayElementTypes.getValue(dt)
|
||||||
val values = array.value.map { (it as NumericLiteralValue).cast(elementType) as Expression}.toTypedArray()
|
val values = array.value.map { (it as NumericLiteralValue).cast(elementType) as Expression}.toTypedArray()
|
||||||
val array2 = ArrayLiteralValue(dt, values, array.heapId, array.position)
|
val array2 = ArrayLiteralValue(dt, values, array.position)
|
||||||
array2.linkParents(array.parent)
|
array2.linkParents(array.parent)
|
||||||
return array2
|
return array2
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun fixupArrayDatatype(array: ArrayLiteralValue, vardecl: VarDecl, program: Program): ArrayLiteralValue {
|
internal fun fixupArrayEltDatatypesFromVardecl(array: ArrayLiteralValue, vardecl: VarDecl): ArrayLiteralValue {
|
||||||
if(array.heapId!=null) {
|
val arrayDt = array.type
|
||||||
val arrayDt = array.type
|
if(arrayDt!=vardecl.datatype) {
|
||||||
if(arrayDt!=vardecl.datatype) {
|
// fix the datatype of the array (also on the heap) to match the vardecl
|
||||||
// fix the datatype of the array (also on the heap) to match the vardecl
|
val cast = array.cast(vardecl.datatype)
|
||||||
val litval2 =
|
if (cast != null) {
|
||||||
try {
|
vardecl.value = cast
|
||||||
val result = array.cast(vardecl.datatype)
|
cast.linkParents(vardecl)
|
||||||
if(result==null) {
|
return cast
|
||||||
val constElements = array.value.mapNotNull { it.constValue(program) }
|
|
||||||
val elementDts = constElements.map { it.type }
|
|
||||||
if(DataType.FLOAT in elementDts) {
|
|
||||||
array.cast(DataType.ARRAY_F) ?: ArrayLiteralValue(DataType.ARRAY_F, array.value, array.heapId, array.position)
|
|
||||||
} else {
|
|
||||||
val numbers = constElements.map { it.number.toInt() }
|
|
||||||
val minValue = numbers.min()!!
|
|
||||||
val maxValue = numbers.max()!!
|
|
||||||
if (minValue >= 0) {
|
|
||||||
// only positive values, so uword or ubyte
|
|
||||||
val dt = if(maxValue<256) DataType.ARRAY_UB else DataType.ARRAY_UW
|
|
||||||
array.cast(dt) ?: ArrayLiteralValue(dt, array.value, array.heapId, array.position)
|
|
||||||
} else {
|
|
||||||
// negative value present, so word or byte
|
|
||||||
val dt = if(minValue >= -128 && maxValue<=127) DataType.ARRAY_B else DataType.ARRAY_W
|
|
||||||
array.cast(dt) ?: ArrayLiteralValue(dt, array.value, array.heapId, array.position)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else result
|
|
||||||
} catch(x: ExpressionError) {
|
|
||||||
// couldn't cast permanently.
|
|
||||||
// instead, simply adjust the array type and trust the AstChecker to report the exact error
|
|
||||||
ArrayLiteralValue(vardecl.datatype, array.value, array.heapId, array.position)
|
|
||||||
}
|
|
||||||
vardecl.value = litval2
|
|
||||||
litval2.linkParents(vardecl)
|
|
||||||
litval2.addToHeap()
|
|
||||||
return litval2
|
|
||||||
}
|
}
|
||||||
|
// can't be casted yet, attempt again later
|
||||||
}
|
}
|
||||||
return array
|
return array
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,7 @@ internal class VarInitValueAndAddressOfCreator(private val program: Program): IA
|
|||||||
val arraysize = decl.arraysize!!.size()!!
|
val arraysize = decl.arraysize!!.size()!!
|
||||||
val array = ArrayLiteralValue(decl.datatype,
|
val array = ArrayLiteralValue(decl.datatype,
|
||||||
Array(arraysize) { NumericLiteralValue.optimalInteger(0, decl.position) },
|
Array(arraysize) { NumericLiteralValue.optimalInteger(0, decl.position) },
|
||||||
null, decl.position)
|
decl.position)
|
||||||
array.addToHeap()
|
|
||||||
decl.value = array
|
decl.value = array
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,9 +198,6 @@ class VarDecl(val type: VarDeclType,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun createAuto(array: ArrayLiteralValue): VarDecl {
|
fun createAuto(array: ArrayLiteralValue): VarDecl {
|
||||||
if(array.heapId==null)
|
|
||||||
throw FatalAstException("can only create autovar for an array that has a heapid $array")
|
|
||||||
|
|
||||||
val autoVarName = "auto_heap_value_${++autoHeapValueSequenceNumber}"
|
val autoVarName = "auto_heap_value_${++autoHeapValueSequenceNumber}"
|
||||||
val declaredType = ArrayElementTypes.getValue(array.type)
|
val declaredType = ArrayElementTypes.getValue(array.type)
|
||||||
val arraysize = ArrayIndex.forArray(array)
|
val arraysize = ArrayIndex.forArray(array)
|
||||||
|
@ -5,7 +5,8 @@ import prog8.ast.Program
|
|||||||
import prog8.ast.base.*
|
import prog8.ast.base.*
|
||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
import prog8.ast.processing.IAstModifyingVisitor
|
import prog8.ast.processing.IAstModifyingVisitor
|
||||||
import prog8.ast.processing.fixupArrayDatatype
|
import prog8.ast.processing.fixupArrayEltDatatypesFromVardecl
|
||||||
|
import prog8.ast.processing.fixupArrayEltDatatypes
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.compiler.target.CompilationTarget
|
import prog8.compiler.target.CompilationTarget
|
||||||
import prog8.functions.BuiltinFunctions
|
import prog8.functions.BuiltinFunctions
|
||||||
@ -116,7 +117,6 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor {
|
|||||||
// create the array itself, filled with the fillvalue.
|
// create the array itself, filled with the fillvalue.
|
||||||
val array = Array(size) {fillvalue}.map { NumericLiteralValue.optimalInteger(it, numericLv.position) as Expression}.toTypedArray()
|
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(decl.datatype, array, position = numericLv.position)
|
||||||
refValue.addToHeap()
|
|
||||||
decl.value = refValue
|
decl.value = refValue
|
||||||
refValue.parent=decl
|
refValue.parent=decl
|
||||||
optimizationsDone++
|
optimizationsDone++
|
||||||
@ -138,7 +138,6 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor {
|
|||||||
// create the array itself, filled with the fillvalue.
|
// create the array itself, filled with the fillvalue.
|
||||||
val array = Array(size) {fillvalue}.map { NumericLiteralValue(DataType.FLOAT, it, litval.position) as Expression}.toTypedArray()
|
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(DataType.ARRAY_F, array, position = litval.position)
|
||||||
refValue.addToHeap()
|
|
||||||
decl.value = refValue
|
decl.value = refValue
|
||||||
refValue.parent=decl
|
refValue.parent=decl
|
||||||
optimizationsDone++
|
optimizationsDone++
|
||||||
@ -586,7 +585,6 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor {
|
|||||||
if(array2!=null && array2!==array) {
|
if(array2!=null && array2!==array) {
|
||||||
forLoop2.iterable = array2
|
forLoop2.iterable = array2
|
||||||
array2.linkParents(forLoop2)
|
array2.linkParents(forLoop2)
|
||||||
array2.addToHeap()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -633,13 +631,12 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor {
|
|||||||
override fun visit(arrayLiteral: ArrayLiteralValue): Expression {
|
override fun visit(arrayLiteral: ArrayLiteralValue): Expression {
|
||||||
val array = super.visit(arrayLiteral)
|
val array = super.visit(arrayLiteral)
|
||||||
if(array is ArrayLiteralValue) {
|
if(array is ArrayLiteralValue) {
|
||||||
array.addToHeap()
|
|
||||||
val vardecl = array.parent as? VarDecl
|
val vardecl = array.parent as? VarDecl
|
||||||
return if (vardecl!=null) {
|
return if (vardecl!=null) {
|
||||||
fixupArrayDatatype(array, vardecl, program)
|
fixupArrayEltDatatypesFromVardecl(array, vardecl)
|
||||||
} else {
|
} else {
|
||||||
// it's not an array associated with a vardecl, attempt to guess the data type from the array values
|
// it's not an array associated with a vardecl, attempt to guess the data type from the array values
|
||||||
fixupArrayDatatype(array, program)
|
fixupArrayEltDatatypes(array, program)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return array
|
return array
|
||||||
|
@ -261,7 +261,7 @@ internal class StatementOptimizer(private val program: Program) : IAstModifyingV
|
|||||||
if(constvalue!=null) {
|
if(constvalue!=null) {
|
||||||
return if(constvalue.asBooleanValue){
|
return if(constvalue.asBooleanValue){
|
||||||
// always true -> keep only if-part
|
// always true -> keep only if-part
|
||||||
printWarning("condition is always true", ifStatement.position)
|
printWarning("condition is always true", ifStatement.position) // TODO don't warn this if the condition is just the single value 'true'
|
||||||
optimizationsDone++
|
optimizationsDone++
|
||||||
ifStatement.truepart
|
ifStatement.truepart
|
||||||
} else {
|
} else {
|
||||||
@ -310,7 +310,7 @@ internal class StatementOptimizer(private val program: Program) : IAstModifyingV
|
|||||||
if(constvalue!=null) {
|
if(constvalue!=null) {
|
||||||
return if(constvalue.asBooleanValue){
|
return if(constvalue.asBooleanValue){
|
||||||
// always true -> print a warning, and optimize into body + jump (if there are no continue and break statements)
|
// always true -> print a warning, and optimize into body + jump (if there are no continue and break statements)
|
||||||
printWarning("condition is always true", whileLoop.position)
|
printWarning("condition is always true", whileLoop.position) // TODO don't warn this if the condition is just the single value 'true'
|
||||||
if(hasContinueOrBreak(whileLoop.body))
|
if(hasContinueOrBreak(whileLoop.body))
|
||||||
return whileLoop
|
return whileLoop
|
||||||
val label = Label("_prog8_back", whileLoop.condition.position)
|
val label = Label("_prog8_back", whileLoop.condition.position)
|
||||||
@ -336,7 +336,7 @@ internal class StatementOptimizer(private val program: Program) : IAstModifyingV
|
|||||||
if(constvalue!=null) {
|
if(constvalue!=null) {
|
||||||
return if(constvalue.asBooleanValue){
|
return if(constvalue.asBooleanValue){
|
||||||
// always true -> keep only the statement block (if there are no continue and break statements)
|
// always true -> keep only the statement block (if there are no continue and break statements)
|
||||||
printWarning("condition is always true", repeatLoop.position)
|
printWarning("condition is always true", repeatLoop.position) // TODO don't warn this if the condition is just the single value 'true'
|
||||||
if(hasContinueOrBreak(repeatLoop.body))
|
if(hasContinueOrBreak(repeatLoop.body))
|
||||||
repeatLoop
|
repeatLoop
|
||||||
else {
|
else {
|
||||||
|
@ -605,7 +605,7 @@ open class RuntimeValueArray(type: DataType, val array: Array<Number>, val heapI
|
|||||||
fun fromLv(array: ArrayLiteralValue): RuntimeValueArray {
|
fun fromLv(array: ArrayLiteralValue): RuntimeValueArray {
|
||||||
return if (array.type == DataType.ARRAY_F) {
|
return if (array.type == DataType.ARRAY_F) {
|
||||||
val doubleArray = array.value.map { (it as NumericLiteralValue).number }.toTypedArray()
|
val doubleArray = array.value.map { (it as NumericLiteralValue).number }.toTypedArray()
|
||||||
RuntimeValueArray(array.type, doubleArray, array.heapId!!)
|
RuntimeValueArray(array.type, doubleArray, array.heapId)
|
||||||
} else {
|
} else {
|
||||||
val resultArray = mutableListOf<Number>()
|
val resultArray = mutableListOf<Number>()
|
||||||
for (elt in array.value.withIndex()) {
|
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
|
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, resultArray.toTypedArray(), array.heapId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,9 +93,9 @@ class TestParserNumericLiteralValue {
|
|||||||
val lvTwoR = NumericLiteralValue(DataType.UBYTE, 2, dummyPos)
|
val lvTwoR = NumericLiteralValue(DataType.UBYTE, 2, dummyPos)
|
||||||
val lvThreeR = NumericLiteralValue(DataType.UBYTE, 3, dummyPos)
|
val lvThreeR = NumericLiteralValue(DataType.UBYTE, 3, dummyPos)
|
||||||
val lvFour= NumericLiteralValue(DataType.UBYTE, 4, dummyPos)
|
val lvFour= NumericLiteralValue(DataType.UBYTE, 4, dummyPos)
|
||||||
val lv1 = ArrayLiteralValue(DataType.ARRAY_UB, arrayOf(lvOne, lvTwo, lvThree), null, dummyPos)
|
val lv1 = ArrayLiteralValue(DataType.ARRAY_UB, arrayOf(lvOne, lvTwo, lvThree), dummyPos)
|
||||||
val lv2 = ArrayLiteralValue(DataType.ARRAY_UB, arrayOf(lvOneR, lvTwoR, lvThreeR), null, dummyPos)
|
val lv2 = ArrayLiteralValue(DataType.ARRAY_UB, arrayOf(lvOneR, lvTwoR, lvThreeR), dummyPos)
|
||||||
val lv3 = ArrayLiteralValue(DataType.ARRAY_UB, arrayOf(lvOneR, lvTwoR, lvFour), null, dummyPos)
|
val lv3 = ArrayLiteralValue(DataType.ARRAY_UB, arrayOf(lvOneR, lvTwoR, lvFour), dummyPos)
|
||||||
assertEquals(lv1, lv2)
|
assertEquals(lv1, lv2)
|
||||||
assertNotEquals(lv1, lv3)
|
assertNotEquals(lv1, lv3)
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,8 @@ main {
|
|||||||
|
|
||||||
c64.VMCSB |= 2 ; switch to lowercase charset
|
c64.VMCSB |= 2 ; switch to lowercase charset
|
||||||
|
|
||||||
str s1 = "HELLO hello 1234 @[/]\n"
|
str s1 = "HELLO hello 1234 @[/]\n" ; regular strings have default encoding (petscii on c64)
|
||||||
str s2 = c64scr("HELLO hello 1234 @[/]\n")
|
str s2 = @"HELLO hello 1234 @[/]\n" ; TODO @-strings for alternate encoding (screencode on c64)
|
||||||
|
|
||||||
c64scr.print("\n\n\n\nString output via print:\n")
|
c64scr.print("\n\n\n\nString output via print:\n")
|
||||||
c64scr.print(s1)
|
c64scr.print(s1)
|
||||||
|
Loading…
Reference in New Issue
Block a user