diff --git a/compiler/src/prog8/ast/expressions/InferredTypes.kt b/compiler/src/prog8/ast/expressions/InferredTypes.kt index ac79df1dd..d7111e1a5 100644 --- a/compiler/src/prog8/ast/expressions/InferredTypes.kt +++ b/compiler/src/prog8/ast/expressions/InferredTypes.kt @@ -29,7 +29,7 @@ object InferredTypes { return when { datatype!=null -> datatype.toString() isVoid -> "" - else -> "" + else -> "" } } } diff --git a/compiler/src/prog8/ast/processing/AstChecker.kt b/compiler/src/prog8/ast/processing/AstChecker.kt index 7dc4e231c..60188e3c5 100644 --- a/compiler/src/prog8/ast/processing/AstChecker.kt +++ b/compiler/src/prog8/ast/processing/AstChecker.kt @@ -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)) { diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index e1197f6f3..473f1ba51 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -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() @@ -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 } diff --git a/compiler/src/prog8/vm/RuntimeValue.kt b/compiler/src/prog8/vm/RuntimeValue.kt index 1df48a823..2cb2b13a0 100644 --- a/compiler/src/prog8/vm/RuntimeValue.kt +++ b/compiler/src/prog8/vm/RuntimeValue.kt @@ -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?=null, val heapId: Int?=null) { + +open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null, val array: Array?=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() - 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() + 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 } diff --git a/compiler/src/prog8/vm/astvm/AstVm.kt b/compiler/src/prog8/vm/astvm/AstVm.kt index 7143a3f3d..3ebe9cf84 100644 --- a/compiler/src/prog8/vm/astvm/AstVm.kt +++ b/compiler/src/prog8/vm/astvm/AstVm.kt @@ -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" -> { diff --git a/compiler/src/prog8/vm/astvm/Expressions.kt b/compiler/src/prog8/vm/astvm/Expressions.kt index 14849e6eb..bc87703e5 100644 --- a/compiler/src/prog8/vm/astvm/Expressions.kt +++ b/compiler/src/prog8/vm/astvm/Expressions.kt @@ -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()] diff --git a/compiler/src/prog8/vm/astvm/VariablesCreator.kt b/compiler/src/prog8/vm/astvm/VariablesCreator.kt index 7d433aa89..44800845c 100644 --- a/compiler/src/prog8/vm/astvm/VariablesCreator.kt +++ b/compiler/src/prog8/vm/astvm/VariablesCreator.kt @@ -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) -// } - } diff --git a/compiler/test/RuntimeValueTests.kt b/compiler/test/RuntimeValueTests.kt index 1e8ece187..ffd59b8e3 100644 --- a/compiler/test/RuntimeValueTests.kt +++ b/compiler/test/RuntimeValueTests.kt @@ -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)) diff --git a/examples/test.p8 b/examples/test.p8 index 150956125..8b2ebbd84 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -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(',') + } } }