mirror of
https://github.com/irmen/prog8.git
synced 2025-04-08 09:37:35 +00:00
taking down the heapvalue mess
This commit is contained in:
parent
0f1485f30b
commit
8c3b43f3ed
@ -29,7 +29,7 @@ object InferredTypes {
|
||||
return when {
|
||||
datatype!=null -> datatype.toString()
|
||||
isVoid -> "<void>"
|
||||
else -> "<unkonwn>"
|
||||
else -> "<unknown>"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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" -> {
|
||||
|
@ -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()]
|
||||
|
@ -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)
|
||||
// }
|
||||
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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(',')
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user