diff --git a/compiler/src/prog8/ast/expressions/AstExpressions.kt b/compiler/src/prog8/ast/expressions/AstExpressions.kt index 4d44680e3..4a78e07a1 100644 --- a/compiler/src/prog8/ast/expressions/AstExpressions.kt +++ b/compiler/src/prog8/ast/expressions/AstExpressions.kt @@ -524,7 +524,7 @@ class ReferenceLiteralValue(val type: DataType, // only reference types allo in ArrayDatatypes -> "$array" else -> throw FatalAstException("weird ref type") } - return "ReferenceValueLiteral($type, $valueStr)" + return "RefValueLit($type, $valueStr)" } override fun inferType(program: Program) = type @@ -559,7 +559,14 @@ class ReferenceLiteralValue(val type: DataType, // only reference types allo when(type) { in StringDatatypes -> { if(targettype in StringDatatypes) - return ReferenceLiteralValue(targettype, str, initHeapId = heapId, position = position) + return ReferenceLiteralValue(targettype, str, position = position) + } + in ArrayDatatypes -> { + if(targettype in ArrayDatatypes) { + val elementType = ArrayElementTypes.getValue(targettype) + val castArray = array!!.map{ (it as NumericLiteralValue).cast(elementType)!! as Expression }.toTypedArray() + return ReferenceLiteralValue(targettype, null, array=castArray, position = position) + } } else -> {} } diff --git a/compiler/src/prog8/ast/processing/AstChecker.kt b/compiler/src/prog8/ast/processing/AstChecker.kt index ff8a7e432..ba1ab217f 100644 --- a/compiler/src/prog8/ast/processing/AstChecker.kt +++ b/compiler/src/prog8/ast/processing/AstChecker.kt @@ -1033,6 +1033,7 @@ internal class AstChecker(private val program: Program, } return err("invalid word array size, must be 1-128") } + TODO("${value.position}") return err("invalid word array initialization value ${value.type}, expected $targetDt") } DataType.ARRAY_F -> { diff --git a/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt b/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt index 3507624f4..c1069ecbd 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt @@ -10,6 +10,7 @@ import prog8.ast.statements.* import prog8.compiler.* import prog8.compiler.target.c64.AssemblyProgram import prog8.compiler.target.c64.MachineDefinition +import prog8.compiler.target.c64.MachineDefinition.C64Zeropage import prog8.compiler.target.c64.MachineDefinition.ESTACK_HI_HEX import prog8.compiler.target.c64.MachineDefinition.ESTACK_HI_PLUS1_HEX import prog8.compiler.target.c64.MachineDefinition.ESTACK_LO_HEX @@ -18,8 +19,6 @@ import prog8.functions.BuiltinFunctions import java.io.File import java.math.RoundingMode import java.util.* -import kotlin.math.PI -import kotlin.math.E import kotlin.math.absoluteValue @@ -961,7 +960,7 @@ internal class AsmGen2(val program: Program, private fun translateExpression(expr: RegisterExpr) { when(expr.register) { Register.A -> out(" sta $ESTACK_LO_HEX,x | dex") - Register.X -> throw AssemblyError("cannot push X") + Register.X -> throw AssemblyError("cannot push X - use a variable instead of the X register") Register.Y -> out(" tya | sta $ESTACK_LO_HEX,x | dex") } } diff --git a/compiler/src/prog8/optimizer/ConstantFolding.kt b/compiler/src/prog8/optimizer/ConstantFolding.kt index 46f862d0b..29746f75b 100644 --- a/compiler/src/prog8/optimizer/ConstantFolding.kt +++ b/compiler/src/prog8/optimizer/ConstantFolding.kt @@ -6,7 +6,6 @@ import prog8.ast.base.* import prog8.ast.expressions.* import prog8.ast.processing.IAstModifyingVisitor import prog8.ast.statements.* -import prog8.compiler.HeapValues import prog8.compiler.IntegerOrAddressOf import prog8.compiler.target.c64.MachineDefinition.FLOAT_MAX_NEGATIVE import prog8.compiler.target.c64.MachineDefinition.FLOAT_MAX_POSITIVE @@ -35,10 +34,6 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor { } if(decl.type==VarDeclType.CONST || decl.type==VarDeclType.VAR) { - val refLv = decl.value as? ReferenceLiteralValue - if(refLv!=null && refLv.isArray && refLv.heapId!=null) - fixupArrayTypeOnHeap(decl, refLv) - if(decl.isArray){ // for arrays that have no size specifier (or a non-constant one) attempt to deduce the size if(decl.arraysize==null) { @@ -155,37 +150,26 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor { } } - return super.visit(decl) - } + //TODO ??? +// val decl2 = super.visit(decl) as VarDecl +// if(decl2.isArray) { +// val refvalue = decl2.value as? ReferenceLiteralValue +// if(refvalue!=null) { +// if (refvalue.isArray && refvalue.type!=decl2.datatype) { +// // fix the datatype of +// println("DECL ${decl2.datatype} - ${refvalue.type} - $array") +// } +// } +// } - private fun fixupArrayTypeOnHeap(decl: VarDecl, litval: ReferenceLiteralValue) { - // fix the type of the array value that's on the heap, to match the vardecl. - // notice that checking the bounds of the actual values is not done here, but in the AstChecker later. - - if(decl.datatype==litval.type) - return // already correct datatype - val heapId = litval.heapId ?: throw FatalAstException("expected array to be on heap $litval") - val array = program.heap.get(heapId) - when(decl.datatype) { - DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W -> { - if(array.array!=null) { - program.heap.update(heapId, HeapValues.HeapValue(decl.datatype, null, array.array, null)) - decl.value = ReferenceLiteralValue(decl.datatype, initHeapId = heapId, position = litval.position) - } + if(decl.isArray) { + val refvalue = decl.value as? ReferenceLiteralValue + if(refvalue!=null) { + println("VISIT DECL ${decl.position} ${decl.datatype} -> ${refvalue.type}") } - DataType.ARRAY_F -> { - if(array.array!=null) { - // convert a non-float array to floats - val doubleArray = array.array.map { it.integer!!.toDouble() }.toDoubleArray() - program.heap.update(heapId, HeapValues.HeapValue(DataType.ARRAY_F, null, null, doubleArray)) - decl.value = ReferenceLiteralValue(decl.datatype, initHeapId = heapId, position = litval.position) - } - } - DataType.STRUCT -> { - // leave it alone for structs. - } - else -> throw FatalAstException("invalid array vardecl type ${decl.datatype}") } + + return super.visit(decl) } /** @@ -611,59 +595,29 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor { if (litval.str!!.length !in 1..255) addError(ExpressionError("string literal length must be between 1 and 255", litval.position)) else { - litval.addToHeap(program.heap) // TODO: we don't know the actual string type yet, STR != STR_S etc... + litval.addToHeap(program.heap) } } else if (litval.isArray) { - // first, adjust the array datatype - val litval2 = adjustArrayValDatatype(litval) - litval2.addToHeap(program.heap) - return litval2 - } - } - return litval - } - - private fun adjustArrayValDatatype(litval: ReferenceLiteralValue): ReferenceLiteralValue { - if(litval.array==null) { - if(litval.heapId!=null) - return litval // thing is already on the heap, assume it's the right type - throw FatalAstException("missing array value") - } - - val typesInArray = litval.array.mapNotNull { it.inferType(program) }.toSet() - val arrayDt = - when { - litval.array.any { it is AddressOf } -> DataType.ARRAY_UW - DataType.FLOAT in typesInArray -> DataType.ARRAY_F - DataType.WORD in typesInArray -> DataType.ARRAY_W - else -> { - val allElementsAreConstantOrAddressOf = litval.array.fold(true) { c, expr-> c and (expr is NumericLiteralValue|| expr is AddressOf)} - if(!allElementsAreConstantOrAddressOf) { - addError(ExpressionError("array literal can only consist of constant primitive numerical values or memory pointers", litval.position)) - return litval - } else { - val integerArray = litval.array.map { it.constValue(program)!!.number.toInt() } - val maxValue = integerArray.max()!! - val minValue = integerArray.min()!! - if (minValue >= 0) { - // unsigned - if (maxValue <= 255) - DataType.ARRAY_UB - else - DataType.ARRAY_UW - } else { - // signed - if (maxValue <= 127) - DataType.ARRAY_B - else - DataType.ARRAY_W - } + val vardecl = litval.parent as? VarDecl + if (vardecl!=null) { + if(litval.heapId!=null) { + val arrayDt = litval.type + if(arrayDt!=vardecl.datatype) { + // fix the datatype of the array (also on the heap) to match the vardecl + val litval2 = litval.cast(vardecl.datatype)!! + vardecl.value = litval2 + litval2.linkParents(vardecl) + litval2.addToHeap(program.heap) // TODO is the previous array discarded from the resulting asm code? + return litval2 } } + } else { + TODO("VISIT REFLITERAL OUTSIDE OF VARDECL $litval") } - if(arrayDt!=litval.type) { - return ReferenceLiteralValue(arrayDt, array = litval.array, position = litval.position) + if(litval.heapId==null) + litval.addToHeap(program.heap) + } } return litval } diff --git a/compiler/src/prog8/vm/astvm/AstVm.kt b/compiler/src/prog8/vm/astvm/AstVm.kt index bdd5e1cb3..4428e9cc1 100644 --- a/compiler/src/prog8/vm/astvm/AstVm.kt +++ b/compiler/src/prog8/vm/astvm/AstVm.kt @@ -731,7 +731,7 @@ class AstVm(val program: Program) { result = RuntimeValue(DataType.UBYTE, paddedStr.indexOf('\u0000')) } "c64flt.print_f" -> { - dialog.canvas.printText(args[0].floatval.toString(), true) + dialog.canvas.printText(args[0].floatval.toString(), false) } "c64.CHROUT" -> { dialog.canvas.printPetscii(args[0].byteval!!)