2018-08-16 21:10:28 +00:00
|
|
|
package il65tests
|
2018-08-10 00:58:41 +00:00
|
|
|
|
2018-08-16 21:10:28 +00:00
|
|
|
import il65.ast.DataType
|
|
|
|
import il65.ast.VarDecl
|
|
|
|
import il65.ast.VarDeclType
|
|
|
|
import il65.compiler.*
|
2018-08-16 23:47:07 +00:00
|
|
|
import org.hamcrest.MatcherAssert.assertThat
|
|
|
|
import org.hamcrest.Matchers.equalTo
|
2018-08-10 00:58:41 +00:00
|
|
|
import org.junit.jupiter.api.Test
|
|
|
|
import org.junit.jupiter.api.TestInstance
|
2018-08-16 23:47:07 +00:00
|
|
|
import kotlin.test.assertEquals
|
2018-08-16 21:10:28 +00:00
|
|
|
import kotlin.test.assertFailsWith
|
2018-08-10 00:58:41 +00:00
|
|
|
|
2018-08-16 23:47:07 +00:00
|
|
|
|
|
|
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
|
|
|
class TestCompiler {
|
|
|
|
@Test
|
|
|
|
fun testToHex() {
|
|
|
|
assertEquals("0", 0.toHex())
|
|
|
|
assertEquals("1", 1.toHex())
|
|
|
|
assertEquals("1", 1.234.toHex())
|
|
|
|
assertEquals("10", 10.toHex())
|
|
|
|
assertEquals("10", 10.99.toHex())
|
|
|
|
assertEquals("15", 15.toHex())
|
|
|
|
assertEquals("$10", 16.toHex())
|
|
|
|
assertEquals("\$ff", 255.toHex())
|
|
|
|
assertEquals("$0100", 256.toHex())
|
|
|
|
assertEquals("$4e5c", 20060.toHex())
|
|
|
|
assertEquals("\$ffff", 65535.toHex())
|
|
|
|
assertEquals("\$ffff", 65535L.toHex())
|
|
|
|
assertFailsWith<CompilerException> { 65536.toHex() }
|
|
|
|
assertFailsWith<CompilerException> { (-1).toHex() }
|
|
|
|
assertFailsWith<CompilerException> { (-1.99).toHex() }
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testFloatToMflpt5() {
|
|
|
|
assertThat((0).toMflpt5(), equalTo(shortArrayOf(0x00, 0x00, 0x00, 0x00, 0x00)))
|
|
|
|
assertThat((3.141592653).toMflpt5(), equalTo(shortArrayOf(0x82, 0x49, 0x0F, 0xDA, 0xA1)))
|
|
|
|
assertThat((3.141592653589793).toMflpt5(), equalTo(shortArrayOf(0x82, 0x49, 0x0F, 0xDA, 0xA2)))
|
|
|
|
assertThat((-32768).toMflpt5(), equalTo(shortArrayOf(0x90, 0x80, 0x00, 0x00, 0x00)))
|
|
|
|
assertThat((1).toMflpt5(), equalTo(shortArrayOf(0x81, 0x00, 0x00, 0x00, 0x00)))
|
|
|
|
assertThat((0.7071067812).toMflpt5(), equalTo(shortArrayOf(0x80, 0x35, 0x04, 0xF3, 0x34)))
|
|
|
|
assertThat((0.7071067811865476).toMflpt5(), equalTo(shortArrayOf(0x80, 0x35, 0x04, 0xF3, 0x33)))
|
|
|
|
assertThat((1.4142135624).toMflpt5(), equalTo(shortArrayOf(0x81, 0x35, 0x04, 0xF3, 0x34)))
|
|
|
|
assertThat((1.4142135623730951).toMflpt5(), equalTo(shortArrayOf(0x81, 0x35, 0x04, 0xF3, 0x33)))
|
|
|
|
assertThat((-.5).toMflpt5(), equalTo(shortArrayOf(0x80, 0x80, 0x00, 0x00, 0x00)))
|
|
|
|
assertThat((0.69314718061).toMflpt5(), equalTo(shortArrayOf(0x80, 0x31, 0x72, 0x17, 0xF8)))
|
|
|
|
assertThat((0.6931471805599453).toMflpt5(), equalTo(shortArrayOf(0x80, 0x31, 0x72, 0x17, 0xF7)))
|
|
|
|
assertThat((10).toMflpt5(), equalTo(shortArrayOf(0x84, 0x20, 0x00, 0x00, 0x00)))
|
|
|
|
assertThat((1000000000).toMflpt5(), equalTo(shortArrayOf(0x9E, 0x6E, 0x6B, 0x28, 0x00)))
|
|
|
|
assertThat((.5).toMflpt5(), equalTo(shortArrayOf(0x80, 0x00, 0x00, 0x00, 0x00)))
|
|
|
|
assertThat((1.4426950408889634).toMflpt5(), equalTo(shortArrayOf(0x81, 0x38, 0xAA, 0x3B, 0x29)))
|
|
|
|
assertThat((1.5707963267948966).toMflpt5(), equalTo(shortArrayOf(0x81, 0x49, 0x0F, 0xDA, 0xA2)))
|
|
|
|
assertThat((6.283185307179586).toMflpt5(), equalTo(shortArrayOf(0x83, 0x49, 0x0F, 0xDA, 0xA2)))
|
|
|
|
assertThat((.25).toMflpt5(), equalTo(shortArrayOf(0x7F, 0x00, 0x00, 0x00, 0x00)))
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testFloatRange() {
|
|
|
|
assertThat(FLOAT_MAX_POSITIVE.toMflpt5(), equalTo(shortArrayOf(0xff, 0x7f, 0xff, 0xff, 0xff)))
|
|
|
|
assertThat(FLOAT_MAX_NEGATIVE.toMflpt5(), equalTo(shortArrayOf(0xff, 0xff, 0xff, 0xff, 0xff)))
|
|
|
|
assertThat((1.7e-38).toMflpt5(), equalTo(shortArrayOf(0x03, 0x39, 0x1d, 0x15, 0x63)))
|
|
|
|
assertThat((1.7e-39).toMflpt5(), equalTo(shortArrayOf(0x00, 0x00, 0x00, 0x00, 0x00)))
|
|
|
|
assertThat((-1.7e-38).toMflpt5(), equalTo(shortArrayOf(0x03, 0xb9, 0x1d, 0x15, 0x63)))
|
|
|
|
assertThat((-1.7e-39).toMflpt5(), equalTo(shortArrayOf(0x00, 0x00, 0x00, 0x00, 0x00)))
|
|
|
|
assertFailsWith<CompilerException> { 1.7014118346e+38.toMflpt5() }
|
|
|
|
assertFailsWith<CompilerException> { (-1.7014118346e+38).toMflpt5() }
|
|
|
|
assertFailsWith<CompilerException> { 1.7014118347e+38.toMflpt5() }
|
|
|
|
assertFailsWith<CompilerException> { (-1.7014118347e+38).toMflpt5() }
|
|
|
|
}
|
|
|
|
|
|
|
|
// @todo test the other way round, mflpt-bytes -> float.
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-08-10 00:58:41 +00:00
|
|
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
2018-08-16 21:10:28 +00:00
|
|
|
class TestZeropage {
|
|
|
|
@Test
|
|
|
|
fun testNames() {
|
|
|
|
val zp = Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.COMPATIBLE, false))
|
|
|
|
|
|
|
|
assertFailsWith<AssertionError> {
|
|
|
|
zp.allocate(VarDecl(VarDeclType.MEMORY, DataType.BYTE, null, "", null))
|
|
|
|
}
|
|
|
|
|
|
|
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null))
|
|
|
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null))
|
|
|
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "varname", null))
|
|
|
|
assertFailsWith<AssertionError> {
|
|
|
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "varname", null))
|
|
|
|
}
|
|
|
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "varname2", null))
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testZpFloatEnable() {
|
|
|
|
val zp = Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, false))
|
2018-08-16 23:47:07 +00:00
|
|
|
assertFailsWith<CompilerException> {
|
2018-08-16 21:10:28 +00:00
|
|
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, null, "", null))
|
|
|
|
}
|
|
|
|
val zp2 = Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, true))
|
|
|
|
zp2.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, null, "", null))
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testCompatibleAllocation() {
|
|
|
|
val zp = Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.COMPATIBLE, true))
|
|
|
|
assert(zp.available() == 9)
|
2018-08-16 23:47:07 +00:00
|
|
|
assertFailsWith<CompilerException> {
|
2018-08-16 21:10:28 +00:00
|
|
|
// in regular zp there aren't 5 sequential bytes free
|
|
|
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, null, "", null))
|
|
|
|
}
|
|
|
|
for (i in 0 until zp.available()) {
|
|
|
|
val loc = zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null))
|
|
|
|
assert(loc > 0)
|
|
|
|
}
|
|
|
|
assert(zp.available() == 0)
|
2018-08-16 23:47:07 +00:00
|
|
|
assertFailsWith<CompilerException> {
|
2018-08-16 21:10:28 +00:00
|
|
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null))
|
|
|
|
}
|
2018-08-16 23:47:07 +00:00
|
|
|
assertFailsWith<CompilerException> {
|
2018-08-16 21:10:28 +00:00
|
|
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.WORD, null, "", null))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-10 00:58:41 +00:00
|
|
|
@Test
|
2018-08-16 21:10:28 +00:00
|
|
|
fun testFullAllocation() {
|
|
|
|
val zp = Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, true))
|
|
|
|
assert(zp.available() == 239)
|
|
|
|
val loc = zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, null, "", null))
|
|
|
|
assert(loc > 3)
|
|
|
|
assert(!zp.free.contains(loc))
|
|
|
|
val num = zp.available() / 5
|
|
|
|
val rest = zp.available() % 5
|
|
|
|
|
|
|
|
for(i in 0..num-4) {
|
|
|
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, null, "", null))
|
|
|
|
}
|
|
|
|
assert(zp.available() == 19)
|
|
|
|
|
2018-08-16 23:47:07 +00:00
|
|
|
assertFailsWith<CompilerException> {
|
2018-08-16 21:10:28 +00:00
|
|
|
// can't allocate because no more sequential bytes, only fragmented
|
|
|
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.FLOAT, null, "", null))
|
|
|
|
}
|
|
|
|
|
|
|
|
for(i in 0..13) {
|
|
|
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null))
|
|
|
|
}
|
|
|
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.WORD, null, "", null))
|
|
|
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.WORD, null, "", null))
|
|
|
|
|
|
|
|
assert(zp.available() == 1)
|
|
|
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null))
|
2018-08-16 23:47:07 +00:00
|
|
|
assertFailsWith<CompilerException> {
|
2018-08-16 21:10:28 +00:00
|
|
|
// no more space
|
|
|
|
zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null))
|
|
|
|
}
|
2018-08-10 00:58:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
2018-08-16 21:10:28 +00:00
|
|
|
fun testEfficientAllocation() {
|
|
|
|
// free = [0x04, 0x05, 0x06, 0x2a, 0x52, 0xf7, 0xf8, 0xf9, 0xfa]
|
|
|
|
val zp = Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.COMPATIBLE, true))
|
|
|
|
assert(zp.available()==9)
|
|
|
|
assert(0x2a == zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null)))
|
|
|
|
assert(0x52 == zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null)))
|
|
|
|
assert(0x04 == zp.allocate(VarDecl(VarDeclType.VAR, DataType.WORD, null, "", null)))
|
|
|
|
assert(0xf7 == zp.allocate(VarDecl(VarDeclType.VAR, DataType.WORD, null, "", null)))
|
|
|
|
assert(0x06 == zp.allocate(VarDecl(VarDeclType.VAR, DataType.BYTE, null, "", null)))
|
|
|
|
assert(0xf9 == zp.allocate(VarDecl(VarDeclType.VAR, DataType.WORD, null, "", null)))
|
|
|
|
assert(zp.available()==0)
|
2018-08-10 00:58:41 +00:00
|
|
|
}
|
|
|
|
}
|