diff --git a/compiler/src/prog8/ast/Interfaces.kt b/compiler/src/prog8/ast/Interfaces.kt index 43f01c183..87ec29c5a 100644 --- a/compiler/src/prog8/ast/Interfaces.kt +++ b/compiler/src/prog8/ast/Interfaces.kt @@ -104,7 +104,8 @@ interface INameScope { } fun getLabelOrVariable(name: String): IStatement? { - // TODO this is called A LOT and could perhaps be optimized a bit more, but adding a cache didn't make much of a practical runtime difference + // this is called A LOT and could perhaps be optimized a bit more, + // but adding a memoization cache didn't make much of a practical runtime difference for (stmt in statements) { if (stmt is VarDecl && stmt.name==name) return stmt if (stmt is Label && stmt.name==name) return stmt diff --git a/compiler/src/prog8/vm/RuntimeValue.kt b/compiler/src/prog8/vm/RuntimeValue.kt index 573de79f3..2e30fa74f 100644 --- a/compiler/src/prog8/vm/RuntimeValue.kt +++ b/compiler/src/prog8/vm/RuntimeValue.kt @@ -72,7 +72,7 @@ open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?= } DataType.UWORD -> { val inum = num!!.toInt() - if(inum !in 0 .. 65536) + if(inum !in 0 .. 65535) throw IllegalArgumentException("invalid value for uword: $inum") wordval = inum byteval = null @@ -189,20 +189,44 @@ open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?= if(leftDt== DataType.UBYTE) RuntimeValue(DataType.UBYTE, (number xor 255) + 1) else - RuntimeValue(DataType.UBYTE, (number xor 65535) + 1) + RuntimeValue(DataType.UWORD, (number xor 65535) + 1) + } + DataType.BYTE -> { + val v=result.toInt() and 255 + if(v<128) + RuntimeValue(DataType.BYTE, v) + else + RuntimeValue(DataType.BYTE, v-256) + } + DataType.WORD -> { + val v=result.toInt() and 65535 + if(v<32768) + RuntimeValue(DataType.WORD, v) + else + RuntimeValue(DataType.WORD, v-65536) } - DataType.BYTE -> RuntimeValue(DataType.BYTE, result.toInt()) - DataType.WORD -> RuntimeValue(DataType.WORD, result.toInt()) DataType.FLOAT -> RuntimeValue(DataType.FLOAT, result) else -> throw ArithmeticException("$op on non-numeric type") } } return when(leftDt) { - DataType.UBYTE -> RuntimeValue(DataType.UBYTE, result.toInt()) - DataType.BYTE -> RuntimeValue(DataType.BYTE, result.toInt()) - DataType.UWORD -> RuntimeValue(DataType.UWORD, result.toInt()) - DataType.WORD -> RuntimeValue(DataType.WORD, result.toInt()) + DataType.UBYTE -> RuntimeValue(DataType.UBYTE, result.toInt() and 255) + DataType.BYTE -> { + val v = result.toInt() and 255 + if(v<128) + RuntimeValue(DataType.BYTE, v) + else + RuntimeValue(DataType.BYTE, v-256) + } + DataType.UWORD -> RuntimeValue(DataType.UWORD, result.toInt() and 65535) + DataType.WORD -> { + val v = result.toInt() and 65535 + if(v<32768) + RuntimeValue(DataType.WORD, v) + else + RuntimeValue(DataType.WORD, v-65536) + } DataType.FLOAT -> RuntimeValue(DataType.FLOAT, result) else -> throw ArithmeticException("$op on non-numeric type") } @@ -278,10 +302,22 @@ open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?= fun shl(): RuntimeValue { val v = integerValue() return when (type) { - DataType.UBYTE, - DataType.BYTE, - DataType.UWORD, - DataType.WORD -> RuntimeValue(type, v shl 1) + DataType.UBYTE -> RuntimeValue(type, (v shl 1) and 255) + DataType.UWORD -> RuntimeValue(type, (v shl 1) and 65535) + DataType.BYTE -> { + val value = v shl 1 + if(value<128) + RuntimeValue(type, value) + else + RuntimeValue(type, value-256) + } + DataType.WORD -> { + val value = v shl 1 + if(value<32768) + RuntimeValue(type, value) + else + RuntimeValue(type, value-65536) + } else -> throw ArithmeticException("invalid type for shl: $type") } } @@ -419,8 +455,10 @@ open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?= fun inv(): RuntimeValue { return when(type) { - in ByteDatatypes -> RuntimeValue(type, byteval!!.toInt().inv()) - in WordDatatypes -> RuntimeValue(type, wordval!!.inv()) + DataType.UBYTE -> RuntimeValue(type, byteval!!.toInt().inv() and 255) + DataType.UWORD -> RuntimeValue(type, wordval!!.inv() and 65535) + DataType.BYTE -> RuntimeValue(type, byteval!!.toInt().inv()) + DataType.WORD -> RuntimeValue(type, wordval!!.inv()) else -> throw ArithmeticException("inv can only work on byte/word") } } @@ -428,18 +466,18 @@ open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?= fun inc(): RuntimeValue { return when(type) { DataType.UBYTE -> RuntimeValue(type, (byteval!! + 1) and 255) - DataType.UWORD -> RuntimeValue(type, (byteval!! + 1) and 65535) + DataType.UWORD -> RuntimeValue(type, (wordval!! + 1) and 65535) DataType.BYTE -> { val newval = byteval!! + 1 - if(newval == 256) - RuntimeValue(type, 0) + if(newval == 128) + RuntimeValue(type, -128) else RuntimeValue(type, newval) } DataType.WORD -> { - val newval = byteval!! + 1 - if(newval == 65536) - RuntimeValue(type, 0) + val newval = wordval!! + 1 + if(newval == 32768) + RuntimeValue(type, -32768) else RuntimeValue(type, newval) } @@ -451,7 +489,7 @@ open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?= fun dec(): RuntimeValue { return when(type) { DataType.UBYTE -> RuntimeValue(type, (byteval!! - 1) and 255) - DataType.UWORD -> RuntimeValue(type, (byteval!! - 1) and 65535) + DataType.UWORD -> RuntimeValue(type, (wordval!! - 1) and 65535) DataType.BYTE -> { val newval = byteval!! - 1 if(newval == -129) @@ -460,7 +498,7 @@ open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?= RuntimeValue(type, newval) } DataType.WORD -> { - val newval = byteval!! - 1 + val newval = wordval!! - 1 if(newval == -32769) RuntimeValue(type, 32767) else @@ -484,9 +522,21 @@ open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?= DataType.UBYTE -> { when (targetType) { DataType.UBYTE -> this - DataType.BYTE -> RuntimeValue(DataType.BYTE, byteval) + DataType.BYTE -> { + val nval=byteval!!.toInt() + if(nval<128) + RuntimeValue(DataType.BYTE, nval) + else + RuntimeValue(DataType.BYTE, nval-256) + } DataType.UWORD -> RuntimeValue(DataType.UWORD, numericValue()) - DataType.WORD -> RuntimeValue(DataType.WORD, numericValue()) + DataType.WORD -> { + val nval = numericValue().toInt() + if(nval<32768) + RuntimeValue(DataType.WORD, nval) + else + RuntimeValue(DataType.WORD, nval-65536) + } DataType.FLOAT -> RuntimeValue(DataType.FLOAT, numericValue()) else -> throw ArithmeticException("invalid type cast from $type to $targetType") } @@ -494,8 +544,8 @@ open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?= DataType.BYTE -> { when (targetType) { DataType.BYTE -> this - DataType.UBYTE -> RuntimeValue(DataType.UBYTE, integerValue()) - DataType.UWORD -> RuntimeValue(DataType.UWORD, integerValue()) + DataType.UBYTE -> RuntimeValue(DataType.UBYTE, integerValue() and 255) + DataType.UWORD -> RuntimeValue(DataType.UWORD, integerValue() and 65535) DataType.WORD -> RuntimeValue(DataType.WORD, integerValue()) DataType.FLOAT -> RuntimeValue(DataType.FLOAT, numericValue()) else -> throw ArithmeticException("invalid type cast from $type to $targetType") @@ -513,8 +563,8 @@ open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?= } DataType.WORD -> { when (targetType) { - DataType.BYTE -> RuntimeValue(DataType.BYTE, integerValue()) - DataType.UBYTE -> RuntimeValue(DataType.UBYTE, integerValue()) + DataType.BYTE -> RuntimeValue(DataType.BYTE, integerValue() and 255) + DataType.UBYTE -> RuntimeValue(DataType.UBYTE, integerValue() and 65535) DataType.UWORD -> RuntimeValue(DataType.UWORD, integerValue()) DataType.WORD -> this DataType.FLOAT -> RuntimeValue(DataType.FLOAT, numericValue()) diff --git a/compiler/test/RuntimeValueTests.kt b/compiler/test/RuntimeValueTests.kt index ffbd84db3..ac8c4fbb1 100644 --- a/compiler/test/RuntimeValueTests.kt +++ b/compiler/test/RuntimeValueTests.kt @@ -17,39 +17,27 @@ 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(0, RuntimeValue(DataType.UBYTE, 0).integerValue()) + assertEquals(255, RuntimeValue(DataType.UBYTE, 255).integerValue()) + assertFailsWith { RuntimeValue(DataType.UBYTE, -1)} + assertFailsWith { RuntimeValue(DataType.UBYTE, 256)} - 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(0, RuntimeValue(DataType.BYTE, 0).integerValue()) + assertEquals(-128, RuntimeValue(DataType.BYTE, -128).integerValue()) + assertEquals(127, RuntimeValue(DataType.BYTE, 127).integerValue()) + assertFailsWith { RuntimeValue(DataType.BYTE, -129)} + assertFailsWith { RuntimeValue(DataType.BYTE, 128)} - 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(0, RuntimeValue(DataType.UWORD, 0).integerValue()) + assertEquals(65535, RuntimeValue(DataType.UWORD, 65535).integerValue()) + assertFailsWith { RuntimeValue(DataType.UWORD, -1)} + assertFailsWith { RuntimeValue(DataType.UWORD, 65536)} - 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()) + assertEquals(0, RuntimeValue(DataType.WORD, 0).integerValue()) + assertEquals(-32768, RuntimeValue(DataType.WORD, -32768).integerValue()) + assertEquals(32767, RuntimeValue(DataType.WORD, 32767).integerValue()) + assertFailsWith { RuntimeValue(DataType.WORD, -32769)} + assertFailsWith { RuntimeValue(DataType.WORD, 32768)} } @Test @@ -60,10 +48,6 @@ class TestRuntimeValue { assertFalse(RuntimeValue(DataType.WORD, 0).asBoolean) assertFalse(RuntimeValue(DataType.UWORD, 0).asBoolean) assertFalse(RuntimeValue(DataType.FLOAT, 0.0).asBoolean) - assertFalse(RuntimeValue(DataType.BYTE, 256).asBoolean) - assertFalse(RuntimeValue(DataType.UBYTE, 256).asBoolean) - assertFalse(RuntimeValue(DataType.WORD, 65536).asBoolean) - assertFalse(RuntimeValue(DataType.UWORD, 65536).asBoolean) assertTrue(RuntimeValue(DataType.BYTE, 42).asBoolean) assertTrue(RuntimeValue(DataType.UBYTE, 42).asBoolean) @@ -71,9 +55,7 @@ class TestRuntimeValue { assertTrue(RuntimeValue(DataType.UWORD, 42).asBoolean) assertTrue(RuntimeValue(DataType.FLOAT, 42.0).asBoolean) assertTrue(RuntimeValue(DataType.BYTE, -42).asBoolean) - assertTrue(RuntimeValue(DataType.UBYTE, -42).asBoolean) assertTrue(RuntimeValue(DataType.WORD, -42).asBoolean) - assertTrue(RuntimeValue(DataType.UWORD, -42).asBoolean) assertTrue(RuntimeValue(DataType.FLOAT, -42.0).asBoolean) } @@ -245,4 +227,155 @@ class TestRuntimeValue { } val result = RuntimeValue(DataType.FLOAT, 233.333).add(RuntimeValue(DataType.FLOAT, 1.234)) } + + @Test + fun arithmetictestUbyte() { + assertEquals(255, RuntimeValue(DataType.UBYTE, 200).add(RuntimeValue(DataType.UBYTE, 55)).integerValue()) + assertEquals(0, RuntimeValue(DataType.UBYTE, 200).add(RuntimeValue(DataType.UBYTE, 56)).integerValue()) + assertEquals(1, RuntimeValue(DataType.UBYTE, 200).add(RuntimeValue(DataType.UBYTE, 57)).integerValue()) + + assertEquals(1, RuntimeValue(DataType.UBYTE, 2).sub(RuntimeValue(DataType.UBYTE, 1)).integerValue()) + assertEquals(0, RuntimeValue(DataType.UBYTE, 2).sub(RuntimeValue(DataType.UBYTE, 2)).integerValue()) + assertEquals(255, RuntimeValue(DataType.UBYTE, 2).sub(RuntimeValue(DataType.UBYTE, 3)).integerValue()) + + assertEquals(255, RuntimeValue(DataType.UBYTE, 254).inc().integerValue()) + assertEquals(0, RuntimeValue(DataType.UBYTE, 255).inc().integerValue()) + assertEquals(0, RuntimeValue(DataType.UBYTE, 1).dec().integerValue()) + assertEquals(255, RuntimeValue(DataType.UBYTE, 0).dec().integerValue()) + + assertEquals(255, RuntimeValue(DataType.UBYTE, 0).inv().integerValue()) + assertEquals(0b00110011, RuntimeValue(DataType.UBYTE, 0b11001100).inv().integerValue()) +// assertEquals(0, RuntimeValue(DataType.UBYTE, 0).neg().integerValue()) +// assertEquals(0, RuntimeValue(DataType.UBYTE, 0).neg().integerValue()) + assertEquals(1, RuntimeValue(DataType.UBYTE, 0).not().integerValue()) + assertEquals(0, RuntimeValue(DataType.UBYTE, 1).not().integerValue()) + assertEquals(0, RuntimeValue(DataType.UBYTE, 111).not().integerValue()) + assertEquals(0, RuntimeValue(DataType.UBYTE, 255).not().integerValue()) + + assertEquals(200, RuntimeValue(DataType.UBYTE, 20).mul(RuntimeValue(DataType.UBYTE, 10)).integerValue()) + assertEquals(144, RuntimeValue(DataType.UBYTE, 20).mul(RuntimeValue(DataType.UBYTE, 20)).integerValue()) + + assertEquals(25, RuntimeValue(DataType.UBYTE, 5).pow(RuntimeValue(DataType.UBYTE, 2)).integerValue()) + assertEquals(125, RuntimeValue(DataType.UBYTE, 5).pow(RuntimeValue(DataType.UBYTE, 3)).integerValue()) + assertEquals(113, RuntimeValue(DataType.UBYTE, 5).pow(RuntimeValue(DataType.UBYTE, 4)).integerValue()) + + assertEquals(100, RuntimeValue(DataType.UBYTE, 50).shl().integerValue()) + assertEquals(200, RuntimeValue(DataType.UBYTE, 100).shl().integerValue()) + assertEquals(144, RuntimeValue(DataType.UBYTE, 200).shl().integerValue()) + } + + @Test + fun arithmetictestUWord() { + assertEquals(65535, RuntimeValue(DataType.UWORD, 60000).add(RuntimeValue(DataType.UWORD, 5535)).integerValue()) + assertEquals(0, RuntimeValue(DataType.UWORD, 60000).add(RuntimeValue(DataType.UWORD, 5536)).integerValue()) + assertEquals(1, RuntimeValue(DataType.UWORD, 60000).add(RuntimeValue(DataType.UWORD, 5537)).integerValue()) + + assertEquals(1, RuntimeValue(DataType.UWORD, 2).sub(RuntimeValue(DataType.UWORD, 1)).integerValue()) + assertEquals(0, RuntimeValue(DataType.UWORD, 2).sub(RuntimeValue(DataType.UWORD, 2)).integerValue()) + assertEquals(65535, RuntimeValue(DataType.UWORD, 2).sub(RuntimeValue(DataType.UWORD, 3)).integerValue()) + + assertEquals(65535, RuntimeValue(DataType.UWORD, 65534).inc().integerValue()) + assertEquals(0, RuntimeValue(DataType.UWORD, 65535).inc().integerValue()) + assertEquals(0, RuntimeValue(DataType.UWORD, 1).dec().integerValue()) + assertEquals(65535, RuntimeValue(DataType.UWORD, 0).dec().integerValue()) + + assertEquals(65535, RuntimeValue(DataType.UWORD, 0).inv().integerValue()) + assertEquals(0b0011001101010101, RuntimeValue(DataType.UWORD, 0b1100110010101010).inv().integerValue()) +// assertEquals(0, RuntimeValue(DataType.UWORD, 0).neg().integerValue()) +// assertEquals(0, RuntimeValue(DataType.UWORD, 0).neg().integerValue()) + assertEquals(1, RuntimeValue(DataType.UWORD, 0).not().integerValue()) + assertEquals(0, RuntimeValue(DataType.UWORD, 1).not().integerValue()) + assertEquals(0, RuntimeValue(DataType.UWORD, 11111).not().integerValue()) + assertEquals(0, RuntimeValue(DataType.UWORD, 65535).not().integerValue()) + + assertEquals(2000, RuntimeValue(DataType.UWORD, 200).mul(RuntimeValue(DataType.UWORD, 10)).integerValue()) + assertEquals(40000, RuntimeValue(DataType.UWORD, 200).mul(RuntimeValue(DataType.UWORD, 200)).integerValue()) + assertEquals(14464, RuntimeValue(DataType.UWORD, 200).mul(RuntimeValue(DataType.UWORD, 400)).integerValue()) + + assertEquals(15625, RuntimeValue(DataType.UWORD, 5).pow(RuntimeValue(DataType.UWORD, 6)).integerValue()) + assertEquals(12589, RuntimeValue(DataType.UWORD, 5).pow(RuntimeValue(DataType.UWORD, 7)).integerValue()) + + assertEquals(10000, RuntimeValue(DataType.UWORD, 5000).shl().integerValue()) + assertEquals(60000, RuntimeValue(DataType.UWORD, 30000).shl().integerValue()) + assertEquals(14464, RuntimeValue(DataType.UWORD, 40000).shl().integerValue()) + } + + @Test + fun arithmetictestByte() { + assertEquals(127, RuntimeValue(DataType.BYTE, 100).add(RuntimeValue(DataType.BYTE, 27)).integerValue()) + assertEquals(-128, RuntimeValue(DataType.BYTE, 100).add(RuntimeValue(DataType.BYTE, 28)).integerValue()) + assertEquals(-127, RuntimeValue(DataType.BYTE, 100).add(RuntimeValue(DataType.BYTE, 29)).integerValue()) + + assertEquals(1, RuntimeValue(DataType.BYTE, 2).sub(RuntimeValue(DataType.BYTE, 1)).integerValue()) + assertEquals(0, RuntimeValue(DataType.BYTE, 2).sub(RuntimeValue(DataType.BYTE, 2)).integerValue()) + assertEquals(-1, RuntimeValue(DataType.BYTE, 2).sub(RuntimeValue(DataType.BYTE, 3)).integerValue()) + assertEquals(-128, RuntimeValue(DataType.BYTE, -100).sub(RuntimeValue(DataType.BYTE, 28)).integerValue()) + assertEquals(127, RuntimeValue(DataType.BYTE, -100).sub(RuntimeValue(DataType.BYTE, 29)).integerValue()) + + assertEquals(127, RuntimeValue(DataType.BYTE, 126).inc().integerValue()) + assertEquals(-128, RuntimeValue(DataType.BYTE, 127).inc().integerValue()) + assertEquals(0, RuntimeValue(DataType.BYTE, 1).dec().integerValue()) + assertEquals(-1, RuntimeValue(DataType.BYTE, 0).dec().integerValue()) + assertEquals(-128, RuntimeValue(DataType.BYTE, -127).dec().integerValue()) + assertEquals(127, RuntimeValue(DataType.BYTE, -128).dec().integerValue()) + + assertEquals(-1, RuntimeValue(DataType.BYTE, 0).inv().integerValue()) + assertEquals(-103, RuntimeValue(DataType.BYTE, 0b01100110).inv().integerValue()) + assertEquals(0, RuntimeValue(DataType.BYTE, 0).neg().integerValue()) + assertEquals(-2, RuntimeValue(DataType.BYTE, 2).neg().integerValue()) + assertEquals(1, RuntimeValue(DataType.BYTE, 0).not().integerValue()) + assertEquals(0, RuntimeValue(DataType.BYTE, 1).not().integerValue()) + assertEquals(0, RuntimeValue(DataType.BYTE, 111).not().integerValue()) + assertEquals(0, RuntimeValue(DataType.BYTE, -33).not().integerValue()) + + assertEquals(100, RuntimeValue(DataType.BYTE, 10).mul(RuntimeValue(DataType.BYTE, 10)).integerValue()) + assertEquals(-56, RuntimeValue(DataType.BYTE, 20).mul(RuntimeValue(DataType.BYTE, 10)).integerValue()) + + assertEquals(25, RuntimeValue(DataType.BYTE, 5).pow(RuntimeValue(DataType.BYTE, 2)).integerValue()) + assertEquals(125, RuntimeValue(DataType.BYTE, 5).pow(RuntimeValue(DataType.BYTE, 3)).integerValue()) + assertEquals(113, RuntimeValue(DataType.BYTE, 5).pow(RuntimeValue(DataType.BYTE, 4)).integerValue()) + + assertEquals(100, RuntimeValue(DataType.BYTE, 50).shl().integerValue()) + assertEquals(-56, RuntimeValue(DataType.BYTE, 100).shl().integerValue()) + assertEquals(-2, RuntimeValue(DataType.BYTE, -1).shl().integerValue()) + } + + @Test + fun arithmetictestWorrd() { + assertEquals(32767, RuntimeValue(DataType.WORD, 32700).add(RuntimeValue(DataType.WORD, 67)).integerValue()) + assertEquals(-32768, RuntimeValue(DataType.WORD, 32700).add(RuntimeValue(DataType.WORD, 68)).integerValue()) + assertEquals(-32767, RuntimeValue(DataType.WORD, 32700).add(RuntimeValue(DataType.WORD, 69)).integerValue()) + + assertEquals(1, RuntimeValue(DataType.WORD, 2).sub(RuntimeValue(DataType.WORD, 1)).integerValue()) + assertEquals(0, RuntimeValue(DataType.WORD, 2).sub(RuntimeValue(DataType.WORD, 2)).integerValue()) + assertEquals(-1, RuntimeValue(DataType.WORD, 2).sub(RuntimeValue(DataType.WORD, 3)).integerValue()) + assertEquals(-32768, RuntimeValue(DataType.WORD, -32700).sub(RuntimeValue(DataType.WORD, 68)).integerValue()) + assertEquals(32767, RuntimeValue(DataType.WORD, -32700).sub(RuntimeValue(DataType.WORD, 69)).integerValue()) + + assertEquals(32767, RuntimeValue(DataType.WORD, 32766).inc().integerValue()) + assertEquals(-32768, RuntimeValue(DataType.WORD, 32767).inc().integerValue()) + assertEquals(0, RuntimeValue(DataType.WORD, 1).dec().integerValue()) + assertEquals(-1, RuntimeValue(DataType.WORD, 0).dec().integerValue()) + assertEquals(-32768, RuntimeValue(DataType.WORD, -32767).dec().integerValue()) + assertEquals(32767, RuntimeValue(DataType.WORD, -32768).dec().integerValue()) + + assertEquals(-1, RuntimeValue(DataType.WORD, 0).inv().integerValue()) + assertEquals(-103, RuntimeValue(DataType.WORD, 0b01100110).inv().integerValue()) + assertEquals(0, RuntimeValue(DataType.WORD, 0).neg().integerValue()) + assertEquals(-2, RuntimeValue(DataType.WORD, 2).neg().integerValue()) + assertEquals(1, RuntimeValue(DataType.WORD, 0).not().integerValue()) + assertEquals(0, RuntimeValue(DataType.WORD, 1).not().integerValue()) + assertEquals(0, RuntimeValue(DataType.WORD, 111).not().integerValue()) + assertEquals(0, RuntimeValue(DataType.WORD, -33).not().integerValue()) + + assertEquals(10000, RuntimeValue(DataType.WORD, 100).mul(RuntimeValue(DataType.WORD, 100)).integerValue()) + assertEquals(-25536, RuntimeValue(DataType.WORD, 200).mul(RuntimeValue(DataType.WORD, 200)).integerValue()) + + assertEquals(15625, RuntimeValue(DataType.WORD, 5).pow(RuntimeValue(DataType.WORD, 6)).integerValue()) + assertEquals(-6487, RuntimeValue(DataType.WORD, 9).pow(RuntimeValue(DataType.WORD, 5)).integerValue()) + + assertEquals(18000, RuntimeValue(DataType.WORD, 9000).shl().integerValue()) + assertEquals(-25536, RuntimeValue(DataType.WORD, 20000).shl().integerValue()) + assertEquals(-2, RuntimeValue(DataType.WORD, -1).shl().integerValue()) + } } diff --git a/compiler/test/StackVMOpcodeTests.kt b/compiler/test/StackVMOpcodeTests.kt index f4ba615ba..047632395 100644 --- a/compiler/test/StackVMOpcodeTests.kt +++ b/compiler/test/StackVMOpcodeTests.kt @@ -413,10 +413,10 @@ class TestStackVmOpcodes { testUnaryOperator(RuntimeValue(DataType.UBYTE, 123), Opcode.INV_BYTE, RuntimeValue(DataType.UBYTE, 0x84)) testUnaryOperator(RuntimeValue(DataType.UWORD, 4044), Opcode.INV_WORD, RuntimeValue(DataType.UWORD, 0xf033)) assertFailsWith { - testUnaryOperator(RuntimeValue(DataType.BYTE, 123), Opcode.INV_BYTE, RuntimeValue(DataType.BYTE, 0x84)) + testUnaryOperator(RuntimeValue(DataType.BYTE, 123), Opcode.INV_BYTE, RuntimeValue(DataType.BYTE, -124)) } assertFailsWith { - testUnaryOperator(RuntimeValue(DataType.WORD, 4044), Opcode.INV_WORD, RuntimeValue(DataType.WORD, 0xf033)) + testUnaryOperator(RuntimeValue(DataType.WORD, 4044), Opcode.INV_WORD, RuntimeValue(DataType.WORD, -4043)) } }