From 4bac5043b6499cfdc1deda1d069aec100ff1bb97 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 24 Jun 2019 22:18:50 +0200 Subject: [PATCH] fix integer wraparounds for RuntimeValue --- compiler/src/prog8/astvm/AstVm.kt | 21 +- compiler/src/prog8/astvm/RuntimeValue.kt | 84 ++++---- compiler/test/LiteralValueTests.kt | 132 ++++++++++++ compiler/test/RuntimeValueTests.kt | 248 +++++++++++++++++++++++ compiler/test/ValueOperationsTests.kt | 125 ------------ examples/test.p8 | 135 ++++++++---- 6 files changed, 530 insertions(+), 215 deletions(-) create mode 100644 compiler/test/LiteralValueTests.kt create mode 100644 compiler/test/RuntimeValueTests.kt diff --git a/compiler/src/prog8/astvm/AstVm.kt b/compiler/src/prog8/astvm/AstVm.kt index a35759b26..34c2c7e22 100644 --- a/compiler/src/prog8/astvm/AstVm.kt +++ b/compiler/src/prog8/astvm/AstVm.kt @@ -52,6 +52,7 @@ class AstVm(val program: Program) { var P_irqd: Boolean = false private set private var dialog = ScreenDialog() + var instructionCounter = 0 init { dialog.requestFocusInWindow() @@ -129,7 +130,9 @@ class AstVm(val program: Program) { } private fun executeStatement(sub: INameScope, stmt: IStatement) { - Thread.sleep(10) + instructionCounter++ + if(instructionCounter % 10 == 0) + Thread.sleep(1) when (stmt) { is NopStatement, is Label, is Subroutine -> { // do nothing, skip this instruction @@ -333,9 +336,25 @@ class AstVm(val program: Program) { "c64scr.print_ub" -> { dialog.canvas.printText(args[0].byteval!!.toString(), 1, true) } + "c64scr.print_b" -> { + dialog.canvas.printText(args[0].byteval!!.toString(), 1, true) + } + "c64scr.print_ubhex" -> { + val prefix = if(args[0].asBooleanRuntimeValue) "$" else "" + val number = args[1].byteval!! + dialog.canvas.printText("$prefix${number.toString(16).padStart(2, '0')}", 1, true) + } "c64scr.print_uw" -> { dialog.canvas.printText(args[0].wordval!!.toString(), 1, true) } + "c64scr.print_w" -> { + dialog.canvas.printText(args[0].wordval!!.toString(), 1, true) + } + "c64scr.print_uwhex" -> { + val prefix = if(args[0].asBooleanRuntimeValue) "$" else "" + val number = args[1].wordval!! + dialog.canvas.printText("$prefix${number.toString(16).padStart(4, '0')}", 1, true) + } "c64.CHROUT" -> { dialog.canvas.printChar(args[0].byteval!!) } diff --git a/compiler/src/prog8/astvm/RuntimeValue.kt b/compiler/src/prog8/astvm/RuntimeValue.kt index 165c9b3d1..ea62eee08 100644 --- a/compiler/src/prog8/astvm/RuntimeValue.kt +++ b/compiler/src/prog8/astvm/RuntimeValue.kt @@ -46,33 +46,27 @@ class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null, init { when(type) { DataType.UBYTE -> { - byteval = num!!.toShort() - if(byteval !in 0..255) - throw ArithmeticException("value out of range: $num") + byteval = (num!!.toInt() and 255).toShort() wordval = null floatval = null - asBooleanRuntimeValue = num != 0 + asBooleanRuntimeValue = byteval != 0.toShort() } DataType.BYTE -> { - byteval = num!!.toShort() - if(byteval !in -128..127) - throw ArithmeticException("value out of range: $num") + val v = num!!.toInt() and 255 + byteval = (if(v<128) v else v-256).toShort() wordval = null floatval = null - asBooleanRuntimeValue = num != 0 + asBooleanRuntimeValue = byteval != 0.toShort() } DataType.UWORD -> { - wordval = num!!.toInt() - if(wordval !in 0..65535) - throw ArithmeticException("value out of range: $num") + wordval = num!!.toInt() and 65535 byteval = null floatval = null asBooleanRuntimeValue = wordval != 0 } DataType.WORD -> { - wordval = num!!.toInt() - if(wordval !in -32768..32767) - throw ArithmeticException("value out of range: $num") + val v = num!!.toInt() and 65535 + wordval = if(v<32768) v else v - 65536 byteval = null floatval = null asBooleanRuntimeValue = wordval != 0 @@ -85,7 +79,7 @@ class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null, } else -> { if(heapId==null) - throw ArithmeticException("for non-numeric types, a heapId should be given") + throw IllegalArgumentException("for non-numeric types, a heapId should be given") byteval = null wordval = null floatval = null @@ -99,14 +93,14 @@ class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null, DataType.UBYTE -> "ub:%02x".format(byteval) DataType.BYTE -> { if(byteval!!<0) - "b:-%02x".format(abs(byteval!!.toInt())) + "b:-%02x".format(abs(byteval.toInt())) else "b:%02x".format(byteval) } DataType.UWORD -> "uw:%04x".format(wordval) DataType.WORD -> { if(wordval!!<0) - "w:-%04x".format(abs(wordval!!)) + "w:-%04x".format(abs(wordval)) else "w:%04x".format(wordval) } @@ -175,9 +169,9 @@ class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null, } return when(leftDt) { - DataType.UBYTE -> RuntimeValue(DataType.UBYTE, result.toInt() and 255) + DataType.UBYTE -> RuntimeValue(DataType.UBYTE, result.toInt()) DataType.BYTE -> RuntimeValue(DataType.BYTE, result.toInt()) - DataType.UWORD -> RuntimeValue(DataType.UWORD, result.toInt() and 65535) + DataType.UWORD -> RuntimeValue(DataType.UWORD, result.toInt()) DataType.WORD -> RuntimeValue(DataType.WORD, result.toInt()) DataType.FLOAT -> RuntimeValue(DataType.FLOAT, result) else -> throw ArithmeticException("$op on non-numeric type") @@ -254,20 +248,10 @@ class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null, fun shl(): RuntimeValue { val v = integerValue() return when (type) { - DataType.UBYTE -> return RuntimeValue(type, (v shl 1) and 255) - DataType.BYTE -> { - if(v<0) - RuntimeValue(type, -((-v shl 1) and 255)) - else - RuntimeValue(type, (v shl 1) and 255) - } - DataType.UWORD -> return RuntimeValue(type, (v shl 1) and 65535) - DataType.WORD -> { - if(v<0) - RuntimeValue(type, -((-v shl 1) and 65535)) - else - RuntimeValue(type, (v shl 1) and 65535) - } + DataType.UBYTE, + DataType.BYTE, + DataType.UWORD, + DataType.WORD -> RuntimeValue(type, v shl 1) else -> throw ArithmeticException("invalid type for shl: $type") } } @@ -275,9 +259,9 @@ class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null, fun shr(): RuntimeValue { val v = integerValue() return when(type){ - DataType.UBYTE -> RuntimeValue(type, (v ushr 1) and 255) + DataType.UBYTE -> RuntimeValue(type, v ushr 1) DataType.BYTE -> RuntimeValue(type, v shr 1) - DataType.UWORD -> RuntimeValue(type, (v ushr 1) and 65535) + DataType.UWORD -> RuntimeValue(type, v ushr 1) DataType.WORD -> RuntimeValue(type, v shr 1) else -> throw ArithmeticException("invalid type for shr: $type") } @@ -405,16 +389,16 @@ class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null, fun inv(): RuntimeValue { return when(type) { - DataType.UBYTE -> RuntimeValue(DataType.UBYTE, byteval!!.toInt().inv() and 255) - DataType.UWORD -> RuntimeValue(DataType.UWORD, wordval!!.inv() and 65535) + DataType.UBYTE -> RuntimeValue(DataType.UBYTE, byteval!!.toInt().inv()) + DataType.UWORD -> RuntimeValue(DataType.UWORD, wordval!!.inv()) else -> throw ArithmeticException("inv can only work on byte/word") } } fun inc(): RuntimeValue { return when(type) { - DataType.UBYTE -> RuntimeValue(DataType.UBYTE, (byteval!! + 1) and 255) - DataType.UWORD -> RuntimeValue(DataType.UWORD, (wordval!! + 1) and 65535) + DataType.UBYTE -> RuntimeValue(DataType.UBYTE, byteval!! + 1) + DataType.UWORD -> RuntimeValue(DataType.UWORD, wordval!! + 1) DataType.FLOAT -> RuntimeValue(DataType.FLOAT, floatval!! + 1) else -> throw ArithmeticException("inc can only work on byte/word/float") } @@ -422,8 +406,8 @@ class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null, fun dec(): RuntimeValue { return when(type) { - DataType.UBYTE -> RuntimeValue(DataType.UBYTE, (byteval!! - 1) and 255) - DataType.UWORD -> RuntimeValue(DataType.UWORD, (wordval!! - 1) and 65535) + DataType.UBYTE -> RuntimeValue(DataType.UBYTE, byteval!! - 1) + DataType.UWORD -> RuntimeValue(DataType.UWORD, wordval!! - 1) DataType.FLOAT -> RuntimeValue(DataType.FLOAT, floatval!! - 1) else -> throw ArithmeticException("dec can only work on byte/word/float") } @@ -444,9 +428,9 @@ class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null, DataType.UBYTE -> this DataType.BYTE -> { if(byteval!!<=127) - RuntimeValue(DataType.BYTE, byteval!!) + RuntimeValue(DataType.BYTE, byteval) else - RuntimeValue(DataType.BYTE, -(256-byteval!!)) + RuntimeValue(DataType.BYTE, -(256-byteval)) } DataType.UWORD -> RuntimeValue(DataType.UWORD, numericValue()) DataType.WORD -> RuntimeValue(DataType.WORD, numericValue()) @@ -457,8 +441,8 @@ class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null, DataType.BYTE -> { when (targetType) { DataType.BYTE -> this - DataType.UBYTE -> RuntimeValue(DataType.UBYTE, integerValue() and 255) - DataType.UWORD -> RuntimeValue(DataType.UWORD, integerValue() and 65535) + DataType.UBYTE -> RuntimeValue(DataType.UBYTE, integerValue()) + DataType.UWORD -> RuntimeValue(DataType.UWORD, integerValue()) DataType.WORD -> RuntimeValue(DataType.WORD, integerValue()) DataType.FLOAT -> RuntimeValue(DataType.FLOAT, numericValue()) else -> throw ArithmeticException("invalid type cast from $type to $targetType") @@ -466,7 +450,7 @@ class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null, } DataType.UWORD -> { when (targetType) { - in ByteDatatypes -> RuntimeValue(DataType.UBYTE, integerValue() and 255) + in ByteDatatypes -> RuntimeValue(DataType.UBYTE, integerValue()) DataType.UWORD -> this DataType.WORD -> { if(integerValue()<=32767) @@ -480,8 +464,8 @@ class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null, } DataType.WORD -> { when (targetType) { - in ByteDatatypes -> RuntimeValue(DataType.UBYTE, integerValue() and 255) - DataType.UWORD -> RuntimeValue(DataType.UWORD, integerValue() and 65535) + in ByteDatatypes -> RuntimeValue(DataType.UBYTE, integerValue()) + DataType.UWORD -> RuntimeValue(DataType.UWORD, integerValue()) DataType.WORD -> this DataType.FLOAT -> RuntimeValue(DataType.FLOAT, numericValue()) else -> throw ArithmeticException("invalid type cast from $type to $targetType") @@ -496,8 +480,8 @@ class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null, else throw ArithmeticException("overflow when casting float to byte: $this") } - DataType.UBYTE -> RuntimeValue(DataType.UBYTE, numericValue().toInt() and 255) - DataType.UWORD -> RuntimeValue(DataType.UWORD, numericValue().toInt() and 65535) + DataType.UBYTE -> RuntimeValue(DataType.UBYTE, numericValue().toInt()) + DataType.UWORD -> RuntimeValue(DataType.UWORD, numericValue().toInt()) DataType.WORD -> { val integer=numericValue().toInt() if(integer in -32768..32767) diff --git a/compiler/test/LiteralValueTests.kt b/compiler/test/LiteralValueTests.kt new file mode 100644 index 000000000..93f5a14dc --- /dev/null +++ b/compiler/test/LiteralValueTests.kt @@ -0,0 +1,132 @@ +package prog8tests + +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import prog8.ast.DataType +import prog8.ast.LiteralValue +import prog8.ast.Position +import kotlin.test.* + + +private fun sameValueAndType(lv1: LiteralValue, lv2: LiteralValue): Boolean { + return lv1.type==lv2.type && lv1==lv2 +} + + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class TestParserLiteralValue { + + private val dummyPos = Position("test", 0,0,0) + + @Test + fun testIdentity() { + val v = LiteralValue(DataType.UWORD, wordvalue = 12345, position = dummyPos) + assertEquals(v, v) + assertFalse(v != v) + assertTrue(v <= v) + assertTrue(v >= v) + assertFalse(v < v) + assertFalse(v > v) + + assertTrue(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue = 12345, position = dummyPos), LiteralValue(DataType.UWORD, wordvalue = 12345, position = dummyPos))) + } + + @Test + fun testEqualsAndNotEquals() { + assertEquals(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UBYTE, 100, position=dummyPos)) + assertEquals(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=100, position=dummyPos)) + assertEquals(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos)) + assertEquals(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos), LiteralValue(DataType.UBYTE, 254, position=dummyPos)) + assertEquals(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos)) + assertEquals(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=12345.0, position=dummyPos)) + assertEquals(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos), LiteralValue(DataType.UBYTE, 100, position=dummyPos)) + assertEquals(LiteralValue(DataType.FLOAT, floatvalue=22239.0, position=dummyPos), LiteralValue(DataType.UWORD,wordvalue=22239, position=dummyPos)) + assertEquals(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos)) + + assertTrue(sameValueAndType(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UBYTE, 100, position=dummyPos))) + assertFalse(sameValueAndType(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=100, position=dummyPos))) + assertFalse(sameValueAndType(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos))) + assertFalse(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos), LiteralValue(DataType.UBYTE, 254, position=dummyPos))) + assertTrue(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos))) + assertFalse(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=12345.0, position=dummyPos))) + assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos), LiteralValue(DataType.UBYTE, 100, position=dummyPos))) + assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=22239.0, position=dummyPos), LiteralValue(DataType.UWORD,wordvalue=22239, position=dummyPos))) + assertTrue(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos))) + + assertNotEquals(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UBYTE, 101, position=dummyPos)) + assertNotEquals(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=101, position=dummyPos)) + assertNotEquals(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=101.0, position=dummyPos)) + assertNotEquals(LiteralValue(DataType.UWORD, wordvalue=245, position=dummyPos), LiteralValue(DataType.UBYTE, 246, position=dummyPos)) + assertNotEquals(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=12346, position=dummyPos)) + assertNotEquals(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=12346.0, position=dummyPos)) + assertNotEquals(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.UBYTE, 9, position=dummyPos)) + assertNotEquals(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=9, position=dummyPos)) + assertNotEquals(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=9.0, position=dummyPos)) + + assertFalse(sameValueAndType(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UBYTE, 101, position=dummyPos))) + assertFalse(sameValueAndType(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=101, position=dummyPos))) + assertFalse(sameValueAndType(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=101.0, position=dummyPos))) + assertFalse(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue=245, position=dummyPos), LiteralValue(DataType.UBYTE, 246, position=dummyPos))) + assertFalse(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=12346, position=dummyPos))) + assertFalse(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=12346.0, position=dummyPos))) + assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.UBYTE, 9, position=dummyPos))) + assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=9, position=dummyPos))) + assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=9.0, position=dummyPos))) + + assertTrue(sameValueAndType(LiteralValue(DataType.STR, strvalue = "hello", position=dummyPos), LiteralValue(DataType.STR, strvalue="hello", position=dummyPos))) + assertFalse(sameValueAndType(LiteralValue(DataType.STR, strvalue = "hello", position=dummyPos), LiteralValue(DataType.STR, strvalue="bye", position=dummyPos))) + + val lvOne = LiteralValue(DataType.UBYTE, 1, position=dummyPos) + val lvTwo = LiteralValue(DataType.UBYTE, 2, position=dummyPos) + val lvThree = LiteralValue(DataType.UBYTE, 3, position=dummyPos) + val lvOneR = LiteralValue(DataType.UBYTE, 1, position=dummyPos) + val lvTwoR = LiteralValue(DataType.UBYTE, 2, position=dummyPos) + val lvThreeR = LiteralValue(DataType.UBYTE, 3, position=dummyPos) + val lvFour= LiteralValue(DataType.UBYTE, 4, position=dummyPos) + val lv1 = LiteralValue(DataType.ARRAY_UB, arrayvalue = arrayOf(lvOne, lvTwo, lvThree), position=dummyPos) + val lv2 = LiteralValue(DataType.ARRAY_UB, arrayvalue = arrayOf(lvOneR, lvTwoR, lvThreeR), position=dummyPos) + val lv3 = LiteralValue(DataType.ARRAY_UB, arrayvalue = arrayOf(lvOneR, lvTwoR, lvFour), position=dummyPos) + assertEquals(lv1, lv2) + assertNotEquals(lv1, lv3) + } + + @Test + fun testGreaterThan(){ + assertTrue(LiteralValue(DataType.UBYTE, 100, position=dummyPos) > LiteralValue(DataType.UBYTE, 99, position=dummyPos)) + assertTrue(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) > LiteralValue(DataType.UWORD, wordvalue=253, position=dummyPos)) + assertTrue(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) > LiteralValue(DataType.FLOAT, floatvalue=99.9, position=dummyPos)) + + assertTrue(LiteralValue(DataType.UBYTE, 100, position=dummyPos) >= LiteralValue(DataType.UBYTE, 100, position=dummyPos)) + assertTrue(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) >= LiteralValue(DataType.UWORD,wordvalue= 254, position=dummyPos)) + assertTrue(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) >= LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos)) + + assertFalse(LiteralValue(DataType.UBYTE, 100, position=dummyPos) > LiteralValue(DataType.UBYTE, 100, position=dummyPos)) + assertFalse(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) > LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos)) + assertFalse(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) > LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos)) + + assertFalse(LiteralValue(DataType.UBYTE, 100, position=dummyPos) >= LiteralValue(DataType.UBYTE, 101, position=dummyPos)) + assertFalse(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) >= LiteralValue(DataType.UWORD,wordvalue= 255, position=dummyPos)) + assertFalse(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) >= LiteralValue(DataType.FLOAT, floatvalue=100.1, position=dummyPos)) + } + + @Test + fun testLessThan() { + assertTrue(LiteralValue(DataType.UBYTE, 100, position=dummyPos) < LiteralValue(DataType.UBYTE, 101, position=dummyPos)) + assertTrue(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) < LiteralValue(DataType.UWORD, wordvalue=255, position=dummyPos)) + assertTrue(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) < LiteralValue(DataType.FLOAT, floatvalue=100.1, position=dummyPos)) + + assertTrue(LiteralValue(DataType.UBYTE, 100, position=dummyPos) <= LiteralValue(DataType.UBYTE, 100, position=dummyPos)) + assertTrue(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) <= LiteralValue(DataType.UWORD,wordvalue= 254, position=dummyPos)) + assertTrue(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) <= LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos)) + + assertFalse(LiteralValue(DataType.UBYTE, 100, position=dummyPos) < LiteralValue(DataType.UBYTE, 100, position=dummyPos)) + assertFalse(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) < LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos)) + assertFalse(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) < LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos)) + + assertFalse(LiteralValue(DataType.UBYTE, 100, position=dummyPos) <= LiteralValue(DataType.UBYTE, 99, position=dummyPos)) + assertFalse(LiteralValue(DataType.UWORD,wordvalue= 254, position=dummyPos) <= LiteralValue(DataType.UWORD,wordvalue= 253, position=dummyPos)) + assertFalse(LiteralValue(DataType.FLOAT,floatvalue= 100.0, position=dummyPos) <= LiteralValue(DataType.FLOAT, floatvalue=99.9, position=dummyPos)) + } + +} + diff --git a/compiler/test/RuntimeValueTests.kt b/compiler/test/RuntimeValueTests.kt new file mode 100644 index 000000000..c2ad71c66 --- /dev/null +++ b/compiler/test/RuntimeValueTests.kt @@ -0,0 +1,248 @@ +package prog8tests + +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import prog8.ast.DataType +import prog8.astvm.RuntimeValue +import kotlin.test.* + + +private fun sameValueAndType(v1: RuntimeValue, v2: RuntimeValue): Boolean { + return v1.type==v2.type && v1==v2 +} + + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class TestRuntimeValue { + + @Test + fun testValueRanges() { + assertEquals(100, RuntimeValue(DataType.UBYTE, 100).integerValue()) + assertEquals(100, RuntimeValue(DataType.BYTE, 100).integerValue()) + assertEquals(10000, RuntimeValue(DataType.UWORD, 10000).integerValue()) + assertEquals(10000, RuntimeValue(DataType.WORD, 10000).integerValue()) + assertEquals(100.11, RuntimeValue(DataType.FLOAT, 100.11).numericValue()) + + assertEquals(200, RuntimeValue(DataType.UBYTE, 200).integerValue()) + assertEquals(-56, RuntimeValue(DataType.BYTE, 200).integerValue()) + assertEquals(50000, RuntimeValue(DataType.UWORD, 50000).integerValue()) + assertEquals(-15536, RuntimeValue(DataType.WORD, 50000).integerValue()) + + assertEquals(44, RuntimeValue(DataType.UBYTE, 300).integerValue()) + assertEquals(44, RuntimeValue(DataType.BYTE, 300).integerValue()) + assertEquals(144, RuntimeValue(DataType.UBYTE, 400).integerValue()) + assertEquals(-112, RuntimeValue(DataType.BYTE, 400).integerValue()) + assertEquals(34463, RuntimeValue(DataType.UWORD, 99999).integerValue()) + assertEquals(-31073, RuntimeValue(DataType.WORD, 99999).integerValue()) + + assertEquals(156, RuntimeValue(DataType.UBYTE, -100).integerValue()) + assertEquals(-100, RuntimeValue(DataType.BYTE, -100).integerValue()) + assertEquals(55536, RuntimeValue(DataType.UWORD, -10000).integerValue()) + assertEquals(-10000, RuntimeValue(DataType.WORD, -10000).integerValue()) + assertEquals(-100.11, RuntimeValue(DataType.FLOAT, -100.11).numericValue()) + + assertEquals(56, RuntimeValue(DataType.UBYTE, -200).integerValue()) + assertEquals(56, RuntimeValue(DataType.BYTE, -200).integerValue()) + assertEquals(45536, RuntimeValue(DataType.UWORD, -20000).integerValue()) + assertEquals(-20000, RuntimeValue(DataType.WORD, -20000).integerValue()) + + assertEquals(212, RuntimeValue(DataType.UBYTE, -300).integerValue()) + assertEquals(-44, RuntimeValue(DataType.BYTE, -300).integerValue()) + assertEquals(42184, RuntimeValue(DataType.UWORD, -88888).integerValue()) + assertEquals(-23352, RuntimeValue(DataType.WORD, -88888).integerValue()) + } + + @Test + fun testTruthiness() + { + assertFalse(RuntimeValue(DataType.BYTE, 0).asBooleanRuntimeValue) + assertFalse(RuntimeValue(DataType.UBYTE, 0).asBooleanRuntimeValue) + assertFalse(RuntimeValue(DataType.WORD, 0).asBooleanRuntimeValue) + assertFalse(RuntimeValue(DataType.UWORD, 0).asBooleanRuntimeValue) + assertFalse(RuntimeValue(DataType.FLOAT, 0.0).asBooleanRuntimeValue) + assertFalse(RuntimeValue(DataType.BYTE, 256).asBooleanRuntimeValue) + assertFalse(RuntimeValue(DataType.UBYTE, 256).asBooleanRuntimeValue) + assertFalse(RuntimeValue(DataType.WORD, 65536).asBooleanRuntimeValue) + assertFalse(RuntimeValue(DataType.UWORD, 65536).asBooleanRuntimeValue) + + assertTrue(RuntimeValue(DataType.BYTE, 42).asBooleanRuntimeValue) + assertTrue(RuntimeValue(DataType.UBYTE, 42).asBooleanRuntimeValue) + assertTrue(RuntimeValue(DataType.WORD, 42).asBooleanRuntimeValue) + assertTrue(RuntimeValue(DataType.UWORD, 42).asBooleanRuntimeValue) + assertTrue(RuntimeValue(DataType.FLOAT, 42.0).asBooleanRuntimeValue) + assertTrue(RuntimeValue(DataType.BYTE, -42).asBooleanRuntimeValue) + assertTrue(RuntimeValue(DataType.UBYTE, -42).asBooleanRuntimeValue) + assertTrue(RuntimeValue(DataType.WORD, -42).asBooleanRuntimeValue) + assertTrue(RuntimeValue(DataType.UWORD, -42).asBooleanRuntimeValue) + assertTrue(RuntimeValue(DataType.FLOAT, -42.0).asBooleanRuntimeValue) + } + + + @Test + fun testIdentity() { + val v = RuntimeValue(DataType.UWORD, 12345) + assertEquals(v, v) + assertFalse(v != v) + assertTrue(v<=v) + assertTrue(v>=v) + assertFalse(vv) + + assertTrue(sameValueAndType(RuntimeValue(DataType.UBYTE, 100), RuntimeValue(DataType.UBYTE, 100))) + } + + @Test + fun testEqualsAndNotEquals() { + assertEquals(RuntimeValue(DataType.UBYTE, 100), RuntimeValue(DataType.UBYTE, 100)) + assertEquals(RuntimeValue(DataType.UBYTE, 100), RuntimeValue(DataType.UWORD, 100)) + assertEquals(RuntimeValue(DataType.UBYTE, 100), RuntimeValue(DataType.FLOAT, 100)) + assertEquals(RuntimeValue(DataType.UWORD, 254), RuntimeValue(DataType.UBYTE, 254)) + assertEquals(RuntimeValue(DataType.UWORD, 12345), RuntimeValue(DataType.UWORD, 12345)) + assertEquals(RuntimeValue(DataType.UWORD, 12345), RuntimeValue(DataType.FLOAT, 12345)) + assertEquals(RuntimeValue(DataType.FLOAT, 100.0), RuntimeValue(DataType.UBYTE, 100)) + assertEquals(RuntimeValue(DataType.FLOAT, 22239.0), RuntimeValue(DataType.UWORD, 22239)) + assertEquals(RuntimeValue(DataType.FLOAT, 9.99), RuntimeValue(DataType.FLOAT, 9.99)) + + assertTrue(sameValueAndType(RuntimeValue(DataType.UBYTE, 100), RuntimeValue(DataType.UBYTE, 100))) + assertFalse(sameValueAndType(RuntimeValue(DataType.UBYTE, 100), RuntimeValue(DataType.UWORD, 100))) + assertFalse(sameValueAndType(RuntimeValue(DataType.UBYTE, 100), RuntimeValue(DataType.FLOAT, 100))) + assertFalse(sameValueAndType(RuntimeValue(DataType.UWORD, 254), RuntimeValue(DataType.UBYTE, 254))) + assertTrue(sameValueAndType(RuntimeValue(DataType.UWORD, 12345), RuntimeValue(DataType.UWORD, 12345))) + assertFalse(sameValueAndType(RuntimeValue(DataType.UWORD, 12345), RuntimeValue(DataType.FLOAT, 12345))) + assertFalse(sameValueAndType(RuntimeValue(DataType.FLOAT, 100.0), RuntimeValue(DataType.UBYTE, 100))) + assertFalse(sameValueAndType(RuntimeValue(DataType.FLOAT, 22239.0), RuntimeValue(DataType.UWORD, 22239))) + assertTrue(sameValueAndType(RuntimeValue(DataType.FLOAT, 9.99), RuntimeValue(DataType.FLOAT, 9.99))) + + assertNotEquals(RuntimeValue(DataType.UBYTE, 100), RuntimeValue(DataType.UBYTE, 101)) + assertNotEquals(RuntimeValue(DataType.UBYTE, 100), RuntimeValue(DataType.UWORD, 101)) + assertNotEquals(RuntimeValue(DataType.UBYTE, 100), RuntimeValue(DataType.FLOAT, 101)) + assertNotEquals(RuntimeValue(DataType.UWORD, 245), RuntimeValue(DataType.UBYTE, 246)) + assertNotEquals(RuntimeValue(DataType.UWORD, 12345), RuntimeValue(DataType.UWORD, 12346)) + assertNotEquals(RuntimeValue(DataType.UWORD, 12345), RuntimeValue(DataType.FLOAT, 12346)) + assertNotEquals(RuntimeValue(DataType.FLOAT, 9.99), RuntimeValue(DataType.UBYTE, 9)) + assertNotEquals(RuntimeValue(DataType.FLOAT, 9.99), RuntimeValue(DataType.UWORD, 9)) + assertNotEquals(RuntimeValue(DataType.FLOAT, 9.99), RuntimeValue(DataType.FLOAT, 9.0)) + + assertFalse(sameValueAndType(RuntimeValue(DataType.UBYTE, 100), RuntimeValue(DataType.UBYTE, 101))) + assertFalse(sameValueAndType(RuntimeValue(DataType.UBYTE, 100), RuntimeValue(DataType.UWORD, 101))) + assertFalse(sameValueAndType(RuntimeValue(DataType.UBYTE, 100), RuntimeValue(DataType.FLOAT, 101))) + assertFalse(sameValueAndType(RuntimeValue(DataType.UWORD, 245), RuntimeValue(DataType.UBYTE, 246))) + assertFalse(sameValueAndType(RuntimeValue(DataType.UWORD, 12345), RuntimeValue(DataType.UWORD, 12346))) + assertFalse(sameValueAndType(RuntimeValue(DataType.UWORD, 12345), RuntimeValue(DataType.FLOAT, 12346))) + assertFalse(sameValueAndType(RuntimeValue(DataType.FLOAT, 9.99), RuntimeValue(DataType.UBYTE, 9))) + assertFalse(sameValueAndType(RuntimeValue(DataType.FLOAT, 9.99), RuntimeValue(DataType.UWORD, 9))) + assertFalse(sameValueAndType(RuntimeValue(DataType.FLOAT, 9.99), RuntimeValue(DataType.FLOAT, 9.0))) + } + + @Test + fun testRequireHeap() + { + assertFailsWith { RuntimeValue(DataType.STR, num = 999) } + assertFailsWith { RuntimeValue(DataType.STR_S, num=999) } + assertFailsWith { RuntimeValue(DataType.ARRAY_F, num=999) } + assertFailsWith { RuntimeValue(DataType.ARRAY_W, num=999) } + assertFailsWith { RuntimeValue(DataType.ARRAY_UW, num=999) } + assertFailsWith { RuntimeValue(DataType.ARRAY_B, num=999) } + assertFailsWith { RuntimeValue(DataType.ARRAY_UB, num=999) } + } + + @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)) + assertTrue(RuntimeValue(DataType.UWORD, 254) > RuntimeValue(DataType.UWORD, 253)) + assertTrue(RuntimeValue(DataType.FLOAT, 100.0) > RuntimeValue(DataType.FLOAT, 99.9)) + + assertTrue(RuntimeValue(DataType.UBYTE, 100) >= RuntimeValue(DataType.UBYTE, 100)) + assertTrue(RuntimeValue(DataType.UWORD, 254) >= RuntimeValue(DataType.UWORD, 254)) + assertTrue(RuntimeValue(DataType.FLOAT, 100.0) >= RuntimeValue(DataType.FLOAT, 100.0)) + + assertFalse(RuntimeValue(DataType.UBYTE, 100) > RuntimeValue(DataType.UBYTE, 100)) + assertFalse(RuntimeValue(DataType.UWORD, 254) > RuntimeValue(DataType.UWORD, 254)) + assertFalse(RuntimeValue(DataType.FLOAT, 100.0) > RuntimeValue(DataType.FLOAT, 100.0)) + + assertFalse(RuntimeValue(DataType.UBYTE, 100) >= RuntimeValue(DataType.UBYTE, 101)) + assertFalse(RuntimeValue(DataType.UWORD, 254) >= RuntimeValue(DataType.UWORD, 255)) + assertFalse(RuntimeValue(DataType.FLOAT, 100.0) >= RuntimeValue(DataType.FLOAT, 100.1)) + } + + @Test + fun testLessThan() { + assertTrue(RuntimeValue(DataType.UBYTE, 100) < RuntimeValue(DataType.UBYTE, 101)) + assertTrue(RuntimeValue(DataType.UWORD, 254) < RuntimeValue(DataType.UWORD, 255)) + assertTrue(RuntimeValue(DataType.FLOAT, 100.0) < RuntimeValue(DataType.FLOAT, 100.1)) + + assertTrue(RuntimeValue(DataType.UBYTE, 100) <= RuntimeValue(DataType.UBYTE, 100)) + assertTrue(RuntimeValue(DataType.UWORD, 254) <= RuntimeValue(DataType.UWORD, 254)) + assertTrue(RuntimeValue(DataType.FLOAT, 100.0) <= RuntimeValue(DataType.FLOAT, 100.0)) + + assertFalse(RuntimeValue(DataType.UBYTE, 100) < RuntimeValue(DataType.UBYTE, 100)) + assertFalse(RuntimeValue(DataType.UWORD, 254) < RuntimeValue(DataType.UWORD, 254)) + assertFalse(RuntimeValue(DataType.FLOAT, 100.0) < RuntimeValue(DataType.FLOAT, 100.0)) + + assertFalse(RuntimeValue(DataType.UBYTE, 100) <= RuntimeValue(DataType.UBYTE, 99)) + assertFalse(RuntimeValue(DataType.UWORD, 254) <= RuntimeValue(DataType.UWORD, 253)) + assertFalse(RuntimeValue(DataType.FLOAT, 100.0) <= RuntimeValue(DataType.FLOAT, 99.9)) + } + + @Test + fun testNoDtConversion() { + assertFailsWith { + RuntimeValue(DataType.UWORD, 100).add(RuntimeValue(DataType.UBYTE, 120)) + } + assertFailsWith { + RuntimeValue(DataType.UBYTE, 100).add(RuntimeValue(DataType.UWORD, 120)) + } + assertFailsWith { + RuntimeValue(DataType.FLOAT, 100.22).add(RuntimeValue(DataType.UWORD, 120)) + } + assertFailsWith { + RuntimeValue(DataType.UWORD, 1002).add(RuntimeValue(DataType.FLOAT, 120.22)) + } + assertFailsWith { + RuntimeValue(DataType.FLOAT, 100.22).add(RuntimeValue(DataType.UBYTE, 120)) + } + assertFailsWith { + RuntimeValue(DataType.UBYTE, 12).add(RuntimeValue(DataType.FLOAT, 120.22)) + } + } + + @Test + fun testNoAutoFloatConversion() { + assertFailsWith { + RuntimeValue(DataType.UBYTE, 233).add(RuntimeValue(DataType.FLOAT, 1.234)) + } + assertFailsWith { + RuntimeValue(DataType.UWORD, 233).add(RuntimeValue(DataType.FLOAT, 1.234)) + } + assertFailsWith { + RuntimeValue(DataType.UBYTE, 233).mul(RuntimeValue(DataType.FLOAT, 1.234)) + } + assertFailsWith { + RuntimeValue(DataType.UWORD, 233).mul(RuntimeValue(DataType.FLOAT, 1.234)) + } + assertFailsWith { + RuntimeValue(DataType.UBYTE, 233).div(RuntimeValue(DataType.FLOAT, 1.234)) + } + assertFailsWith { + RuntimeValue(DataType.UWORD, 233).div(RuntimeValue(DataType.FLOAT, 1.234)) + } + val result = RuntimeValue(DataType.FLOAT, 233.333).add(RuntimeValue(DataType.FLOAT, 1.234)) + } +} diff --git a/compiler/test/ValueOperationsTests.kt b/compiler/test/ValueOperationsTests.kt index 6e5406015..a2b46c9ab 100644 --- a/compiler/test/ValueOperationsTests.kt +++ b/compiler/test/ValueOperationsTests.kt @@ -3,8 +3,6 @@ package prog8tests import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import prog8.ast.DataType -import prog8.ast.LiteralValue -import prog8.ast.Position import prog8.compiler.intermediate.Value import prog8.compiler.intermediate.ValueException import kotlin.test.* @@ -14,10 +12,6 @@ private fun sameValueAndType(v1: Value, v2: Value): Boolean { return v1.type==v2.type && v1==v2 } -private fun sameValueAndType(lv1: LiteralValue, lv2: LiteralValue): Boolean { - return lv1.type==lv2.type && lv1==lv2 -} - @TestInstance(TestInstance.Lifecycle.PER_CLASS) class TestStackVmValue { @@ -178,122 +172,3 @@ class TestStackVmValue { val result = Value(DataType.FLOAT, 233.333).add(Value(DataType.FLOAT, 1.234)) } } - - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -class TestParserLiteralValue { - - private val dummyPos = Position("test", 0,0,0) - - @Test - fun testIdentity() { - val v = LiteralValue(DataType.UWORD, wordvalue = 12345, position = dummyPos) - assertEquals(v, v) - assertFalse(v != v) - assertTrue(v <= v) - assertTrue(v >= v) - assertFalse(v < v) - assertFalse(v > v) - - assertTrue(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue = 12345, position = dummyPos), LiteralValue(DataType.UWORD, wordvalue = 12345, position = dummyPos))) - } - - @Test - fun testEqualsAndNotEquals() { - assertEquals(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UBYTE, 100, position=dummyPos)) - assertEquals(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=100, position=dummyPos)) - assertEquals(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos)) - assertEquals(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos), LiteralValue(DataType.UBYTE, 254, position=dummyPos)) - assertEquals(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos)) - assertEquals(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=12345.0, position=dummyPos)) - assertEquals(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos), LiteralValue(DataType.UBYTE, 100, position=dummyPos)) - assertEquals(LiteralValue(DataType.FLOAT, floatvalue=22239.0, position=dummyPos), LiteralValue(DataType.UWORD,wordvalue=22239, position=dummyPos)) - assertEquals(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos)) - - assertTrue(sameValueAndType(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UBYTE, 100, position=dummyPos))) - assertFalse(sameValueAndType(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=100, position=dummyPos))) - assertFalse(sameValueAndType(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos))) - assertFalse(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos), LiteralValue(DataType.UBYTE, 254, position=dummyPos))) - assertTrue(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos))) - assertFalse(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=12345.0, position=dummyPos))) - assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos), LiteralValue(DataType.UBYTE, 100, position=dummyPos))) - assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=22239.0, position=dummyPos), LiteralValue(DataType.UWORD,wordvalue=22239, position=dummyPos))) - assertTrue(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos))) - - assertNotEquals(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UBYTE, 101, position=dummyPos)) - assertNotEquals(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=101, position=dummyPos)) - assertNotEquals(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=101.0, position=dummyPos)) - assertNotEquals(LiteralValue(DataType.UWORD, wordvalue=245, position=dummyPos), LiteralValue(DataType.UBYTE, 246, position=dummyPos)) - assertNotEquals(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=12346, position=dummyPos)) - assertNotEquals(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=12346.0, position=dummyPos)) - assertNotEquals(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.UBYTE, 9, position=dummyPos)) - assertNotEquals(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=9, position=dummyPos)) - assertNotEquals(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=9.0, position=dummyPos)) - - assertFalse(sameValueAndType(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UBYTE, 101, position=dummyPos))) - assertFalse(sameValueAndType(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=101, position=dummyPos))) - assertFalse(sameValueAndType(LiteralValue(DataType.UBYTE, 100, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=101.0, position=dummyPos))) - assertFalse(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue=245, position=dummyPos), LiteralValue(DataType.UBYTE, 246, position=dummyPos))) - assertFalse(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=12346, position=dummyPos))) - assertFalse(sameValueAndType(LiteralValue(DataType.UWORD, wordvalue=12345, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=12346.0, position=dummyPos))) - assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.UBYTE, 9, position=dummyPos))) - assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.UWORD, wordvalue=9, position=dummyPos))) - assertFalse(sameValueAndType(LiteralValue(DataType.FLOAT, floatvalue=9.99, position=dummyPos), LiteralValue(DataType.FLOAT, floatvalue=9.0, position=dummyPos))) - - assertTrue(sameValueAndType(LiteralValue(DataType.STR, strvalue = "hello", position=dummyPos), LiteralValue(DataType.STR, strvalue="hello", position=dummyPos))) - assertFalse(sameValueAndType(LiteralValue(DataType.STR, strvalue = "hello", position=dummyPos), LiteralValue(DataType.STR, strvalue="bye", position=dummyPos))) - - val lvOne = LiteralValue(DataType.UBYTE, 1, position=dummyPos) - val lvTwo = LiteralValue(DataType.UBYTE, 2, position=dummyPos) - val lvThree = LiteralValue(DataType.UBYTE, 3, position=dummyPos) - val lvOneR = LiteralValue(DataType.UBYTE, 1, position=dummyPos) - val lvTwoR = LiteralValue(DataType.UBYTE, 2, position=dummyPos) - val lvThreeR = LiteralValue(DataType.UBYTE, 3, position=dummyPos) - val lvFour= LiteralValue(DataType.UBYTE, 4, position=dummyPos) - val lv1 = LiteralValue(DataType.ARRAY_UB, arrayvalue = arrayOf(lvOne, lvTwo, lvThree), position=dummyPos) - val lv2 = LiteralValue(DataType.ARRAY_UB, arrayvalue = arrayOf(lvOneR, lvTwoR, lvThreeR), position=dummyPos) - val lv3 = LiteralValue(DataType.ARRAY_UB, arrayvalue = arrayOf(lvOneR, lvTwoR, lvFour), position=dummyPos) - assertEquals(lv1, lv2) - assertNotEquals(lv1, lv3) - } - - @Test - fun testGreaterThan(){ - assertTrue(LiteralValue(DataType.UBYTE, 100, position=dummyPos) > LiteralValue(DataType.UBYTE, 99, position=dummyPos)) - assertTrue(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) > LiteralValue(DataType.UWORD, wordvalue=253, position=dummyPos)) - assertTrue(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) > LiteralValue(DataType.FLOAT, floatvalue=99.9, position=dummyPos)) - - assertTrue(LiteralValue(DataType.UBYTE, 100, position=dummyPos) >= LiteralValue(DataType.UBYTE, 100, position=dummyPos)) - assertTrue(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) >= LiteralValue(DataType.UWORD,wordvalue= 254, position=dummyPos)) - assertTrue(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) >= LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos)) - - assertFalse(LiteralValue(DataType.UBYTE, 100, position=dummyPos) > LiteralValue(DataType.UBYTE, 100, position=dummyPos)) - assertFalse(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) > LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos)) - assertFalse(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) > LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos)) - - assertFalse(LiteralValue(DataType.UBYTE, 100, position=dummyPos) >= LiteralValue(DataType.UBYTE, 101, position=dummyPos)) - assertFalse(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) >= LiteralValue(DataType.UWORD,wordvalue= 255, position=dummyPos)) - assertFalse(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) >= LiteralValue(DataType.FLOAT, floatvalue=100.1, position=dummyPos)) - } - - @Test - fun testLessThan() { - assertTrue(LiteralValue(DataType.UBYTE, 100, position=dummyPos) < LiteralValue(DataType.UBYTE, 101, position=dummyPos)) - assertTrue(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) < LiteralValue(DataType.UWORD, wordvalue=255, position=dummyPos)) - assertTrue(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) < LiteralValue(DataType.FLOAT, floatvalue=100.1, position=dummyPos)) - - assertTrue(LiteralValue(DataType.UBYTE, 100, position=dummyPos) <= LiteralValue(DataType.UBYTE, 100, position=dummyPos)) - assertTrue(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) <= LiteralValue(DataType.UWORD,wordvalue= 254, position=dummyPos)) - assertTrue(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) <= LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos)) - - assertFalse(LiteralValue(DataType.UBYTE, 100, position=dummyPos) < LiteralValue(DataType.UBYTE, 100, position=dummyPos)) - assertFalse(LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos) < LiteralValue(DataType.UWORD, wordvalue=254, position=dummyPos)) - assertFalse(LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos) < LiteralValue(DataType.FLOAT, floatvalue=100.0, position=dummyPos)) - - assertFalse(LiteralValue(DataType.UBYTE, 100, position=dummyPos) <= LiteralValue(DataType.UBYTE, 99, position=dummyPos)) - assertFalse(LiteralValue(DataType.UWORD,wordvalue= 254, position=dummyPos) <= LiteralValue(DataType.UWORD,wordvalue= 253, position=dummyPos)) - assertFalse(LiteralValue(DataType.FLOAT,floatvalue= 100.0, position=dummyPos) <= LiteralValue(DataType.FLOAT, floatvalue=99.9, position=dummyPos)) - } - -} - diff --git a/examples/test.p8 b/examples/test.p8 index b2b548c9a..613990b8c 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -3,49 +3,106 @@ ~ main { - ubyte[256] sieve - ubyte candidate_prime = 2 ; is increased in the loop - sub start() { - memset(sieve, 256, false) ; clear the sieve, to reset starting situation on subsequent runs - ; calculate primes - c64scr.print("prime numbers up to 255:\n\n") - ubyte amount=0 - while true { - ubyte prime = find_next_prime() - if prime==0 - break - c64scr.print_ub(prime) - c64scr.print(", ") - amount++ - } - c64.CHROUT('\n') - c64scr.print("number of primes (expected 54): ") - c64scr.print_ub(amount) - c64.CHROUT('\n') - } + ubyte ub = 10 + byte bb=-100 + uword uw = 1000 + word ww = -25000 + ubyte i = 0 - - sub find_next_prime() -> ubyte { - - while sieve[candidate_prime] { - candidate_prime++ - if candidate_prime==0 - return 0 ; we wrapped; no more primes available in the sieve + while i < 100 { + bb += 10 + c64scr.print_b(bb) + c64.CHROUT(',') + i++ } - ; found next one, mark the multiples and return it. - sieve[candidate_prime] = true - uword multiple = candidate_prime - - - while multiple < len(sieve) { - sieve[lsb(multiple)] = true - multiple += candidate_prime - ; c64scr.print_uw(multiple) ; TODO - ; c4.CHROUT('\n') ; TODO - } - return candidate_prime +; c64scr.print("while1\n") +; while(ub < 220) { +; c64scr.print_ub(ub) +; c64.CHROUT(',') +; ub += 25 +; if ub < 150 continue else break +; ub=99 +; } +; c64.CHROUT('\n') +; +; c64scr.print("while2\n") +; while(bb < 120) { +; c64scr.print_b(bb) +; c64.CHROUT(',') +; bb += 25 +; if bb < 50 continue else break +; bb=99 +; } +; c64.CHROUT('\n') +; +; c64scr.print("while3\n") +; while(uw < 50000) { +; c64scr.print_uw(uw) +; c64.CHROUT(',') +; uw += 2500 +; if uw < 30000 continue else break +; uw=9999 +; } +; c64.CHROUT('\n') +; +; c64scr.print("while4\n") +; while(ww < 30000) { +; c64scr.print_w(ww) +; c64.CHROUT(',') +; ww += 2500 +; if ww < 10000 continue else break +; ww=9999 +; } +; c64.CHROUT('\n') +; c64.CHROUT('\n') +; +; ub=22 +; bb=-111 +; uw=2222 +; ww=-22222 +; +; c64scr.print("repeat1\n") +; repeat { +; c64scr.print_ub(ub) +; c64.CHROUT(',') +; ub += 22 +; ; if ub < 150 continue else break +; ;ub=99 +; } until ub>200 +; c64.CHROUT('\n') +; +; c64scr.print("repeat2\n") +; repeat { +; c64scr.print_b(bb) +; c64.CHROUT(',') +; bb += 22 +; ;if bb < 50 continue else break +; ;bb=99 +; } until bb > 100 +; c64.CHROUT('\n') +; +; c64scr.print("repeat3\n") +; repeat { +; c64scr.print_uw(uw) +; c64.CHROUT(',') +; uw += 2222 +; ;if uw < 30000 continue else break +; ;uw=9999 +; } until uw>50000 +; c64.CHROUT('\n') +; +; c64scr.print("repeat4\n") +; repeat { +; c64scr.print_w(ww) +; c64.CHROUT(',') +; ww += 2222 +; ;if ww < 10000 continue else break +; ;ww=9999 +; } until ww > 20000 +; c64.CHROUT('\n') +; c64.CHROUT('\n') } }