streamline moving values to heap

This commit is contained in:
Irmen de Jong 2019-07-01 18:01:36 +02:00
parent 31137743f0
commit 1d7f0d3537
3 changed files with 40 additions and 39 deletions

View File

@ -5,6 +5,7 @@ import org.antlr.v4.runtime.ParserRuleContext
import org.antlr.v4.runtime.tree.TerminalNode
import prog8.compiler.RuntimeValue
import prog8.compiler.HeapValues
import prog8.compiler.IntegerOrAddressOf
import prog8.compiler.target.c64.Petscii
import prog8.functions.BuiltinFunctions
import prog8.functions.NotConstArgumentException
@ -1298,7 +1299,7 @@ open class LiteralValue(val type: DataType,
val floatvalue: Double? = null,
val strvalue: String? = null,
val arrayvalue: Array<IExpression>? = null,
var heapId: Int? =null,
initHeapId: Int? =null,
override val position: Position) : IExpression {
override lateinit var parent: Node
@ -1307,6 +1308,8 @@ open class LiteralValue(val type: DataType,
val isString = type in StringDatatypes
val isNumeric = type in NumericDatatypes
val isArray = type in ArrayDatatypes
var heapId = initHeapId
private set
companion object {
fun fromBoolean(bool: Boolean, position: Position) =
@ -1522,6 +1525,35 @@ open class LiteralValue(val type: DataType,
}
return null // invalid type conversion from $this to $targettype
}
fun addToHeap(heap: HeapValues) {
if(heapId==null) {
if (strvalue != null) {
heapId = heap.addString(type, strvalue)
}
else if (arrayvalue!=null) {
if(arrayvalue.any {it is AddressOf}) {
val intArrayWithAddressOfs = arrayvalue.map {
when (it) {
is AddressOf -> IntegerOrAddressOf(null, it)
is LiteralValue -> IntegerOrAddressOf(it.asIntegerValue, null)
else -> throw FatalAstException("invalid datatype in array")
}
}
heapId = heap.addIntegerArray(type, intArrayWithAddressOfs.toTypedArray())
} else {
val valuesInArray = arrayvalue.map { (it as LiteralValue).asNumericValue!! }
if(type==DataType.ARRAY_F) {
val doubleArray = valuesInArray.map { it.toDouble() }.toDoubleArray()
heapId = heap.addDoublesArray(doubleArray)
} else {
val integerArray = valuesInArray.map { it.toInt() }
heapId = heap.addIntegerArray(type, integerArray.map { IntegerOrAddressOf(it, null) }.toTypedArray())
}
}
}
}
}
}

View File

@ -535,7 +535,7 @@ private class AstChecker(private val program: Program,
decl.value = litVal
}
decl.type==VarDeclType.VAR -> {
val litVal = LiteralValue(decl.datatype, heapId = heapStringSentinel, position=decl.position) // point to the sentinel heap value instead
val litVal = LiteralValue(decl.datatype, initHeapId = heapStringSentinel, position=decl.position) // point to the sentinel heap value instead
litVal.parent=decl
decl.value = litVal
}

View File

@ -113,7 +113,7 @@ class ConstantFolding(private val program: Program) : IAstProcessor {
else -> {}
}
val heapId = program.heap.addIntegerArray(decl.datatype, Array(size) { IntegerOrAddressOf(fillvalue, null) })
decl.value = LiteralValue(decl.datatype, heapId = heapId, position = litval?.position ?: decl.position)
decl.value = LiteralValue(decl.datatype, initHeapId = heapId, position = litval?.position ?: decl.position)
optimizationsDone++
return decl
}
@ -127,7 +127,7 @@ class ConstantFolding(private val program: Program) : IAstProcessor {
errors.add(ExpressionError("float value overflow", litval?.position ?: decl.position))
else {
val heapId = program.heap.addDoublesArray(DoubleArray(size) { fillvalue })
decl.value = LiteralValue(DataType.ARRAY_F, heapId = heapId, position = litval?.position ?: decl.position)
decl.value = LiteralValue(DataType.ARRAY_F, initHeapId = heapId, position = litval?.position ?: decl.position)
optimizationsDone++
return decl
}
@ -154,7 +154,7 @@ class ConstantFolding(private val program: Program) : IAstProcessor {
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 = LiteralValue(decl.datatype, heapId=heapId, position = litval.position)
decl.value = LiteralValue(decl.datatype, initHeapId=heapId, position = litval.position)
}
}
DataType.ARRAY_F -> {
@ -162,7 +162,7 @@ class ConstantFolding(private val program: Program) : IAstProcessor {
// 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 = LiteralValue(decl.datatype, heapId = heapId, position = litval.position)
decl.value = LiteralValue(decl.datatype, initHeapId = heapId, position = litval.position)
}
}
else -> throw FatalAstException("invalid array vardecl type ${decl.datatype}")
@ -598,12 +598,12 @@ class ConstantFolding(private val program: Program) : IAstProcessor {
if(litval.strvalue!!.length !in 1..255)
addError(ExpressionError("string literal length must be between 1 and 255", litval.position))
else {
litval.heapId = program.heap.addString(litval.type, litval.strvalue) // TODO: we don't know the actual string type yet, STR != STR_S etc...
litval.addToHeap(program.heap) // TODO: we don't know the actual string type yet, STR != STR_S etc...
}
} else if(litval.arrayvalue!=null) {
// first, adjust the array datatype
val litval2 = adjustArrayValDatatype(litval)
moveArrayToHeap(litval2)
litval2.addToHeap(program.heap)
return litval2
}
return litval
@ -649,37 +649,6 @@ class ConstantFolding(private val program: Program) : IAstProcessor {
return litval
}
private fun moveArrayToHeap(arraylit: LiteralValue) {
val array: Array<IExpression> = arraylit.arrayvalue!!.map { it.process(this) }.toTypedArray()
if(array.any {it is AddressOf}) {
val intArrayWithAddressOfs = array.map {
when (it) {
is AddressOf -> IntegerOrAddressOf(null, it)
is LiteralValue -> IntegerOrAddressOf(it.asIntegerValue, null)
else -> throw CompilerException("invalid datatype in array")
}
}
arraylit.heapId = program.heap.addIntegerArray(arraylit.type, intArrayWithAddressOfs.toTypedArray())
} else {
// array is only constant numerical values
val valuesInArray = array.map { it.constValue(program)!!.asNumericValue!! }
arraylit.heapId = when(arraylit.type) {
DataType.ARRAY_UB,
DataType.ARRAY_B,
DataType.ARRAY_UW,
DataType.ARRAY_W -> {
val integerArray = valuesInArray.map{ it.toInt() }
program.heap.addIntegerArray(arraylit.type, integerArray.map { IntegerOrAddressOf(it, null) }.toTypedArray())
}
DataType.ARRAY_F -> {
val doubleArray = valuesInArray.map{it.toDouble()}.toDoubleArray()
program.heap.addDoublesArray(doubleArray)
}
else -> throw CompilerException("invalid arraysize type")
}
}
}
override fun process(assignment: Assignment): IStatement {
super.process(assignment)
val lv = assignment.value as? LiteralValue