taking down the heapvalue mess further

This commit is contained in:
Irmen de Jong 2019-08-21 00:09:44 +02:00
parent c717f4573d
commit 8eff51904e
19 changed files with 177 additions and 243 deletions

View File

@ -4,7 +4,6 @@ import prog8.ast.base.*
import prog8.ast.expressions.Expression
import prog8.ast.expressions.IdentifierReference
import prog8.ast.statements.*
import prog8.compiler.HeapValues
import prog8.functions.BuiltinFunctions
import java.nio.file.Path
@ -166,7 +165,6 @@ interface INameScope {
class Program(val name: String, val modules: MutableList<Module>) {
val namespace = GlobalNamespace(modules)
val heap = HeapValues()
val definedLoadAddress: Int
get() = modules.first().loadAddress

View File

@ -429,7 +429,7 @@ private fun prog8Parser.ExpressionContext.toAst() : Expression {
else -> throw FatalAstException("invalid datatype for numeric literal")
}
litval.floatliteral()!=null -> NumericLiteralValue(DataType.FLOAT, litval.floatliteral().toAst(), litval.toPosition())
litval.stringliteral()!=null -> StringLiteralValue(DataType.STR, unescape(litval.stringliteral().text, litval.toPosition()), null, litval.toPosition())
litval.stringliteral()!=null -> StringLiteralValue(DataType.STR, unescape(litval.stringliteral().text, litval.toPosition()), litval.toPosition())
litval.charliteral()!=null -> {
try {
NumericLiteralValue(DataType.UBYTE, Petscii.encodePetscii(unescape(litval.charliteral().text, litval.toPosition()), true)[0], litval.toPosition())

View File

@ -12,8 +12,6 @@ import prog8.ast.statements.ArrayIndex
import prog8.ast.statements.BuiltinFunctionStatementPlaceholder
import prog8.ast.statements.Subroutine
import prog8.ast.statements.VarDecl
import prog8.compiler.HeapValues
import prog8.compiler.IntegerOrAddressOf
import prog8.compiler.target.c64.Petscii
import prog8.functions.BuiltinFunctions
import prog8.functions.NotConstArgumentException
@ -414,7 +412,6 @@ class StructLiteralValue(var values: List<Expression>,
class StringLiteralValue(val type: DataType, // only string types
val value: String,
var heapId: Int?,
override val position: Position) : Expression() {
override lateinit var parent: Node
@ -435,16 +432,18 @@ class StringLiteralValue(val type: DataType, // only string types
return value==other.value && type==other.type
}
fun addToHeap(heap: HeapValues) {
if (heapId != null)
return
else {
val encodedStr = Petscii.encodePetscii(value, true)
heapId = heap.addIntegerArray(DataType.ARRAY_UB, encodedStr.map { IntegerOrAddressOf(it.toInt(), null)}.toTypedArray())
}
var heapId: Int? = null
private set
fun addToHeap() {
if(heapId==null)
heapId = ++heapIdSequence
}
}
private var heapIdSequence = 0
class ArrayLiteralValue(val type: DataType, // only array types
val value: Array<Expression>,
initHeapId: Int? =null,
@ -497,32 +496,9 @@ class ArrayLiteralValue(val type: DataType, // only array types
return null // invalid type conversion from $this to $targettype
}
fun addToHeap(heap: HeapValues) {
if (heapId != null)
return
else {
if(value.any {it is AddressOf }) {
val intArrayWithAddressOfs = value.map {
when (it) {
is AddressOf -> IntegerOrAddressOf(null, it)
is NumericLiteralValue -> IntegerOrAddressOf(it.number.toInt(), null)
else -> throw FatalAstException("invalid datatype in array")
}
}
heapId = heap.addIntegerArray(type, intArrayWithAddressOfs.toTypedArray())
} else {
val valuesInArray = value.map { (it as? NumericLiteralValue)?.number }
if(null !in valuesInArray) {
heapId = if (type == DataType.ARRAY_F) {
val doubleArray = valuesInArray.map { it!!.toDouble() }.toDoubleArray()
heap.addDoublesArray(doubleArray)
} else {
val integerArray = valuesInArray.map { it!!.toInt() }
heap.addIntegerArray(type, integerArray.map { IntegerOrAddressOf(it, null) }.toTypedArray())
}
}
}
}
fun addToHeap() {
if(heapId==null)
heapId = ++heapIdSequence
}
}

View File

@ -1205,53 +1205,56 @@ internal class AstChecker(private val program: Program,
}
private fun checkArrayValues(value: ArrayLiteralValue, type: DataType): Boolean {
if(value.heapId==null) {
if (value.heapId == null) {
// hmm weird, array literal that hasn't been moved to the heap yet?
val array = value.value.mapNotNull { it.constValue(program) }
val correct: Boolean
when(type) {
when (type) {
DataType.ARRAY_UB -> {
correct=array.all { it.type==DataType.UBYTE && it.number.toInt() in 0..255 }
correct = array.all { it.type == DataType.UBYTE && it.number.toInt() in 0..255 }
}
DataType.ARRAY_B -> {
correct=array.all { it.type==DataType.BYTE && it.number.toInt() in -128..127 }
correct = array.all { it.type == DataType.BYTE && it.number.toInt() in -128..127 }
}
DataType.ARRAY_UW -> {
correct=array.all { it.type==DataType.UWORD && it.number.toInt() in 0..65535 }
correct = array.all { it.type == DataType.UWORD && it.number.toInt() in 0..65535 }
}
DataType.ARRAY_W -> {
correct=array.all { it.type==DataType.WORD && it.number.toInt() in -32768..32767}
correct = array.all { it.type == DataType.WORD && it.number.toInt() in -32768..32767 }
}
DataType.ARRAY_F -> correct = true
else -> throw AstException("invalid array type $type")
}
if(!correct)
if (!correct)
checkResult.add(ExpressionError("array value out of range for type $type", value.position))
return correct
}
val array = program.heap.get(value.heapId!!) // TODO use value.array directly?
if(array.type !in ArrayDatatypes || (array.array==null && array.doubleArray==null))
throw FatalAstException("should have an array in the heapvar $array")
val array = value.value.map {
if(it is NumericLiteralValue)
it.number.toInt()
else if(it is AddressOf)
it.identifier.heapId(program.namespace)
else -9999999
}
val correct: Boolean
when(type) {
when (type) {
DataType.ARRAY_UB -> {
correct= array.array?.all { it.integer!=null && it.integer in 0..255 } ?: false
correct = array.all { it in 0..255 }
}
DataType.ARRAY_B -> {
correct=array.array?.all { it.integer!=null && it.integer in -128..127 } ?: false
correct = array.all { it in -128..127 }
}
DataType.ARRAY_UW -> {
correct=array.array?.all { (it.integer!=null && it.integer in 0..65535) || it.addressOf!=null} ?: false
correct = array.all { (it in 0..65535) }
}
DataType.ARRAY_W -> {
correct=array.array?.all { it.integer!=null && it.integer in -32768..32767 } ?: false
correct = array.all { it in -32768..32767 }
}
DataType.ARRAY_F -> correct = array.doubleArray!=null
DataType.ARRAY_F -> correct = true
else -> throw AstException("invalid array type $type")
}
if(!correct)
if (!correct)
checkResult.add(ExpressionError("array value out of range for type $type", value.position))
return correct
}

View File

@ -260,7 +260,7 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi
if (string.value.length !in 1..255)
checkResult.add(ExpressionError("string literal length must be between 1 and 255", string.position))
else {
string.addToHeap(program.heap)
string.addToHeap()
}
return if (vardecl != null)
string
@ -289,7 +289,7 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi
// a referencetype literal value that's not declared as a variable
// we need to introduce an auto-generated variable for this to be able to refer to the value
// note: if the var references the same literal value, it is not yet de-duplicated here.
array.addToHeap(program.heap)
array.addToHeap()
val scope = array.definingScope()
val variable = VarDecl.createAuto(array)
return replaceWithIdentifier(variable, scope, array.parent)
@ -299,7 +299,7 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi
// a referencetype literal value that's not declared as a variable
// we need to introduce an auto-generated variable for this to be able to refer to the value
// note: if the var references the same literal value, it is not yet de-duplicated here.
string.addToHeap(program.heap)
string.addToHeap()
val scope = string.definingScope()
val variable = VarDecl.createAuto(string)
return replaceWithIdentifier(variable, scope, string.parent)
@ -340,14 +340,14 @@ internal class AstIdentifiersChecker(private val program: Program) : IAstModifyi
// repeat a string a number of times
val idt = string.inferType(program)
return StringLiteralValue(idt.typeOrElse(DataType.STR),
string.value.repeat(constvalue.number.toInt()), null, expr.position)
string.value.repeat(constvalue.number.toInt()), expr.position)
}
}
if(expr.operator == "+" && operand is StringLiteralValue) {
// concatenate two strings
val idt = string.inferType(program)
return StringLiteralValue(idt.typeOrElse(DataType.STR),
"${string.value}${operand.value}", null, expr.position)
"${string.value}${operand.value}", expr.position)
}
return expr
}
@ -426,7 +426,7 @@ internal fun fixupArrayDatatype(array: ArrayLiteralValue, vardecl: VarDecl, prog
}
vardecl.value = litval2
litval2.linkParents(vardecl)
litval2.addToHeap(program.heap)
litval2.addToHeap()
return litval2
}
}

View File

@ -45,7 +45,7 @@ internal class VarInitValueAndAddressOfCreator(private val program: Program): IA
val array = ArrayLiteralValue(decl.datatype,
Array(arraysize) { NumericLiteralValue.optimalInteger(0, decl.position) },
null, decl.position)
array.addToHeap(program.heap)
array.addToHeap()
decl.value = array
}

View File

@ -1,53 +0,0 @@
package prog8.compiler
import prog8.ast.base.ArrayDatatypes
import prog8.ast.base.DataType
import java.util.*
/**
* The 'heapvalues' is the collection of variables that are allocated globally.
* Arrays and strings belong here.
* They get assigned a heapId to be able to retrieve them later.
*/
class HeapValues {
data class HeapValue(val type: DataType, val array: Array<IntegerOrAddressOf>?, val doubleArray: DoubleArray?) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as HeapValue
return type==other.type && Arrays.equals(array, other.array) && Arrays.equals(doubleArray, other.doubleArray)
}
override fun hashCode(): Int = Objects.hash(type, array, doubleArray)
}
private val heap = mutableMapOf<Int, HeapValue>()
private var heapId = 1
fun size(): Int = heap.size
fun addIntegerArray(type: DataType, array: Array<IntegerOrAddressOf>): Int {
// arrays are never shared, don't check for existing
if(type !in ArrayDatatypes)
throw CompilerException("wrong array type $type")
val newId = heapId++
heap[newId] = HeapValue(type, array, null)
return newId
}
fun addDoublesArray(darray: DoubleArray): Int {
// arrays are never shared, don't check for existing
val newId = heapId++
heap[newId] = HeapValue(DataType.ARRAY_F, null, darray)
return newId
}
fun get(heapId: Int): HeapValue {
return heap[heapId] ?:
throw IllegalArgumentException("heapId $heapId not found in heap")
}
fun remove(heapId: Int) {
heap.remove(heapId)
}
}

