mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
PtNumber can now be compared
This commit is contained in:
parent
b6eb343234
commit
3f6393f732
@ -3,6 +3,8 @@ package prog8.code.ast
|
||||
import prog8.code.core.DataType
|
||||
import prog8.code.core.Encoding
|
||||
import prog8.code.core.Position
|
||||
import java.util.*
|
||||
import kotlin.math.round
|
||||
|
||||
|
||||
sealed class PtExpression(val type: DataType, position: Position) : PtNode(position) {
|
||||
@ -26,7 +28,14 @@ class PtArrayIndexer(type: DataType, position: Position): PtExpression(type, pos
|
||||
}
|
||||
|
||||
|
||||
class PtArray(type: DataType, position: Position): PtExpression(type, position)
|
||||
class PtArray(type: DataType, position: Position): PtExpression(type, position) {
|
||||
override fun hashCode(): Int = Objects.hash(children, type)
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if(other==null || other !is PtArray)
|
||||
return false
|
||||
return type==other.type && children == other.children
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtBuiltinFunctionCall(val name: String, val void: Boolean, type: DataType, position: Position) : PtExpression(type, position) {
|
||||
@ -95,9 +104,28 @@ class PtMemoryByte(position: Position) : PtExpression(DataType.UBYTE, position)
|
||||
|
||||
|
||||
class PtNumber(type: DataType, val number: Double, position: Position) : PtExpression(type, position) {
|
||||
|
||||
init {
|
||||
if(type!=DataType.FLOAT) {
|
||||
val rounded = round(number)
|
||||
if (rounded != number)
|
||||
throw IllegalArgumentException("refused rounding of float to avoid loss of precision")
|
||||
}
|
||||
}
|
||||
|
||||
override fun printProperties() {
|
||||
print("$number ($type)")
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = Objects.hash(type, number)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if(other==null || other !is PtNumber)
|
||||
return false
|
||||
return number==other.number
|
||||
}
|
||||
|
||||
operator fun compareTo(other: PtNumber): Int = number.compareTo(other.number)
|
||||
}
|
||||
|
||||
|
||||
@ -140,6 +168,13 @@ class PtString(val value: String, val encoding: Encoding, position: Position) :
|
||||
override fun printProperties() {
|
||||
print("$encoding:\"$value\"")
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = Objects.hash(value, encoding)
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if(other==null || other !is PtString)
|
||||
return false
|
||||
return value==other.value && encoding == other.encoding
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
156
compiler/test/TestPtNumber.kt
Normal file
156
compiler/test/TestPtNumber.kt
Normal file
@ -0,0 +1,156 @@
|
||||
package prog8tests
|
||||
|
||||
import io.kotest.assertions.throwables.shouldThrow
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.kotest.matchers.shouldNotBe
|
||||
import io.kotest.matchers.string.shouldContain
|
||||
import prog8.code.ast.PtArray
|
||||
import prog8.code.ast.PtNumber
|
||||
import prog8.code.ast.PtString
|
||||
import prog8.code.core.DataType
|
||||
import prog8.code.core.Encoding
|
||||
import prog8.code.core.Position
|
||||
|
||||
|
||||
class TestPtNumber: FunSpec({
|
||||
|
||||
fun sameValueAndType(lv1: PtNumber, lv2: PtNumber): Boolean {
|
||||
return lv1.type==lv2.type && lv1==lv2
|
||||
}
|
||||
|
||||
val dummyPos = Position("test", 0, 0, 0)
|
||||
|
||||
test("testIdentity") {
|
||||
val v = PtNumber(DataType.UWORD, 12345.0, dummyPos)
|
||||
(v==v) shouldBe true
|
||||
(v != v) shouldBe false
|
||||
(v <= v) shouldBe true
|
||||
(v >= v) shouldBe true
|
||||
(v < v ) shouldBe false
|
||||
(v > v ) shouldBe false
|
||||
|
||||
sameValueAndType(PtNumber(DataType.UWORD, 12345.0, dummyPos), PtNumber(DataType.UWORD, 12345.0, dummyPos)) shouldBe true
|
||||
}
|
||||
|
||||
test("test rounding") {
|
||||
shouldThrow<IllegalArgumentException> {
|
||||
PtNumber(DataType.BYTE, -2.345, dummyPos)
|
||||
}.message shouldContain "refused rounding"
|
||||
shouldThrow<IllegalArgumentException> {
|
||||
PtNumber(DataType.BYTE, -2.6, dummyPos)
|
||||
}.message shouldContain "refused rounding"
|
||||
shouldThrow<IllegalArgumentException> {
|
||||
PtNumber(DataType.UWORD, 2222.345, dummyPos)
|
||||
}.message shouldContain "refused rounding"
|
||||
PtNumber(DataType.UBYTE, 2.0, dummyPos).number shouldBe 2.0
|
||||
PtNumber(DataType.BYTE, -2.0, dummyPos).number shouldBe -2.0
|
||||
PtNumber(DataType.UWORD, 2222.0, dummyPos).number shouldBe 2222.0
|
||||
PtNumber(DataType.FLOAT, 123.456, dummyPos)
|
||||
}
|
||||
|
||||
test("testEqualsAndNotEquals") {
|
||||
(PtNumber(DataType.UBYTE, 100.0, dummyPos) == PtNumber(DataType.UBYTE, 100.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.UBYTE, 100.0, dummyPos) == PtNumber(DataType.UWORD, 100.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.UBYTE, 100.0, dummyPos) == PtNumber(DataType.FLOAT, 100.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.UWORD, 254.0, dummyPos) == PtNumber(DataType.UBYTE, 254.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.UWORD, 12345.0, dummyPos) == PtNumber(DataType.UWORD, 12345.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.UWORD, 12345.0, dummyPos) == PtNumber(DataType.FLOAT, 12345.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.FLOAT, 100.0, dummyPos) == PtNumber(DataType.UBYTE, 100.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.FLOAT, 22239.0, dummyPos) == PtNumber(DataType.UWORD, 22239.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.FLOAT, 9.99, dummyPos) == PtNumber(DataType.FLOAT, 9.99, dummyPos)) shouldBe true
|
||||
|
||||
sameValueAndType(PtNumber(DataType.UBYTE, 100.0, dummyPos), PtNumber(DataType.UBYTE, 100.0, dummyPos)) shouldBe true
|
||||
sameValueAndType(PtNumber(DataType.UBYTE, 100.0, dummyPos), PtNumber(DataType.UWORD, 100.0, dummyPos)) shouldBe false
|
||||
sameValueAndType(PtNumber(DataType.UBYTE, 100.0, dummyPos), PtNumber(DataType.FLOAT, 100.0, dummyPos)) shouldBe false
|
||||
sameValueAndType(PtNumber(DataType.UWORD, 254.0, dummyPos), PtNumber(DataType.UBYTE, 254.0, dummyPos)) shouldBe false
|
||||
sameValueAndType(PtNumber(DataType.UWORD, 12345.0, dummyPos), PtNumber(DataType.UWORD, 12345.0, dummyPos)) shouldBe true
|
||||
sameValueAndType(PtNumber(DataType.UWORD, 12345.0, dummyPos), PtNumber(DataType.FLOAT, 12345.0, dummyPos)) shouldBe false
|
||||
sameValueAndType(PtNumber(DataType.FLOAT, 100.0, dummyPos), PtNumber(DataType.UBYTE, 100.0, dummyPos)) shouldBe false
|
||||
sameValueAndType(PtNumber(DataType.FLOAT, 22239.0, dummyPos), PtNumber(DataType.UWORD, 22239.0, dummyPos)) shouldBe false
|
||||
sameValueAndType(PtNumber(DataType.FLOAT, 9.99, dummyPos), PtNumber(DataType.FLOAT, 9.99, dummyPos)) shouldBe true
|
||||
|
||||
(PtNumber(DataType.UBYTE, 100.0, dummyPos) != PtNumber(DataType.UBYTE, 101.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.UBYTE, 100.0, dummyPos) != PtNumber(DataType.UWORD, 101.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.UBYTE, 100.0, dummyPos) != PtNumber(DataType.FLOAT, 101.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.UWORD, 245.0, dummyPos) != PtNumber(DataType.UBYTE, 246.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.UWORD, 12345.0, dummyPos) != PtNumber(DataType.UWORD, 12346.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.UWORD, 12345.0, dummyPos) != PtNumber(DataType.FLOAT, 12346.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.FLOAT, 9.99, dummyPos) != PtNumber(DataType.UBYTE, 9.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.FLOAT, 9.99, dummyPos) != PtNumber(DataType.UWORD, 9.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.FLOAT, 9.99, dummyPos) != PtNumber(DataType.FLOAT, 9.0, dummyPos)) shouldBe true
|
||||
|
||||
sameValueAndType(PtNumber(DataType.UBYTE, 100.0, dummyPos), PtNumber(DataType.UBYTE, 101.0, dummyPos)) shouldBe false
|
||||
sameValueAndType(PtNumber(DataType.UBYTE, 100.0, dummyPos), PtNumber(DataType.UWORD, 101.0, dummyPos)) shouldBe false
|
||||
sameValueAndType(PtNumber(DataType.UBYTE, 100.0, dummyPos), PtNumber(DataType.FLOAT, 101.0, dummyPos)) shouldBe false
|
||||
sameValueAndType(PtNumber(DataType.UWORD, 245.0, dummyPos), PtNumber(DataType.UBYTE, 246.0, dummyPos)) shouldBe false
|
||||
sameValueAndType(PtNumber(DataType.UWORD, 12345.0, dummyPos), PtNumber(DataType.UWORD, 12346.0, dummyPos)) shouldBe false
|
||||
sameValueAndType(PtNumber(DataType.UWORD, 12345.0, dummyPos), PtNumber(DataType.FLOAT, 12346.0, dummyPos)) shouldBe false
|
||||
sameValueAndType(PtNumber(DataType.FLOAT, 9.99, dummyPos), PtNumber(DataType.UBYTE, 9.0, dummyPos)) shouldBe false
|
||||
sameValueAndType(PtNumber(DataType.FLOAT, 9.99, dummyPos), PtNumber(DataType.UWORD, 9.0, dummyPos)) shouldBe false
|
||||
sameValueAndType(PtNumber(DataType.FLOAT, 9.99, dummyPos), PtNumber(DataType.FLOAT, 9.0, dummyPos)) shouldBe false
|
||||
|
||||
|
||||
}
|
||||
|
||||
test("testEqualsRef") {
|
||||
(PtString("hello", Encoding.PETSCII, dummyPos) == PtString("hello", Encoding.PETSCII, dummyPos)) shouldBe true
|
||||
(PtString("hello", Encoding.PETSCII, dummyPos) != PtString("bye", Encoding.PETSCII, dummyPos)) shouldBe true
|
||||
(PtString("hello", Encoding.SCREENCODES, dummyPos) == PtString("hello", Encoding.SCREENCODES, dummyPos)) shouldBe true
|
||||
(PtString("hello", Encoding.SCREENCODES, dummyPos) != PtString("bye", Encoding.SCREENCODES, dummyPos)) shouldBe true
|
||||
(PtString("hello", Encoding.SCREENCODES, dummyPos) != PtString("hello", Encoding.PETSCII, dummyPos)) shouldBe true
|
||||
|
||||
val lvOne = PtNumber(DataType.UBYTE, 1.0, dummyPos)
|
||||
val lvTwo = PtNumber(DataType.UBYTE, 2.0, dummyPos)
|
||||
val lvThree = PtNumber(DataType.UBYTE, 3.0, dummyPos)
|
||||
val lvOneR = PtNumber(DataType.UBYTE, 1.0, dummyPos)
|
||||
val lvTwoR = PtNumber(DataType.UBYTE, 2.0, dummyPos)
|
||||
val lvThreeR = PtNumber(DataType.UBYTE, 3.0, dummyPos)
|
||||
val lvFour= PtNumber(DataType.UBYTE, 4.0, dummyPos)
|
||||
val lv1 = PtArray(DataType.ARRAY_UB, dummyPos)
|
||||
arrayOf(lvOne, lvTwo, lvThree).forEach { lv1.add(it) }
|
||||
val lv2 = PtArray(DataType.ARRAY_UB, dummyPos)
|
||||
arrayOf(lvOneR, lvTwoR, lvThreeR).forEach { lv2.add(it) }
|
||||
val lv3 = PtArray(DataType.ARRAY_UB, dummyPos)
|
||||
arrayOf(lvOneR, lvTwoR, lvFour).forEach { lv3.add(it) }
|
||||
lv1 shouldBe lv2
|
||||
lv1 shouldNotBe lv3
|
||||
}
|
||||
|
||||
test("testGreaterThan") {
|
||||
(PtNumber(DataType.UBYTE, 100.0, dummyPos) > PtNumber(DataType.UBYTE, 99.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.UWORD, 254.0, dummyPos) > PtNumber(DataType.UWORD, 253.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.FLOAT, 100.0, dummyPos) > PtNumber(DataType.FLOAT, 99.9, dummyPos)) shouldBe true
|
||||
|
||||
(PtNumber(DataType.UBYTE, 100.0, dummyPos) >= PtNumber(DataType.UBYTE, 100.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.UWORD, 254.0, dummyPos) >= PtNumber(DataType.UWORD, 254.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.FLOAT, 100.0, dummyPos) >= PtNumber(DataType.FLOAT, 100.0, dummyPos)) shouldBe true
|
||||
|
||||
(PtNumber(DataType.UBYTE, 100.0, dummyPos) > PtNumber(DataType.UBYTE, 100.0, dummyPos)) shouldBe false
|
||||
(PtNumber(DataType.UWORD, 254.0, dummyPos) > PtNumber(DataType.UWORD, 254.0, dummyPos)) shouldBe false
|
||||
(PtNumber(DataType.FLOAT, 100.0, dummyPos) > PtNumber(DataType.FLOAT, 100.0, dummyPos)) shouldBe false
|
||||
|
||||
(PtNumber(DataType.UBYTE, 100.0, dummyPos) >= PtNumber(DataType.UBYTE, 101.0, dummyPos)) shouldBe false
|
||||
(PtNumber(DataType.UWORD, 254.0, dummyPos) >= PtNumber(DataType.UWORD, 255.0, dummyPos)) shouldBe false
|
||||
(PtNumber(DataType.FLOAT, 100.0, dummyPos) >= PtNumber(DataType.FLOAT, 100.1, dummyPos)) shouldBe false
|
||||
}
|
||||
|
||||
test("testLessThan") {
|
||||
(PtNumber(DataType.UBYTE, 100.0, dummyPos) < PtNumber(DataType.UBYTE, 101.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.UWORD, 254.0, dummyPos) < PtNumber(DataType.UWORD, 255.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.FLOAT, 100.0, dummyPos) < PtNumber(DataType.FLOAT, 100.1, dummyPos)) shouldBe true
|
||||
|
||||
(PtNumber(DataType.UBYTE, 100.0, dummyPos) <= PtNumber(DataType.UBYTE, 100.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.UWORD, 254.0, dummyPos) <= PtNumber(DataType.UWORD, 254.0, dummyPos)) shouldBe true
|
||||
(PtNumber(DataType.FLOAT, 100.0, dummyPos) <= PtNumber(DataType.FLOAT, 100.0, dummyPos)) shouldBe true
|
||||
|
||||
(PtNumber(DataType.UBYTE, 100.0, dummyPos) < PtNumber(DataType.UBYTE, 100.0, dummyPos)) shouldBe false
|
||||
(PtNumber(DataType.UWORD, 254.0, dummyPos) < PtNumber(DataType.UWORD, 254.0, dummyPos)) shouldBe false
|
||||
(PtNumber(DataType.FLOAT, 100.0, dummyPos) < PtNumber(DataType.FLOAT, 100.0, dummyPos)) shouldBe false
|
||||
|
||||
(PtNumber(DataType.UBYTE, 100.0, dummyPos) <= PtNumber(DataType.UBYTE, 99.0, dummyPos)) shouldBe false
|
||||
(PtNumber(DataType.UWORD, 254.0, dummyPos) <= PtNumber(DataType.UWORD, 253.0, dummyPos)) shouldBe false
|
||||
(PtNumber(DataType.FLOAT, 100.0, dummyPos) <= PtNumber(DataType.FLOAT, 99.9, dummyPos)) shouldBe false
|
||||
}
|
||||
|
||||
})
|
Loading…
Reference in New Issue
Block a user