taking down the heapvalue mess

This commit is contained in:
Irmen de Jong 2019-08-19 22:28:41 +02:00
parent 0f1485f30b
commit 8c3b43f3ed
9 changed files with 109 additions and 104 deletions

View File

@ -29,7 +29,7 @@ object InferredTypes {
return when {
datatype!=null -> datatype.toString()
isVoid -> "<void>"
else -> "<unkonwn>"
else -> "<unknown>"
}
}
}

View File

@ -889,7 +889,7 @@ internal class AstChecker(private val program: Program,
for (arg in args.withIndex().zip(target.parameters)) {
val argIDt = arg.first.value.inferType(program)
if(!argIDt.isKnown) {
throw FatalAstException("can't determine arg dt ${arg.first.value}")
return
}
val argDt=argIDt.typeOrElse(DataType.STRUCT)
if(!(argDt isAssignableTo arg.second.type)) {

View File

@ -84,8 +84,6 @@ class HeapValues {
}
override fun hashCode(): Int = Objects.hash(str, array, doubleArray)
val arraysize: Int = array?.size ?: doubleArray?.size ?: 0
}
private val heap = mutableMapOf<Int, HeapValue>()
@ -124,7 +122,7 @@ class HeapValues {
return newId
}
fun update(heapId: Int, str: String) {
fun updateString(heapId: Int, str: String) {
val oldVal = heap[heapId] ?: throw IllegalArgumentException("heapId not found in heap")
if(oldVal.type in StringDatatypes) {
if (oldVal.str!!.length != str.length)
@ -134,16 +132,8 @@ class HeapValues {
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 {
return heap[heapId] ?:
throw IllegalArgumentException("heapId $heapId not found in heap")
}
fun allEntries() = heap.entries
}

View File

@ -4,7 +4,6 @@ import prog8.ast.base.*
import prog8.ast.expressions.ArrayLiteralValue
import prog8.ast.expressions.NumericLiteralValue
import prog8.ast.expressions.StringLiteralValue
import prog8.compiler.HeapValues
import prog8.compiler.target.c64.Petscii
import java.util.*
import kotlin.math.abs
@ -16,8 +15,8 @@ import kotlin.math.pow
* this runtime value can be used to *execute* the parsed Ast (or another intermediary form)
* It contains a value of a variable during run time of the program and provides arithmetic operations on the value.
*/
open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null,
val array: Array<Number>?=null, val heapId: Int?=null) {
open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null, val array: Array<Number>?=null) {
val byteval: Short?
val wordval: Int?
@ -29,34 +28,26 @@ open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=
return RuntimeValue(literalValue.type, num = literalValue.number)
}
fun fromLv(string: StringLiteralValue, heap: HeapValues): RuntimeValue = fromHeapId(string.heapId!!, heap)
fun fromLv(array: ArrayLiteralValue, heap: HeapValues): RuntimeValue = fromHeapId(array.heapId!!, heap)
fun fromHeapId(heapId: Int, heap: HeapValues): RuntimeValue {
val value = heap.get(heapId)
return when {
value.type in StringDatatypes ->
RuntimeValue(value.type, str = value.str!!, heapId = heapId)
value.type in ArrayDatatypes ->
if (value.type == DataType.ARRAY_F) {
RuntimeValue(value.type, array = value.doubleArray!!.toList().toTypedArray(), heapId = heapId)
} else {
val array = value.array!!
val resultArray = mutableListOf<Number>()
for(elt in array.withIndex()){
if(elt.value.integer!=null)
resultArray.add(elt.value.integer!!)
else {
TODO("ADDRESSOF ${elt.value}")
}
}
RuntimeValue(value.type, array = resultArray.toTypedArray(), heapId = heapId)
//RuntimeValue(value.type, array = array.map { it.integer!! }.toTypedArray(), heapId = heapId)
}
else -> throw IllegalArgumentException("weird value type on heap $value")
}
fun fromLv(string: StringLiteralValue): RuntimeValue {
return RuntimeValue(string.type, str = string.value)
}
fun fromLv(array: ArrayLiteralValue): RuntimeValue {
return if (array.type == DataType.ARRAY_F) {
val doubleArray = array.value.map { (it as NumericLiteralValue).number }.toTypedArray()
RuntimeValue(array.type, array = doubleArray)
} else {
val resultArray = mutableListOf<Number>()
for (elt in array.value.withIndex()) {
if (elt.value is NumericLiteralValue)
resultArray.add((elt.value as NumericLiteralValue).number.toInt())
else {
TODO("ADDRESSOF ${elt.value}")
}
}
RuntimeValue(array.type, array = resultArray.toTypedArray())
}
}
}
init {
@ -129,7 +120,14 @@ open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=
"w:%04x".format(wordval)
}
DataType.FLOAT -> "f:$floatval"
else -> "heap:$heapId"
DataType.STR -> "str:$str"
DataType.STR_S -> "str_s:$str"
DataType.ARRAY_UB -> "array_ub:..."
DataType.ARRAY_B -> "array_b:..."
DataType.ARRAY_UW -> "array_uw:..."
DataType.ARRAY_W -> "array_w:..."
DataType.ARRAY_F -> "array_f:..."
DataType.STRUCT -> "struct:..."
}
}
@ -156,8 +154,6 @@ open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=
override fun equals(other: Any?): Boolean {
if(other==null || other !is RuntimeValue)
return false
if(type==other.type)
return if (type in IterableDatatypes) heapId==other.heapId else compareTo(other)==0
return compareTo(other)==0 // note: datatype doesn't matter
}

View File

@ -615,8 +615,7 @@ class AstVm(val program: Program) {
val ident = contextStmt.definingScope().lookup(targetArrayIndexed.identifier.nameInSource, contextStmt) as? VarDecl
?: throw VmExecutionException("can't find assignment target ${target.identifier}")
val identScope = ident.definingScope()
program.heap.update(array.heapId!!, newstr)
runtimeVariables.set(identScope, ident.name, RuntimeValue(array.type, str = newstr, heapId = array.heapId))
runtimeVariables.set(identScope, ident.name, RuntimeValue(array.type, str = newstr))
}
}
else {
@ -735,7 +734,7 @@ class AstVm(val program: Program) {
val heapId = args[0].wordval!!
val origStr = program.heap.get(heapId).str!!
val paddedStr=inputStr.padEnd(origStr.length+1, '\u0000').substring(0, origStr.length)
program.heap.update(heapId, paddedStr)
program.heap.updateString(heapId, paddedStr)
result = RuntimeValue(DataType.UBYTE, paddedStr.indexOf('\u0000'))
}
"c64flt.print_f" -> {

View File

@ -30,8 +30,8 @@ fun evaluate(expr: Expression, ctx: EvalContext): RuntimeValue {
when(expr) {
is NumericLiteralValue -> return RuntimeValue.fromLv(expr)
is StringLiteralValue -> return RuntimeValue.fromLv(expr, ctx.program.heap)
is ArrayLiteralValue -> return RuntimeValue.fromLv(expr, ctx.program.heap)
is StringLiteralValue -> return RuntimeValue.fromLv(expr)
is ArrayLiteralValue -> return RuntimeValue.fromLv(expr)
is PrefixExpression -> {
return when(expr.operator) {
"-" -> evaluate(expr.expression, ctx).neg()
@ -80,7 +80,7 @@ fun evaluate(expr: Expression, ctx: EvalContext): RuntimeValue {
val array = evaluate(expr.identifier, ctx)
val index = evaluate(expr.arrayspec.index, ctx)
return if(array.array!=null) {
val value = array.array!![index.integerValue()]
val value = array.array[index.integerValue()]
RuntimeValue(ArrayElementTypes.getValue(array.type), value)
} else {
val value = array.str!![index.integerValue()]

View File

@ -52,9 +52,9 @@ class VariablesCreator(private val runtimeVariables: RuntimeVariables, private v
RuntimeValue.fromLv(numericLv)
} else {
if(decl.value is StringLiteralValue)
RuntimeValue.fromLv(decl.value as StringLiteralValue, heap)
RuntimeValue.fromLv(decl.value as StringLiteralValue)
else
RuntimeValue.fromLv(decl.value as ArrayLiteralValue, heap)
RuntimeValue.fromLv(decl.value as ArrayLiteralValue)
}
runtimeVariables.define(decl.definingScope(), decl.name, value)
}
@ -69,12 +69,4 @@ class VariablesCreator(private val runtimeVariables: RuntimeVariables, private v
}
return super.visit(decl)
}
// override fun accept(assignment: Assignment): Statement {
// if(assignment is VariableInitializationAssignment) {
// println("INIT VAR $assignment")
// }
// return super.accept(assignment)
// }
}

View File

@ -116,23 +116,6 @@ class TestRuntimeValue {
assertFalse(sameValueAndType(RuntimeValue(DataType.FLOAT, 9.99), RuntimeValue(DataType.FLOAT, 9.0)))
}
@Test
fun testEqualityHeapTypes()
{
assertTrue(sameValueAndType(RuntimeValue(DataType.STR, heapId = 999), RuntimeValue(DataType.STR, heapId = 999)))
assertFalse(sameValueAndType(RuntimeValue(DataType.STR, heapId = 999), RuntimeValue(DataType.STR, heapId = 222)))
assertTrue(sameValueAndType(RuntimeValue(DataType.ARRAY_UB, heapId = 99), RuntimeValue(DataType.ARRAY_UB, heapId = 99)))
assertFalse(sameValueAndType(RuntimeValue(DataType.ARRAY_UB, heapId = 99), RuntimeValue(DataType.ARRAY_UB, heapId = 22)))
assertTrue(sameValueAndType(RuntimeValue(DataType.ARRAY_UW, heapId = 999), RuntimeValue(DataType.ARRAY_UW, heapId = 999)))
assertFalse(sameValueAndType(RuntimeValue(DataType.ARRAY_UW, heapId = 999), RuntimeValue(DataType.ARRAY_UW, heapId = 222)))
assertTrue(sameValueAndType(RuntimeValue(DataType.ARRAY_F, heapId = 999), RuntimeValue(DataType.ARRAY_F, heapId = 999)))
assertFalse(sameValueAndType(RuntimeValue(DataType.ARRAY_F, heapId = 999), RuntimeValue(DataType.ARRAY_UW, heapId = 999)))
assertFalse(sameValueAndType(RuntimeValue(DataType.ARRAY_F, heapId = 999), RuntimeValue(DataType.ARRAY_F, heapId = 222)))
}
@Test
fun testGreaterThan(){
assertTrue(RuntimeValue(DataType.UBYTE, 100) > RuntimeValue(DataType.UBYTE, 99))

View File

@ -6,41 +6,86 @@
main {
str str1 = "irmen"
str str2 = "test"
str_s strs1 = "irmen"
str_s strs2 = "test"
sub start() {
str str1x = "irmen"
str str2x = "test"
str_s strs1x = "irmen"
str_s strs2x = "test"
c64scr.print(str1)
c64.CHROUT('\n')
c64scr.print(str2)
c64.CHROUT('\n')
c64scr.print(str1x)
c64.CHROUT('\n')
c64scr.print(str2x)
c64.CHROUT('\n')
str1[0]='a'
str2[0]='a'
str1x[0]='a'
str2x[0]='a'
strs1x[0]='a'
strs2x[0]='a'
strs1[0]='a'
strs2[0]='a'
; @TODO fix AstVm handling of strings (they're not modified right now) NOTE: array's seem to work fine
c64scr.print(str1)
c64.CHROUT('\n')
c64scr.print(str2)
c64.CHROUT('\n')
c64scr.print(str1x)
c64.CHROUT('\n')
c64scr.print(str2x)
c64.CHROUT('\n')
byte[] barr = [1,2,3]
word[] warr = [1000,2000,3000]
float[] farr = [1.1, 2.2, 3.3]
byte bb
word ww
float fl
bb=-1
c64scr.print_b(sgn(bb))
float ff
for bb in barr {
c64scr.print_b(bb)
c64.CHROUT(',')
}
c64.CHROUT('\n')
bb=0
c64scr.print_b(sgn(bb))
for ww in warr {
c64scr.print_w(ww)
c64.CHROUT(',')
}
c64.CHROUT('\n')
bb=1
c64scr.print_b(sgn(bb))
for bb in 0 to len(farr)-1 {
c64flt.print_f(farr[bb])
c64.CHROUT(',')
}
c64.CHROUT('\n')
barr[0] = 99
warr[0] = 99
farr[0] = 99.9
for bb in barr {
c64scr.print_b(bb)
c64.CHROUT(',')
}
c64.CHROUT('\n')
ww=-1
c64scr.print_b(sgn(ww))
c64.CHROUT('\n')
ww=0
c64scr.print_b(sgn(ww))
c64.CHROUT('\n')
ww=1
c64scr.print_b(sgn(ww))
c64.CHROUT('\n')
c64.CHROUT('\n')
fl=-1.1
c64scr.print_b(sgn(fl))
c64.CHROUT('\n')
fl=0.0
c64scr.print_b(sgn(fl))
c64.CHROUT('\n')
fl=1.0
c64scr.print_b(sgn(fl))
c64.CHROUT('\n')
for ww in warr {
c64scr.print_w(ww)
c64.CHROUT(',')
}
c64.CHROUT('\n')
for bb in 0 to len(farr)-1 {
c64flt.print_f(farr[bb])
c64.CHROUT(',')
}
}
}