From 5e42c0d7368bd18b74454c19c2d1b07e13f32f34 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 12 Jan 2019 16:32:03 +0100 Subject: [PATCH] rewrote HeapVars a bit to allow for more flexibility (removal of values?) --- compiler/src/prog8/ast/AstChecker.kt | 2 +- compiler/src/prog8/compiler/Compiler.kt | 45 +++++++++++-------- .../intermediate/IntermediateProgram.kt | 6 +-- .../prog8/optimizing/StatementOptimizer.kt | 1 - 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/compiler/src/prog8/ast/AstChecker.kt b/compiler/src/prog8/ast/AstChecker.kt index c7f23585f..c7cc2bc39 100644 --- a/compiler/src/prog8/ast/AstChecker.kt +++ b/compiler/src/prog8/ast/AstChecker.kt @@ -52,7 +52,7 @@ class AstChecker(private val namespace: INameScope, private val heapStringSentinel: Int init { val stringSentinel = heap.allEntries().firstOrNull {it.value.str==""} - heapStringSentinel = stringSentinel?.index ?: heap.add(DataType.STR, "") + heapStringSentinel = stringSentinel?.key ?: heap.add(DataType.STR, "") } fun result(): List { diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index 33ed0aa7b..fb1667903 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -50,7 +50,8 @@ class HeapValues { val arraysize: Int = array?.size ?: doubleArray?.size ?: 0 } - private val heap = mutableListOf() + private val heap = mutableMapOf() + private var heapId = 1 fun size(): Int = heap.size @@ -60,48 +61,56 @@ class HeapValues { // strings are 'interned' and shared if they're the same val value = HeapValue(type, str, null, null) - val existing = heap.indexOf(value) - if(existing>=0) + + val existing = heap.filter { it.value==value }.map { it.key }.firstOrNull() + if(existing!=null) return existing - heap.add(value) - return heap.size-1 + val newId = heapId++ + heap[newId] = value + return newId } fun add(type: DataType, array: IntArray): Int { - // arrays are never shared - heap.add(HeapValue(type, null, array, null)) - return heap.size-1 + // arrays are never shared, don't check for existing + val newId = heapId++ + heap[newId] = HeapValue(type, null, array, null) + return newId } fun add(type: DataType, darray: DoubleArray): Int { - // arrays are never shared - heap.add(HeapValue(type, null, null, darray)) - return heap.size-1 + // arrays are never shared, don't check for existing + val newId = heapId++ + heap[newId] = HeapValue(type, null, null, darray) + return newId } fun update(heapId: Int, str: String) { - when(heap[heapId].type){ + val oldVal = heap[heapId] ?: throw IllegalArgumentException("heapId not found in heap") + when(oldVal.type){ DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> { - if(heap[heapId].str!!.length!=str.length) + if(oldVal.str!!.length!=str.length) throw IllegalArgumentException("heap string length mismatch") - heap[heapId] = heap[heapId].copy(str=str) + heap[heapId] = oldVal.copy(str=str) } else-> throw IllegalArgumentException("heap data type mismatch") } } fun update(heapId: Int, heapval: HeapValue) { + if(heapId !in heap) + throw IllegalArgumentException("heapId not found in heap") heap[heapId] = heapval } - fun get(heapId: Int): HeapValue = heap[heapId] + fun get(heapId: Int): HeapValue { + return heap[heapId] ?: + throw IllegalArgumentException("heapId not found in heap") + } - // TODO remove function - - fun allEntries() = heap.withIndex().toList() + fun allEntries() = heap.entries } diff --git a/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt b/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt index 3ec1aa8b0..6554c7005 100644 --- a/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt +++ b/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt @@ -404,11 +404,11 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap heap.allEntries().forEach { when { it.value.str!=null -> - out.println("${it.index} ${it.value.type.toString().toLowerCase()} \"${escape(it.value.str!!)}\"") + out.println("${it.key} ${it.value.type.toString().toLowerCase()} \"${escape(it.value.str!!)}\"") it.value.array!=null -> - out.println("${it.index} ${it.value.type.toString().toLowerCase()} ${it.value.array!!.toList()}") + out.println("${it.key} ${it.value.type.toString().toLowerCase()} ${it.value.array!!.toList()}") it.value.doubleArray!=null -> - out.println("${it.index} ${it.value.type.toString().toLowerCase()} ${it.value.doubleArray!!.toList()}") + out.println("${it.key} ${it.value.type.toString().toLowerCase()} ${it.value.doubleArray!!.toList()}") else -> throw CompilerException("invalid heap entry $it") } } diff --git a/compiler/src/prog8/optimizing/StatementOptimizer.kt b/compiler/src/prog8/optimizing/StatementOptimizer.kt index e557ef5b0..dd526b43d 100644 --- a/compiler/src/prog8/optimizing/StatementOptimizer.kt +++ b/compiler/src/prog8/optimizing/StatementOptimizer.kt @@ -51,7 +51,6 @@ class StatementOptimizer(private val namespace: INameScope, private val heap: He if(stringVar!=null) { val heapId = stringVar.heapId(namespace) val string = heap.get(heapId).str!! - // TODO heap.remove(heapId) if(string.length==1) { val petscii = Petscii.encodePetscii(string, true)[0] functionCall.arglist.clear()