fix integer wraparounds for RuntimeValue

This commit is contained in:
Irmen de Jong 2019-06-24 22:18:50 +02:00
parent eb25b4c800
commit 4bac5043b6
6 changed files with 530 additions and 215 deletions

View File

@ -52,6 +52,7 @@ class AstVm(val program: Program) {
var P_irqd: Boolean = false var P_irqd: Boolean = false
private set private set
private var dialog = ScreenDialog() private var dialog = ScreenDialog()
var instructionCounter = 0
init { init {
dialog.requestFocusInWindow() dialog.requestFocusInWindow()
@ -129,7 +130,9 @@ class AstVm(val program: Program) {
} }
private fun executeStatement(sub: INameScope, stmt: IStatement) { private fun executeStatement(sub: INameScope, stmt: IStatement) {
Thread.sleep(10) instructionCounter++
if(instructionCounter % 10 == 0)
Thread.sleep(1)
when (stmt) { when (stmt) {
is NopStatement, is Label, is Subroutine -> { is NopStatement, is Label, is Subroutine -> {
// do nothing, skip this instruction // do nothing, skip this instruction
@ -333,9 +336,25 @@ class AstVm(val program: Program) {
"c64scr.print_ub" -> { "c64scr.print_ub" -> {
dialog.canvas.printText(args[0].byteval!!.toString(), 1, true) 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" -> { "c64scr.print_uw" -> {
dialog.canvas.printText(args[0].wordval!!.toString(), 1, true) 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" -> { "c64.CHROUT" -> {
dialog.canvas.printChar(args[0].byteval!!) dialog.canvas.printChar(args[0].byteval!!)
} }

View File

@ -46,33 +46,27 @@ class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null,
init { init {
when(type) { when(type) {
DataType.UBYTE -> { DataType.UBYTE -> {
byteval = num!!.toShort() byteval = (num!!.toInt() and 255).toShort()
if(byteval !in 0..255)
throw ArithmeticException("value out of range: $num")
wordval = null wordval = null
floatval = null floatval = null
asBooleanRuntimeValue = num != 0 asBooleanRuntimeValue = byteval != 0.toShort()
} }
DataType.BYTE -> { DataType.BYTE -> {
byteval = num!!.toShort() val v = num!!.toInt() and 255
if(byteval !in -128..127) byteval = (if(v<128) v else v-256).toShort()
throw ArithmeticException("value out of range: $num")
wordval = null wordval = null
floatval = null floatval = null
asBooleanRuntimeValue = num != 0 asBooleanRuntimeValue = byteval != 0.toShort()
} }
DataType.UWORD -> { DataType.UWORD -> {
wordval = num!!.toInt() wordval = num!!.toInt() and 65535
if(wordval !in 0..65535)
throw ArithmeticException("value out of range: $num")
byteval = null byteval = null
floatval = null floatval = null
asBooleanRuntimeValue = wordval != 0 asBooleanRuntimeValue = wordval != 0
} }
DataType.WORD -> { DataType.WORD -> {
wordval = num!!.toInt() val v = num!!.toInt() and 65535
if(wordval !in -32768..32767) wordval = if(v<32768) v else v - 65536
throw ArithmeticException("value out of range: $num")
byteval = null byteval = null
floatval = null floatval = null
asBooleanRuntimeValue = wordval != 0 asBooleanRuntimeValue = wordval != 0
@ -85,7 +79,7 @@ class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null,
} }
else -> { else -> {
if(heapId==null) 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 byteval = null
wordval = null wordval = null
floatval = 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.UBYTE -> "ub:%02x".format(byteval)
DataType.BYTE -> { DataType.BYTE -> {
if(byteval!!<0) if(byteval!!<0)
"b:-%02x".format(abs(byteval!!.toInt())) "b:-%02x".format(abs(byteval.toInt()))
else else
"b:%02x".format(byteval) "b:%02x".format(byteval)
} }
DataType.UWORD -> "uw:%04x".format(wordval) DataType.UWORD -> "uw:%04x".format(wordval)
DataType.WORD -> { DataType.WORD -> {
if(wordval!!<0) if(wordval!!<0)
"w:-%04x".format(abs(wordval!!)) "w:-%04x".format(abs(wordval))
else else
"w:%04x".format(wordval) "w:%04x".format(wordval)
} }
@ -175,9 +169,9 @@ class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null,
} }
return when(leftDt) { 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.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.WORD -> RuntimeValue(DataType.WORD, result.toInt())
DataType.FLOAT -> RuntimeValue(DataType.FLOAT, result) DataType.FLOAT -> RuntimeValue(DataType.FLOAT, result)
else -> throw ArithmeticException("$op on non-numeric type") 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 { fun shl(): RuntimeValue {
val v = integerValue() val v = integerValue()
return when (type) { return when (type) {
DataType.UBYTE -> return RuntimeValue(type, (v shl 1) and 255) DataType.UBYTE,
DataType.BYTE -> { DataType.BYTE,
if(v<0) DataType.UWORD,
RuntimeValue(type, -((-v shl 1) and 255)) DataType.WORD -> RuntimeValue(type, v shl 1)
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)
}
else -> throw ArithmeticException("invalid type for shl: $type") 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 { fun shr(): RuntimeValue {
val v = integerValue() val v = integerValue()
return when(type){ 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.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) DataType.WORD -> RuntimeValue(type, v shr 1)
else -> throw ArithmeticException("invalid type for shr: $type") 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 { fun inv(): RuntimeValue {
return when(type) { return when(type) {
DataType.UBYTE -> RuntimeValue(DataType.UBYTE, byteval!!.toInt().inv() and 255) DataType.UBYTE -> RuntimeValue(DataType.UBYTE, byteval!!.toInt().inv())
DataType.UWORD -> RuntimeValue(DataType.UWORD, wordval!!.inv() and 65535) DataType.UWORD -> RuntimeValue(DataType.UWORD, wordval!!.inv())
else -> throw ArithmeticException("inv can only work on byte/word") else -> throw ArithmeticException("inv can only work on byte/word")
} }
} }
fun inc(): RuntimeValue { fun inc(): RuntimeValue {
return when(type) { return when(type) {
DataType.UBYTE -> RuntimeValue(DataType.UBYTE, (byteval!! + 1) and 255) DataType.UBYTE -> RuntimeValue(DataType.UBYTE, byteval!! + 1)
DataType.UWORD -> RuntimeValue(DataType.UWORD, (wordval!! + 1) and 65535) DataType.UWORD -> RuntimeValue(DataType.UWORD, wordval!! + 1)
DataType.FLOAT -> RuntimeValue(DataType.FLOAT, floatval!! + 1) DataType.FLOAT -> RuntimeValue(DataType.FLOAT, floatval!! + 1)
else -> throw ArithmeticException("inc can only work on byte/word/float") 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 { fun dec(): RuntimeValue {
return when(type) { return when(type) {
DataType.UBYTE -> RuntimeValue(DataType.UBYTE, (byteval!! - 1) and 255) DataType.UBYTE -> RuntimeValue(DataType.UBYTE, byteval!! - 1)
DataType.UWORD -> RuntimeValue(DataType.UWORD, (wordval!! - 1) and 65535) DataType.UWORD -> RuntimeValue(DataType.UWORD, wordval!! - 1)
DataType.FLOAT -> RuntimeValue(DataType.FLOAT, floatval!! - 1) DataType.FLOAT -> RuntimeValue(DataType.FLOAT, floatval!! - 1)
else -> throw ArithmeticException("dec can only work on byte/word/float") 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.UBYTE -> this
DataType.BYTE -> { DataType.BYTE -> {
if(byteval!!<=127) if(byteval!!<=127)
RuntimeValue(DataType.BYTE, byteval!!) RuntimeValue(DataType.BYTE, byteval)
else else
RuntimeValue(DataType.BYTE, -(256-byteval!!)) RuntimeValue(DataType.BYTE, -(256-byteval))
} }
DataType.UWORD -> RuntimeValue(DataType.UWORD, numericValue()) DataType.UWORD -> RuntimeValue(DataType.UWORD, numericValue())
DataType.WORD -> RuntimeValue(DataType.WORD, 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 -> { DataType.BYTE -> {
when (targetType) { when (targetType) {
DataType.BYTE -> this DataType.BYTE -> this
DataType.UBYTE -> RuntimeValue(DataType.UBYTE, integerValue() and 255) DataType.UBYTE -> RuntimeValue(DataType.UBYTE, integerValue())
DataType.UWORD -> RuntimeValue(DataType.UWORD, integerValue() and 65535) DataType.UWORD -> RuntimeValue(DataType.UWORD, integerValue())
DataType.WORD -> RuntimeValue(DataType.WORD, integerValue()) DataType.WORD -> RuntimeValue(DataType.WORD, integerValue())
DataType.FLOAT -> RuntimeValue(DataType.FLOAT, numericValue()) DataType.FLOAT -> RuntimeValue(DataType.FLOAT, numericValue())
else -> throw ArithmeticException("invalid type cast from $type to $targetType") 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 -> { DataType.UWORD -> {
when (targetType) { when (targetType) {
in ByteDatatypes -> RuntimeValue(DataType.UBYTE, integerValue() and 255) in ByteDatatypes -> RuntimeValue(DataType.UBYTE, integerValue())
DataType.UWORD -> this DataType.UWORD -> this
DataType.WORD -> { DataType.WORD -> {
if(integerValue()<=32767) if(integerValue()<=32767)
@ -480,8 +464,8 @@ class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=null,
} }
DataType.WORD -> { DataType.WORD -> {
when (targetType) { when (targetType) {
in ByteDatatypes -> RuntimeValue(DataType.UBYTE, integerValue() and 255) in ByteDatatypes -> RuntimeValue(DataType.UBYTE, integerValue())
DataType.UWORD -> RuntimeValue(DataType.UWORD, integerValue() and 65535) DataType.UWORD -> RuntimeValue(DataType.UWORD, integerValue())
DataType.WORD -> this DataType.WORD -> this
DataType.FLOAT -> RuntimeValue(DataType.FLOAT, numericValue()) DataType.FLOAT -> RuntimeValue(DataType.FLOAT, numericValue())
else -> throw ArithmeticException("invalid type cast from $type to $targetType") 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 else
throw ArithmeticException("overflow when casting float to byte: $this") throw ArithmeticException("overflow when casting float to byte: $this")
} }
DataType.UBYTE -> RuntimeValue(DataType.UBYTE, numericValue().toInt() and 255) DataType.UBYTE -> RuntimeValue(DataType.UBYTE, numericValue().toInt())
DataType.UWORD -> RuntimeValue(DataType.UWORD, numericValue().toInt() and 65535) DataType.UWORD -> RuntimeValue(DataType.UWORD, numericValue().toInt())
DataType.WORD -> { DataType.WORD -> {
val integer=numericValue().toInt() val integer=numericValue().toInt()
if(integer in -32768..32767) if(integer in -32768..32767)

View File

@ -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))
}
}

View File

@ -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(v<v)
assertFalse(v>v)
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<IllegalArgumentException> { RuntimeValue(DataType.STR, num = 999) }
assertFailsWith<IllegalArgumentException> { RuntimeValue(DataType.STR_S, num=999) }
assertFailsWith<IllegalArgumentException> { RuntimeValue(DataType.ARRAY_F, num=999) }
assertFailsWith<IllegalArgumentException> { RuntimeValue(DataType.ARRAY_W, num=999) }
assertFailsWith<IllegalArgumentException> { RuntimeValue(DataType.ARRAY_UW, num=999) }
assertFailsWith<IllegalArgumentException> { RuntimeValue(DataType.ARRAY_B, num=999) }
assertFailsWith<IllegalArgumentException> { 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<ArithmeticException> {
RuntimeValue(DataType.UWORD, 100).add(RuntimeValue(DataType.UBYTE, 120))
}
assertFailsWith<ArithmeticException> {
RuntimeValue(DataType.UBYTE, 100).add(RuntimeValue(DataType.UWORD, 120))
}
assertFailsWith<ArithmeticException> {
RuntimeValue(DataType.FLOAT, 100.22).add(RuntimeValue(DataType.UWORD, 120))
}
assertFailsWith<ArithmeticException> {
RuntimeValue(DataType.UWORD, 1002).add(RuntimeValue(DataType.FLOAT, 120.22))
}
assertFailsWith<ArithmeticException> {
RuntimeValue(DataType.FLOAT, 100.22).add(RuntimeValue(DataType.UBYTE, 120))
}
assertFailsWith<ArithmeticException> {
RuntimeValue(DataType.UBYTE, 12).add(RuntimeValue(DataType.FLOAT, 120.22))
}
}
@Test
fun testNoAutoFloatConversion() {
assertFailsWith<ArithmeticException> {
RuntimeValue(DataType.UBYTE, 233).add(RuntimeValue(DataType.FLOAT, 1.234))
}
assertFailsWith<ArithmeticException> {
RuntimeValue(DataType.UWORD, 233).add(RuntimeValue(DataType.FLOAT, 1.234))
}
assertFailsWith<ArithmeticException> {
RuntimeValue(DataType.UBYTE, 233).mul(RuntimeValue(DataType.FLOAT, 1.234))
}
assertFailsWith<ArithmeticException> {
RuntimeValue(DataType.UWORD, 233).mul(RuntimeValue(DataType.FLOAT, 1.234))
}
assertFailsWith<ArithmeticException> {
RuntimeValue(DataType.UBYTE, 233).div(RuntimeValue(DataType.FLOAT, 1.234))
}
assertFailsWith<ArithmeticException> {
RuntimeValue(DataType.UWORD, 233).div(RuntimeValue(DataType.FLOAT, 1.234))
}
val result = RuntimeValue(DataType.FLOAT, 233.333).add(RuntimeValue(DataType.FLOAT, 1.234))
}
}

View File

@ -3,8 +3,6 @@ package prog8tests
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance
import prog8.ast.DataType import prog8.ast.DataType
import prog8.ast.LiteralValue
import prog8.ast.Position
import prog8.compiler.intermediate.Value import prog8.compiler.intermediate.Value
import prog8.compiler.intermediate.ValueException import prog8.compiler.intermediate.ValueException
import kotlin.test.* import kotlin.test.*
@ -14,10 +12,6 @@ private fun sameValueAndType(v1: Value, v2: Value): Boolean {
return v1.type==v2.type && v1==v2 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) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
class TestStackVmValue { class TestStackVmValue {
@ -178,122 +172,3 @@ class TestStackVmValue {
val result = Value(DataType.FLOAT, 233.333).add(Value(DataType.FLOAT, 1.234)) 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))
}
}

View File

@ -3,49 +3,106 @@
~ main { ~ main {
ubyte[256] sieve
ubyte candidate_prime = 2 ; is increased in the loop
sub start() { sub start() {
memset(sieve, 256, false) ; clear the sieve, to reset starting situation on subsequent runs
; calculate primes ubyte ub = 10
c64scr.print("prime numbers up to 255:\n\n") byte bb=-100
ubyte amount=0 uword uw = 1000
while true { word ww = -25000
ubyte prime = find_next_prime() ubyte i = 0
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')
}
while i < 100 {
sub find_next_prime() -> ubyte { bb += 10
c64scr.print_b(bb)
while sieve[candidate_prime] { c64.CHROUT(',')
candidate_prime++ i++
if candidate_prime==0
return 0 ; we wrapped; no more primes available in the sieve
} }
; found next one, mark the multiples and return it. ; c64scr.print("while1\n")
sieve[candidate_prime] = true ; while(ub < 220) {
uword multiple = candidate_prime ; c64scr.print_ub(ub)
; c64.CHROUT(',')
; ub += 25
while multiple < len(sieve) { ; if ub < 150 continue else break
sieve[lsb(multiple)] = true ; ub=99
multiple += candidate_prime ; }
; c64scr.print_uw(multiple) ; TODO ; c64.CHROUT('\n')
; c4.CHROUT('\n') ; TODO ;
} ; c64scr.print("while2\n")
return candidate_prime ; 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')
} }
} }