From 3732ab1e627d501a00f05956d4bad96cdba0d8cf Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 30 Jul 2019 02:26:30 +0200 Subject: [PATCH] fix compilation errors --- compiler/src/prog8/ast/antlr/Antr2Kotlin.kt | 2 +- .../prog8/ast/expressions/AstExpressions.kt | 19 +++-- compiler/src/prog8/compiler/Main.kt | 2 +- .../compiler/target/c64/codegen2/AsmGen2.kt | 13 +++- .../src/prog8/optimizer/ConstantFolding.kt | 21 ++++-- examples/test.p8 | 71 ++----------------- 6 files changed, 45 insertions(+), 83 deletions(-) diff --git a/compiler/src/prog8/ast/antlr/Antr2Kotlin.kt b/compiler/src/prog8/ast/antlr/Antr2Kotlin.kt index 294c9cef6..215d93f9b 100644 --- a/compiler/src/prog8/ast/antlr/Antr2Kotlin.kt +++ b/compiler/src/prog8/ast/antlr/Antr2Kotlin.kt @@ -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 -> { diff --git a/compiler/src/prog8/ast/expressions/AstExpressions.kt b/compiler/src/prog8/ast/expressions/AstExpressions.kt index c5a4d28e2..700a78031 100644 --- a/compiler/src/prog8/ast/expressions/AstExpressions.kt +++ b/compiler/src/prog8/ast/expressions/AstExpressions.kt @@ -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) } } diff --git a/compiler/src/prog8/compiler/Main.kt b/compiler/src/prog8/compiler/Main.kt index 76355c169..cb061953d 100644 --- a/compiler/src/prog8/compiler/Main.kt +++ b/compiler/src/prog8/compiler/Main.kt @@ -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 diff --git a/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt b/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt index b16f3a47a..7e5bc24a5 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen2/AsmGen2.kt @@ -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 { - 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 { - 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 diff --git a/compiler/src/prog8/optimizer/ConstantFolding.kt b/compiler/src/prog8/optimizer/ConstantFolding.kt index 3df40d952..3cec7f85a 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.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) } diff --git a/examples/test.p8 b/examples/test.p8 index 60cb11b47..9d59007b7 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -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') - } } }