View File

@ -96,7 +96,7 @@ fun compileProgram(filepath: Path,
programAst.checkValid(compilerOptions) // check if final tree is valid
programAst.checkRecursion() // check if there are recursive subroutine calls
printAst(programAst)
// printAst(programAst)
if(writeAssembly) {
// asm generation directly from the Ast, no need for intermediate code

View File

@ -199,7 +199,7 @@ fun builtinFunctionReturnType(function: String, args: List<Expression>, program:
}
class NotConstArgumentException: AstException("not a const argument to a built-in function") // TODO: ugly, remove throwing exceptions for control flow
class NotConstArgumentException: AstException("not a const argument to a built-in function")
private fun oneDoubleArg(args: List<Expression>, position: Position, program: Program, function: (arg: Double)->Number): NumericLiteralValue {

View File

@ -124,7 +124,7 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor {
// create the array itself, filled with the fillvalue.
val array = Array(size) {fillvalue}.map { NumericLiteralValue.optimalInteger(it, numericLv.position) as Expression}.toTypedArray()
val refValue = ArrayLiteralValue(decl.datatype, array, position = numericLv.position)
refValue.addToHeap(program.heap)
refValue.addToHeap()
decl.value = refValue
refValue.parent=decl
optimizationsDone++
@ -146,7 +146,7 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor {
// create the array itself, filled with the fillvalue.
val array = Array(size) {fillvalue}.map { NumericLiteralValue(DataType.FLOAT, it, litval.position) as Expression}.toTypedArray()
val refValue = ArrayLiteralValue(DataType.ARRAY_F, array, position = litval.position)
refValue.addToHeap(program.heap)
refValue.addToHeap()
decl.value = refValue
refValue.parent=decl
optimizationsDone++
@ -610,8 +610,7 @@ class ConstantFolding(private val program: Program) : IAstModifyingVisitor {
override fun visit(arrayLiteral: ArrayLiteralValue): Expression {
val array = super.visit(arrayLiteral)
if(array is ArrayLiteralValue) {
if(array.heapId==null)
array.addToHeap(program.heap)
array.addToHeap()
val vardecl = array.parent as? VarDecl
return if (vardecl!=null) {
fixupArrayDatatype(array, vardecl, program)

View File

@ -615,8 +615,6 @@ internal class SimplifyExpressions(private val program: Program) : IAstModifying
if(leftVal==null && rightVal==null)
return expr
// TODO fix bug in this routine!
// cannot shuffle assiciativity with division!
if(rightVal!=null) {
// right value is a constant, see if we can optimize

View File

@ -186,7 +186,6 @@ internal class StatementOptimizer(private val program: Program) : IAstModifyingV
functionCallStatement.arglist.add(NumericLiteralValue.optimalInteger(encodedString[0].toInt(), functionCallStatement.position))
functionCallStatement.target = IdentifierReference(listOf("c64", "CHROUT"), functionCallStatement.target.position)
vardeclsToRemove.add(vardecl)
program.heap.remove(string.heapId!!)
optimizationsDone++
return functionCallStatement
} else if(string.value.length==2) {
@ -196,7 +195,6 @@ internal class StatementOptimizer(private val program: Program) : IAstModifyingV
scope.statements.add(FunctionCallStatement(IdentifierReference(listOf("c64", "CHROUT"), functionCallStatement.target.position),
mutableListOf(NumericLiteralValue.optimalInteger(encodedString[1].toInt(), functionCallStatement.position)), functionCallStatement.position))
vardeclsToRemove.add(vardecl)
program.heap.remove(string.heapId!!)
optimizationsDone++
return scope
}

View File

@ -575,10 +575,10 @@ class RuntimeValueNumeric(type: DataType, num: Number): RuntimeValueBase(type) {
}
class RuntimeValueString(type: DataType, val str: String): RuntimeValueBase(type) {
class RuntimeValueString(type: DataType, val str: String, val heapId: Int?): RuntimeValueBase(type) {
companion object {
fun fromLv(string: StringLiteralValue): RuntimeValueString {
return RuntimeValueString(string.type, str = string.value)
return RuntimeValueString(string.type, string.value, string.heapId!!)
}
}
@ -610,13 +610,13 @@ class RuntimeValueString(type: DataType, val str: String): RuntimeValueBase(type
}
open class RuntimeValueArray(type: DataType, val array: Array<Number>): RuntimeValueBase(type) {
open class RuntimeValueArray(type: DataType, val array: Array<Number>, val heapId: Int?): RuntimeValueBase(type) {
companion object {
fun fromLv(array: ArrayLiteralValue): RuntimeValueArray {
return if (array.type == DataType.ARRAY_F) {
val doubleArray = array.value.map { (it as NumericLiteralValue).number }.toTypedArray()
RuntimeValueArray(array.type, array = doubleArray)
RuntimeValueArray(array.type, doubleArray, array.heapId!!)
} else {
val resultArray = mutableListOf<Number>()
for (elt in array.value.withIndex()) {
@ -626,7 +626,7 @@ open class RuntimeValueArray(type: DataType, val array: Array<Number>): RuntimeV
TODO("ADDRESSOF ${elt.value}")
}
}
RuntimeValueArray(array.type, array = resultArray.toTypedArray())
RuntimeValueArray(array.type, resultArray.toTypedArray(), array.heapId!!)
}
}
}
@ -662,7 +662,7 @@ open class RuntimeValueArray(type: DataType, val array: Array<Number>): RuntimeV
}
class RuntimeValueRange(type: DataType, val range: IntProgression): RuntimeValueArray(type, range.toList().toTypedArray()) {
class RuntimeValueRange(type: DataType, val range: IntProgression): RuntimeValueArray(type, range.toList().toTypedArray(), null) {
override fun iterator(): Iterator<Number> {
return range.iterator()
}

View File

@ -7,7 +7,6 @@ import prog8.ast.expressions.Expression
import prog8.ast.expressions.IdentifierReference
import prog8.ast.expressions.NumericLiteralValue
import prog8.ast.statements.*
import prog8.compiler.IntegerOrAddressOf
import prog8.compiler.target.c64.MachineDefinition
import prog8.compiler.target.c64.Petscii
import prog8.vm.*
@ -75,6 +74,10 @@ class RuntimeVariables {
val where = vars.getValue(scope)
where[name] = initialValue
vars[scope] = where
if(initialValue is RuntimeValueString)
byHeapId[initialValue.heapId!!] = initialValue
else if(initialValue is RuntimeValueArray)
byHeapId[initialValue.heapId!!] = initialValue
}
fun defineMemory(scope: INameScope, name: String, address: Int) {
@ -95,8 +98,14 @@ class RuntimeVariables {
throw VmExecutionException("new value is of different datatype ${value.type} expected ${existing.type} for $name")
where[name] = value
vars[scope] = where
if(value is RuntimeValueString)
byHeapId[value.heapId!!] = value
else if(value is RuntimeValueArray)
byHeapId[value.heapId!!] = value
}
fun getByHeapId(heapId: Int): RuntimeValueBase = byHeapId.getValue(heapId)
fun get(scope: INameScope, name: String): RuntimeValueBase {
val where = vars.getValue(scope)
return where[name] ?: throw NoSuchElementException("no such runtime variable: ${scope.name}.$name")
@ -118,6 +127,7 @@ class RuntimeVariables {
private val vars = mutableMapOf<INameScope, MutableMap<String, RuntimeValueBase>>().withDefault { mutableMapOf() }
private val memvars = mutableMapOf<INameScope, MutableMap<String, Int>>().withDefault { mutableMapOf() }
private val byHeapId = mutableMapOf<Int, RuntimeValueBase>()
}
@ -620,7 +630,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()
runtimeVariables.set(identScope, ident.name, RuntimeValueString(array.type, newstr))
runtimeVariables.set(identScope, ident.name, RuntimeValueString(array.type, newstr, array.heapId))
}
}
else {
@ -662,7 +672,7 @@ class AstVm(val program: Program) {
"c64scr.print" -> {
// if the argument is an UWORD, consider it to be the "address" of the string (=heapId)
if (args[0].wordval != null) {
val encodedStr = program.heap.get(args[0].wordval!!).array!!.map { it.integer!!.toShort() }
val encodedStr = getEncodedStringFromRuntimeVars(args[0].wordval!!)
dialog.canvas.printText(encodedStr)
} else
throw VmExecutionException("print non-heap string")
@ -738,9 +748,9 @@ class AstVm(val program: Program) {
}
val inputStr = input.joinToString("")
val heapId = args[0].wordval!!
val origStrLength = program.heap.get(heapId).array!!.size
val origStrLength = getEncodedStringFromRuntimeVars(heapId).size
val encodedStr = Petscii.encodePetscii(inputStr, true).take(origStrLength).toMutableList()
while(encodedStr.size<origStrLength)
while(encodedStr.size < origStrLength)
encodedStr.add(0)
result = RuntimeValueNumeric(DataType.UBYTE, encodedStr.indexOf(0))
}
@ -762,8 +772,8 @@ class AstVm(val program: Program) {
}
"c64utils.str2uword" -> {
val heapId = args[0].wordval!!
val argString = program.heap.get(heapId).array!!.map { it.integer!!.toChar() }
val numericpart = argString.takeWhile { it.isDigit() }.toString()
val argString = getEncodedStringFromRuntimeVars(heapId)
val numericpart = argString.takeWhile { it.toChar().isDigit() }.toString()
result = RuntimeValueNumeric(DataType.UWORD, numericpart.toInt() and 65535)
}
else -> TODO("syscall ${sub.scopedname} $sub")
@ -772,6 +782,20 @@ class AstVm(val program: Program) {
return result
}
private fun getEncodedStringFromRuntimeVars(heapId: Int): List<Short> {
val stringvar = runtimeVariables.getByHeapId(heapId) as RuntimeValueString
return when {
stringvar.type==DataType.STR -> Petscii.encodePetscii(stringvar.str, true)
stringvar.type==DataType.STR_S -> Petscii.encodeScreencode(stringvar.str, true)
else -> throw VmExecutionException("weird string type")
}
}
private fun getArrayFromRuntimeVars(heapId: Int): IntArray {
val arrayvar = runtimeVariables.getByHeapId(heapId) as RuntimeValueArray
return arrayvar.array.map { it.toInt() }.toIntArray()
}
private fun performBuiltinFunction(name: String, args: List<RuntimeValueBase>, statusflags: StatusFlags): RuntimeValueNumeric? {
return when (name) {
"rnd" -> RuntimeValueNumeric(DataType.UBYTE, rnd.nextInt() and 255)
@ -886,30 +910,30 @@ class AstVm(val program: Program) {
}
"memset" -> {
val heapId = (args[0] as RuntimeValueNumeric).wordval!!
val target = program.heap.get(heapId).array ?: throw VmExecutionException("memset target is not an array")
val target = getArrayFromRuntimeVars(heapId)
val amount = args[1].integerValue()
val value = args[2].integerValue()
for (i in 0 until amount) {
target[i] = IntegerOrAddressOf(value, null)
target[i] = value
}
null
}
"memsetw" -> {
val heapId = (args[0] as RuntimeValueNumeric).wordval!!
val target = program.heap.get(heapId).array ?: throw VmExecutionException("memset target is not an array")
val target = getArrayFromRuntimeVars(heapId)
val amount = args[1].integerValue()
val value = args[2].integerValue()
for (i in 0 until amount step 2) {
target[i * 2] = IntegerOrAddressOf(value and 255, null)
target[i * 2 + 1] = IntegerOrAddressOf(value ushr 8, null)
target[i * 2] = value and 255
target[i * 2 + 1] = value ushr 8
}
null
}
"memcopy" -> {
val sourceHeapId = (args[0] as RuntimeValueNumeric).wordval!!
val destHeapId = (args[1] as RuntimeValueNumeric).wordval!!
val source = program.heap.get(sourceHeapId).array!!
val dest = program.heap.get(destHeapId).array!!
val source = getArrayFromRuntimeVars(sourceHeapId)
val dest = getArrayFromRuntimeVars(destHeapId)
val amount = args[2].integerValue()
for(i in 0 until amount) {
dest[i] = source[i]
@ -982,5 +1006,4 @@ class AstVm(val program: Program) {
else -> TODO("builtin function $name")
}
}
}

View File

@ -124,8 +124,8 @@ fun evaluate(expr: Expression, ctx: EvalContext): RuntimeValueBase {
DataType.UWORD -> RuntimeValueNumeric(DataType.UWORD, ctx.mem.getUWord(address))
DataType.WORD -> RuntimeValueNumeric(DataType.WORD, ctx.mem.getSWord(address))
DataType.FLOAT -> RuntimeValueNumeric(DataType.FLOAT, ctx.mem.getFloat(address))
DataType.STR -> RuntimeValueString(DataType.STR, ctx.mem.getString(address))
DataType.STR_S -> RuntimeValueString(DataType.STR_S, ctx.mem.getScreencodeString(address)!!)
DataType.STR -> RuntimeValueString(DataType.STR, ctx.mem.getString(address), null)
DataType.STR_S -> RuntimeValueString(DataType.STR_S, ctx.mem.getScreencodeString(address)!!, null)
else -> throw VmExecutionException("unexpected datatype $variable")
}
}

View File

@ -52,10 +52,17 @@ class VariablesCreator(private val runtimeVariables: RuntimeVariables) : IAstMod
val value = if(numericLv!=null) {
RuntimeValueNumeric.fromLv(numericLv)
} else {
if(decl.value is StringLiteralValue)
RuntimeValueString.fromLv(decl.value as StringLiteralValue)
else
RuntimeValueArray.fromLv(decl.value as ArrayLiteralValue)
val strLv = decl.value as? StringLiteralValue
val arrayLv = decl.value as? ArrayLiteralValue
when {
strLv!=null -> {
RuntimeValueString.fromLv(strLv)
}
arrayLv!=null -> {
RuntimeValueArray.fromLv(arrayLv)
}
else -> throw VmExecutionException("weird var type")
}
}
runtimeVariables.define(decl.definingScope(), decl.name, value)
}

View File

@ -83,8 +83,8 @@ class TestParserNumericLiteralValue {
@Test
fun testEqualsRef() {
assertTrue(StringLiteralValue(DataType.STR, "hello", null, dummyPos) == StringLiteralValue(DataType.STR, "hello", null, dummyPos))
assertFalse(StringLiteralValue(DataType.STR, "hello", null, dummyPos) == StringLiteralValue(DataType.STR, "bye", null, dummyPos))
assertTrue(StringLiteralValue(DataType.STR, "hello", dummyPos) == StringLiteralValue(DataType.STR, "hello", dummyPos))
assertFalse(StringLiteralValue(DataType.STR, "hello", dummyPos) == StringLiteralValue(DataType.STR, "bye", dummyPos))
val lvOne = NumericLiteralValue(DataType.UBYTE, 1, dummyPos)
val lvTwo = NumericLiteralValue(DataType.UBYTE, 2, dummyPos)

View File

@ -371,8 +371,8 @@ class TestPetscii {
assertTrue(ten <= ten)
assertFalse(ten < ten)
val abc = StringLiteralValue(DataType.STR, "abc", null, Position("", 0, 0, 0))
val abd = StringLiteralValue(DataType.STR, "abd", null, Position("", 0, 0, 0))
val abc = StringLiteralValue(DataType.STR, "abc", Position("", 0, 0, 0))
val abd = StringLiteralValue(DataType.STR, "abd", Position("", 0, 0, 0))
assertEquals(abc, abc)
assertTrue(abc!=abd)
assertFalse(abc!=abc)

View File

@ -12,94 +12,79 @@ main {
str_s strs2 = "test"
sub start() {
str str1x = "irmen"
str str2x = "test"
str_s strs1x = "irmen"
str_s strs2x = "test"
str foo1 = "1\n"
str foo2 = "12\n"
c64scr.print(str1)
c64.CHROUT('\n')
c64scr.print(str2)
c64.CHROUT('\n')
c64scr.print(str1x)
c64.CHROUT('\n')
c64scr.print(str2x)
c64.CHROUT('\n')
c64scr.print(foo1)
c64scr.print(foo2)
c64scr.print("\n")
c64scr.print("1\n")
c64scr.print("12\n")
c64scr.print("\n")
c64scr.print("1\n")
c64scr.print("12\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'
; str str1x = "irmen"
; str str2x = "test"
; str_s strs1x = "irmen"
; str_s strs2x = "test"
;
; c64scr.print("yoooooo")
; 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 ff
; for bb in barr {
; c64scr.print_b(bb)
; c64.CHROUT(',')
; }
; 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(',')
; }
; 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')
; 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(',')
; }
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 ff
for bb in barr {
c64scr.print_b(bb)
c64.CHROUT(',')
}
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(',')
}
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')
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(',')
}
}
}