fix compilation errors

This commit is contained in:
Irmen de Jong 2019-07-30 02:26:30 +02:00
parent fba149ee28
commit 3732ab1e62
6 changed files with 45 additions and 83 deletions

View File

@ -440,7 +440,7 @@ private fun prog8Parser.ExpressionContext.toAst() : Expression {
litval.arrayliteral()!=null -> {
val array = litval.arrayliteral()?.toAst()
// the actual type of the arraysize can not yet be determined here (missing namespace & heap)
// the ConstantFolder takes care of that and converts the type if needed.
// the ConstantFold takes care of that and converts the type if needed.
ReferenceLiteralValue(DataType.ARRAY_UB, array = array, position = litval.toPosition())
}
litval.structliteral()!=null -> {

View File

@ -367,6 +367,7 @@ class NumericLiteralValue(val type: DataType, // only numerical types allowed
in 0..255 -> NumericLiteralValue(DataType.UBYTE, value, position)
in -128..127 -> NumericLiteralValue(DataType.BYTE, value, position)
in 0..65535 -> NumericLiteralValue(DataType.UWORD, value, position)
in -32768..32767 -> NumericLiteralValue(DataType.WORD, value, position)
else -> throw FatalAstException("integer overflow: $value")
}
}
@ -495,12 +496,12 @@ class ReferenceLiteralValue(val type: DataType, // only reference types allo
init {
when(type){
in StringDatatypes ->
if(str==null && heapId==null) throw FatalAstException("literal value missing strvalue/heapId")
if(str==null) throw FatalAstException("literal value missing strvalue/heapId")
in ArrayDatatypes ->
if(array==null && heapId==null) throw FatalAstException("literal value missing arrayvalue/heapId")
if(array==null) throw FatalAstException("literal value missing arrayvalue/heapId")
else -> throw FatalAstException("invalid type $type")
}
if(array==null && str==null && heapId==null)
if(array==null && str==null)
throw FatalAstException("literal ref value without actual value")
}
@ -564,7 +565,17 @@ class ReferenceLiteralValue(val type: DataType, // only reference types allo
in ArrayDatatypes -> {
if(targettype in ArrayDatatypes) {
val elementType = ArrayElementTypes.getValue(targettype)
val castArray = array!!.map{ (it as NumericLiteralValue).cast(elementType)!! as Expression }.toTypedArray()
val castArray = array!!.map{
val num = it as? NumericLiteralValue
if(num==null) {
// an array of UWORDs could possibly also contain AddressOfs
if (elementType != DataType.UWORD || it !is AddressOf)
throw FatalAstException("weird array element $it")
it
} else {
num.cast(elementType)!!
}
}.toTypedArray()
return ReferenceLiteralValue(targettype, null, array=castArray, position = position)
}
}

View File

@ -61,7 +61,7 @@ fun compileProgram(filepath: Path,
programAst.removeNopsFlattenAnonScopes()
// if you want to print the AST, do it before shuffling the statements around below
printAst(programAst)
// printAst(programAst)
programAst.reorderStatements() // reorder statements and add type casts, to please the compiler later

View File

@ -294,7 +294,9 @@ internal class AsmGen2(val program: Program,
}
}
DataType.ARRAY_F -> {
val array = (decl.value as ReferenceLiteralValue).array!!
val array = (decl.value as ReferenceLiteralValue).array
if(array==null)
TODO("fix this")
val floatFills = array.map {
val number = (it as NumericLiteralValue).number
makeFloatFill(MachineDefinition.Mflpt5.fromNumber(number))
@ -359,7 +361,9 @@ internal class AsmGen2(val program: Program,
}
private fun makeArrayFillDataUnsigned(decl: VarDecl): List<String> {
val array = (decl.value as ReferenceLiteralValue).array!!
val array = (decl.value as ReferenceLiteralValue).array
if(array==null)
TODO("fix this")
return when {
decl.datatype == DataType.ARRAY_UB ->
// byte array can never contain pointer-to types, so treat values as all integers
@ -377,7 +381,10 @@ internal class AsmGen2(val program: Program,
}
private fun makeArrayFillDataSigned(decl: VarDecl): List<String> {
val array = (decl.value as ReferenceLiteralValue).array!!
val array = (decl.value as ReferenceLiteralValue).array
if(array==null)
TODO("fix this ${decl.value}")
return when {
decl.datatype == DataType.ARRAY_UB ->
// byte array can never contain pointer-to types, so treat values as all integers

View File

@ -6,7 +6,6 @@ import prog8.ast.base.*
import prog8.ast.expressions.*
import prog8.ast.processing.IAstModifyingVisitor
import prog8.ast.statements.*
import prog8.compiler.IntegerOrAddressOf
import prog8.compiler.target.c64.MachineDefinition.FLOAT_MAX_NEGATIVE
import prog8.compiler.target.c64.MachineDefinition.FLOAT_MAX_POSITIVE
import kotlin.math.floor
@ -35,8 +34,8 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor {
if(decl.type==VarDeclType.CONST || decl.type==VarDeclType.VAR) {
if(decl.isArray){
// for arrays that have no size specifier (or a non-constant one) attempt to deduce the size
if(decl.arraysize==null) {
// for arrays that have no size specifier (or a non-constant one) attempt to deduce the size
val arrayval = (decl.value as? ReferenceLiteralValue)?.array
if(arrayval!=null) {
decl.arraysize = ArrayIndex(NumericLiteralValue.optimalInteger(arrayval.size, decl.position), decl.position)
@ -73,7 +72,7 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor {
val numericLv = decl.value as? NumericLiteralValue
val rangeExpr = decl.value as? RangeExpr
if(rangeExpr!=null) {
// convert the initializer range expression to an actual array (will be put on heap later)
// convert the initializer range expression to an actual array
val declArraySize = decl.arraysize?.size()
if(declArraySize!=null && declArraySize!=rangeExpr.size())
errors.add(ExpressionError("range expression size doesn't match declared array size", decl.value?.position!!))
@ -119,8 +118,12 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor {
}
else -> {}
}
val heapId = program.heap.addIntegerArray(decl.datatype, Array(size) { IntegerOrAddressOf(fillvalue, null) })
decl.value = ReferenceLiteralValue(decl.datatype, initHeapId = heapId, position = numericLv.position)
// create the array itself, filled with the fillvalue.
val array = Array(size) {fillvalue}.map { NumericLiteralValue.optimalInteger(it, numericLv.position) as Expression}.toTypedArray()
val refValue = ReferenceLiteralValue(decl.datatype, array = array, position = numericLv.position)
refValue.addToHeap(program.heap)
decl.value = refValue
refValue.parent=decl
optimizationsDone++
return super.visit(decl)
}
@ -137,8 +140,12 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor {
if (fillvalue < FLOAT_MAX_NEGATIVE || fillvalue > FLOAT_MAX_POSITIVE)
errors.add(ExpressionError("float value overflow", litval.position))
else {
val heapId = program.heap.addDoublesArray(DoubleArray(size) { fillvalue })
decl.value = ReferenceLiteralValue(DataType.ARRAY_F, initHeapId = heapId, position = litval.position)
// 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 = ReferenceLiteralValue(DataType.ARRAY_F, array = array, position = litval.position)
refValue.addToHeap(program.heap)
decl.value = refValue
refValue.parent=decl
optimizationsDone++
return super.visit(decl)
}

View File

@ -5,75 +5,12 @@
main {
sub start() {
uword target = 4444
; @($d020) = A
; @($d020) = A+4
; @(target) = A+4
; @(target+4) = A+4
whenubyte(20)
whenubyte(111)
whenbyte(-10)
whenbyte(-111)
whenbyte(0)
byte[4] barray=2
uword[4] uwarray=50000
word[4] warray=-500
float[4] rotatedx=0.0
whenuword(500)
whenuword(44)
whenword(-3000)
whenword(-44)
whenword(0)
sub whenbyte(byte value) {
when value {
-4 -> c64scr.print("minusfour")
-5 -> c64scr.print("minusfive")
-10,-20,-30 -> {
c64scr.print("minusten or twenty or thirty")
}
-99 -> c64scr.print("minusninetynine")
else -> c64scr.print("don't know")
}
c64.CHROUT('\n')
}
sub whenubyte(ubyte value) {
when value {
4 -> c64scr.print("four")
5 -> c64scr.print("five")
10,20,30 -> {
c64scr.print("ten or twenty or thirty")
}
99 -> c64scr.print("ninetynine")
else -> c64scr.print("don't know")
}
c64.CHROUT('\n')
}
sub whenuword(uword value) {
when value {
400 -> c64scr.print("four100")
500 -> c64scr.print("five100")
1000,2000,3000 -> {
c64scr.print("thousand 2thousand or 3thousand")
}
9999 -> c64scr.print("ninetynine99")
else -> c64scr.print("don't know")
}
c64.CHROUT('\n')
}
sub whenword(word value) {
when value {
-400 -> c64scr.print("minusfour100")
-500 -> c64scr.print("minusfive100")
-1000,-2000,-3000 -> {
c64scr.print("minusthousand 2thousand or 3thousand")
}
-9999 -> c64scr.print("minusninetynine99")
else -> c64scr.print("don't know")
}
c64.CHROUT('\n')
}
}
}