mirror of
https://github.com/irmen/prog8.git
synced 2024-11-29 01:49:22 +00:00
char encodings now use UByte type instead of short
This commit is contained in:
parent
2491509c6a
commit
c0035ba1a2
@ -13,14 +13,14 @@ import prog8.compilerinterface.ICompilationTarget
|
|||||||
object C64Target: ICompilationTarget {
|
object C64Target: ICompilationTarget {
|
||||||
override val name = "c64"
|
override val name = "c64"
|
||||||
override val machine = C64MachineDefinition
|
override val machine = C64MachineDefinition
|
||||||
override fun encodeString(str: String, altEncoding: Boolean): List<Short> {
|
override fun encodeString(str: String, altEncoding: Boolean): List<UByte> {
|
||||||
val coded = if (altEncoding) Petscii.encodeScreencode(str, true) else Petscii.encodePetscii(str, true)
|
val coded = if (altEncoding) Petscii.encodeScreencode(str, true) else Petscii.encodePetscii(str, true)
|
||||||
return coded.fold(
|
return coded.fold(
|
||||||
failure = { throw it },
|
failure = { throw it },
|
||||||
success = { it }
|
success = { it }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
override fun decodeString(bytes: List<Short>, altEncoding: Boolean) =
|
override fun decodeString(bytes: List<UByte>, altEncoding: Boolean) =
|
||||||
if (altEncoding) Petscii.decodeScreencode(bytes, true) else Petscii.decodePetscii(bytes, true)
|
if (altEncoding) Petscii.decodeScreencode(bytes, true) else Petscii.decodePetscii(bytes, true)
|
||||||
|
|
||||||
override fun memorySize(dt: DataType): Int {
|
override fun memorySize(dt: DataType): Int {
|
||||||
|
@ -13,14 +13,14 @@ import prog8.compilerinterface.ICompilationTarget
|
|||||||
object Cx16Target: ICompilationTarget {
|
object Cx16Target: ICompilationTarget {
|
||||||
override val name = "cx16"
|
override val name = "cx16"
|
||||||
override val machine = CX16MachineDefinition
|
override val machine = CX16MachineDefinition
|
||||||
override fun encodeString(str: String, altEncoding: Boolean): List<Short> {
|
override fun encodeString(str: String, altEncoding: Boolean): List<UByte> {
|
||||||
val coded= if (altEncoding) Petscii.encodeScreencode(str, true) else Petscii.encodePetscii(str, true)
|
val coded= if (altEncoding) Petscii.encodeScreencode(str, true) else Petscii.encodePetscii(str, true)
|
||||||
return coded.fold(
|
return coded.fold(
|
||||||
failure = { throw it },
|
failure = { throw it },
|
||||||
success = { it }
|
success = { it }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
override fun decodeString(bytes: List<Short>, altEncoding: Boolean) =
|
override fun decodeString(bytes: List<UByte>, altEncoding: Boolean) =
|
||||||
if (altEncoding) Petscii.decodeScreencode(bytes, true) else Petscii.decodePetscii(bytes, true)
|
if (altEncoding) Petscii.decodeScreencode(bytes, true) else Petscii.decodePetscii(bytes, true)
|
||||||
|
|
||||||
override fun memorySize(dt: DataType): Int {
|
override fun memorySize(dt: DataType): Int {
|
||||||
|
@ -1065,15 +1065,15 @@ object Petscii {
|
|||||||
else -> chr
|
else -> chr
|
||||||
}
|
}
|
||||||
|
|
||||||
fun encodePetscii(text: String, lowercase: Boolean = false): Result<List<Short>, CharConversionException> {
|
fun encodePetscii(text: String, lowercase: Boolean = false): Result<List<UByte>, CharConversionException> {
|
||||||
fun encodeChar(chr3: Char, lowercase: Boolean): Short {
|
fun encodeChar(chr3: Char, lowercase: Boolean): UByte {
|
||||||
val chr = replaceSpecial(chr3)
|
val chr = replaceSpecial(chr3)
|
||||||
val screencode = if(lowercase) encodingPetsciiLowercase[chr] else encodingPetsciiUppercase[chr]
|
val screencode = if(lowercase) encodingPetsciiLowercase[chr] else encodingPetsciiUppercase[chr]
|
||||||
return screencode?.toShort() ?: when (chr) {
|
return screencode?.toUByte() ?: when (chr) {
|
||||||
'\u0000' -> 0.toShort()
|
'\u0000' -> 0u
|
||||||
in '\u8000'..'\u80ff' -> {
|
in '\u8000'..'\u80ff' -> {
|
||||||
// special case: take the lower 8 bit hex value directly
|
// special case: take the lower 8 bit hex value directly
|
||||||
(chr.code - 0x8000).toShort()
|
(chr.code - 0x8000).toUByte()
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val case = if (lowercase) "lower" else "upper"
|
val case = if (lowercase) "lower" else "upper"
|
||||||
@ -1095,7 +1095,7 @@ object Petscii {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun decodePetscii(petscii: Iterable<Short>, lowercase: Boolean = false): String {
|
fun decodePetscii(petscii: Iterable<UByte>, lowercase: Boolean = false): String {
|
||||||
return petscii.map {
|
return petscii.map {
|
||||||
val code = it.toInt()
|
val code = it.toInt()
|
||||||
if(code<0 || code>= decodingPetsciiLowercase.size)
|
if(code<0 || code>= decodingPetsciiLowercase.size)
|
||||||
@ -1104,15 +1104,15 @@ object Petscii {
|
|||||||
}.joinToString("")
|
}.joinToString("")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun encodeScreencode(text: String, lowercase: Boolean = false): Result<List<Short>, CharConversionException> {
|
fun encodeScreencode(text: String, lowercase: Boolean = false): Result<List<UByte>, CharConversionException> {
|
||||||
fun encodeChar(chr3: Char, lowercase: Boolean): Short {
|
fun encodeChar(chr3: Char, lowercase: Boolean): UByte {
|
||||||
val chr = replaceSpecial(chr3)
|
val chr = replaceSpecial(chr3)
|
||||||
val screencode = if(lowercase) encodingScreencodeLowercase[chr] else encodingScreencodeUppercase[chr]
|
val screencode = if(lowercase) encodingScreencodeLowercase[chr] else encodingScreencodeUppercase[chr]
|
||||||
return screencode?.toShort() ?: when (chr) {
|
return screencode?.toUByte() ?: when (chr) {
|
||||||
'\u0000' -> 0.toShort()
|
'\u0000' -> 0u
|
||||||
in '\u8000'..'\u80ff' -> {
|
in '\u8000'..'\u80ff' -> {
|
||||||
// special case: take the lower 8 bit hex value directly
|
// special case: take the lower 8 bit hex value directly
|
||||||
(chr.code - 0x8000).toShort()
|
(chr.code - 0x8000).toUByte()
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val case = if (lowercase) "lower" else "upper"
|
val case = if (lowercase) "lower" else "upper"
|
||||||
@ -1134,7 +1134,7 @@ object Petscii {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun decodeScreencode(screencode: Iterable<Short>, lowercase: Boolean = false): String {
|
fun decodeScreencode(screencode: Iterable<UByte>, lowercase: Boolean = false): String {
|
||||||
return screencode.map {
|
return screencode.map {
|
||||||
val code = it.toInt()
|
val code = it.toInt()
|
||||||
if(code<0 || code>= decodingScreencodeLowercase.size)
|
if(code<0 || code>= decodingScreencodeLowercase.size)
|
||||||
@ -1143,38 +1143,37 @@ object Petscii {
|
|||||||
}.joinToString("")
|
}.joinToString("")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun petscii2scr(petscii_code: Short, inverseVideo: Boolean): Result<Short, CharConversionException> {
|
fun petscii2scr(petscii_code: UByte, inverseVideo: Boolean): Result<UByte, CharConversionException> {
|
||||||
val code = when {
|
val code: UInt = when {
|
||||||
petscii_code < 0 -> return Err(CharConversionException("petscii code out of range"))
|
petscii_code <= 0x1fu -> petscii_code + 128u
|
||||||
petscii_code <= 0x1f -> petscii_code + 128
|
petscii_code <= 0x3fu -> petscii_code.toUInt()
|
||||||
petscii_code <= 0x3f -> petscii_code.toInt()
|
petscii_code <= 0x5fu -> petscii_code - 64u
|
||||||
petscii_code <= 0x5f -> petscii_code - 64
|
petscii_code <= 0x7fu -> petscii_code - 32u
|
||||||
petscii_code <= 0x7f -> petscii_code - 32
|
petscii_code <= 0x9fu -> petscii_code + 64u
|
||||||
petscii_code <= 0x9f -> petscii_code + 64
|
petscii_code <= 0xbfu -> petscii_code - 64u
|
||||||
petscii_code <= 0xbf -> petscii_code - 64
|
petscii_code <= 0xfeu -> petscii_code - 128u
|
||||||
petscii_code <= 0xfe -> petscii_code - 128
|
petscii_code == 255.toUByte() -> 95u
|
||||||
petscii_code == 255.toShort() -> 95
|
|
||||||
else -> return Err(CharConversionException("petscii code out of range"))
|
else -> return Err(CharConversionException("petscii code out of range"))
|
||||||
}
|
}
|
||||||
if(inverseVideo)
|
if(inverseVideo) {
|
||||||
return Ok((code or 0x80).toShort())
|
return Ok((code or 0x80u).toUByte())
|
||||||
return Ok(code.toShort())
|
}
|
||||||
|
return Ok(code.toUByte())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun scr2petscii(screencode: Short): Result<Short, CharConversionException> {
|
fun scr2petscii(screencode: UByte): Result<UByte, CharConversionException> {
|
||||||
val petscii = when {
|
val petscii: UInt = when {
|
||||||
screencode < 0 -> return Err(CharConversionException("screencode out of range"))
|
screencode <= 0x1fu -> screencode + 64u
|
||||||
screencode <= 0x1f -> screencode + 64
|
screencode <= 0x3fu -> screencode.toUInt()
|
||||||
screencode <= 0x3f -> screencode.toInt()
|
screencode <= 0x5du -> screencode +123u
|
||||||
screencode <= 0x5d -> screencode +123
|
screencode == 0x5e.toUByte() -> 255u
|
||||||
screencode == 0x5e.toShort() -> 255
|
screencode == 0x5f.toUByte() -> 223u
|
||||||
screencode == 0x5f.toShort() -> 223
|
screencode <= 0x7fu -> screencode + 64u
|
||||||
screencode <= 0x7f -> screencode + 64
|
screencode <= 0xbfu -> screencode - 128u
|
||||||
screencode <= 0xbf -> screencode - 128
|
screencode <= 0xfeu -> screencode - 64u
|
||||||
screencode <= 0xfe -> screencode - 64
|
screencode == 255.toUByte() -> 191u
|
||||||
screencode == 255.toShort() -> 191
|
|
||||||
else -> return Err(CharConversionException("screencode out of range"))
|
else -> return Err(CharConversionException("screencode out of range"))
|
||||||
}
|
}
|
||||||
return Ok(petscii.toShort())
|
return Ok(petscii.toUByte())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -297,7 +297,7 @@ class AsmGen(private val program: Program,
|
|||||||
DataType.FLOAT -> out("$name\t.byte 0,0,0,0,0 ; float")
|
DataType.FLOAT -> out("$name\t.byte 0,0,0,0,0 ; float")
|
||||||
DataType.STR -> {
|
DataType.STR -> {
|
||||||
val str = decl.value as StringLiteralValue
|
val str = decl.value as StringLiteralValue
|
||||||
outputStringvar(decl, compTarget.encodeString(str.value, str.altEncoding).plus(0))
|
outputStringvar(decl, compTarget.encodeString(str.value, str.altEncoding).plus(0.toUByte()))
|
||||||
}
|
}
|
||||||
DataType.ARRAY_UB -> {
|
DataType.ARRAY_UB -> {
|
||||||
val data = makeArrayFillDataUnsigned(decl)
|
val data = makeArrayFillDataUnsigned(decl)
|
||||||
@ -393,7 +393,7 @@ class AsmGen(private val program: Program,
|
|||||||
.filter {it.datatype == DataType.STR }
|
.filter {it.datatype == DataType.STR }
|
||||||
.map {
|
.map {
|
||||||
val str = it.value as StringLiteralValue
|
val str = it.value as StringLiteralValue
|
||||||
it to compTarget.encodeString(str.value, str.altEncoding).plus(0)
|
it to compTarget.encodeString(str.value, str.altEncoding).plus(0.toUByte())
|
||||||
}
|
}
|
||||||
for((decl, variables) in encodedstringVars) {
|
for((decl, variables) in encodedstringVars) {
|
||||||
outputStringvar(decl, variables)
|
outputStringvar(decl, variables)
|
||||||
@ -410,7 +410,7 @@ class AsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun outputStringvar(strdecl: VarDecl, bytes: List<Short>) {
|
private fun outputStringvar(strdecl: VarDecl, bytes: List<UByte>) {
|
||||||
val sv = strdecl.value as StringLiteralValue
|
val sv = strdecl.value as StringLiteralValue
|
||||||
val altEncoding = if(sv.altEncoding) "@" else ""
|
val altEncoding = if(sv.altEncoding) "@" else ""
|
||||||
out("${strdecl.name}\t; ${strdecl.datatype} $altEncoding\"${escape(sv.value).replace("\u0000", "<NULL>")}\"")
|
out("${strdecl.name}\t; ${strdecl.datatype} $altEncoding\"${escape(sv.value).replace("\u0000", "<NULL>")}\"")
|
||||||
|
@ -27,11 +27,11 @@ internal val DummyMemsizer = object : IMemSizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal val DummyStringEncoder = object : IStringEncoding {
|
internal val DummyStringEncoder = object : IStringEncoding {
|
||||||
override fun encodeString(str: String, altEncoding: Boolean): List<Short> {
|
override fun encodeString(str: String, altEncoding: Boolean): List<UByte> {
|
||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun decodeString(bytes: List<Short>, altEncoding: Boolean): String {
|
override fun decodeString(bytes: List<UByte>, altEncoding: Boolean): String {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ class TestCompilerOnCharLit: FunSpec({
|
|||||||
}
|
}
|
||||||
val arg = funCall.args[0] as NumericLiteralValue
|
val arg = funCall.args[0] as NumericLiteralValue
|
||||||
arg.type shouldBe DataType.UBYTE
|
arg.type shouldBe DataType.UBYTE
|
||||||
arg.number shouldBe platform.encodeString("\n", false)[0]
|
arg.number shouldBe platform.encodeString("\n", false)[0].toDouble()
|
||||||
}
|
}
|
||||||
|
|
||||||
test("testCharVarAsRomsubArg") {
|
test("testCharVarAsRomsubArg") {
|
||||||
@ -83,7 +83,7 @@ class TestCompilerOnCharLit: FunSpec({
|
|||||||
}
|
}
|
||||||
val initializerValue = assignInitialValue.value as NumericLiteralValue
|
val initializerValue = assignInitialValue.value as NumericLiteralValue
|
||||||
initializerValue.type shouldBe DataType.UBYTE
|
initializerValue.type shouldBe DataType.UBYTE
|
||||||
initializerValue.number shouldBe platform.encodeString("\n", false)[0]
|
initializerValue.number shouldBe platform.encodeString("\n", false)[0].toDouble()
|
||||||
}
|
}
|
||||||
|
|
||||||
test("testCharConstAsRomsubArg") {
|
test("testCharConstAsRomsubArg") {
|
||||||
@ -111,7 +111,7 @@ class TestCompilerOnCharLit: FunSpec({
|
|||||||
(decl.value as NumericLiteralValue).number shouldBe platform.encodeString("\n", false)[0]
|
(decl.value as NumericLiteralValue).number shouldBe platform.encodeString("\n", false)[0]
|
||||||
}
|
}
|
||||||
is NumericLiteralValue -> {
|
is NumericLiteralValue -> {
|
||||||
arg.number shouldBe platform.encodeString("\n", false)[0]
|
arg.number shouldBe platform.encodeString("\n", false)[0].toDouble()
|
||||||
}
|
}
|
||||||
else -> fail("invalid arg type") // funCall.args[0] shouldBe instanceOf<IdentifierReference>() // make test fail
|
else -> fail("invalid arg type") // funCall.args[0] shouldBe instanceOf<IdentifierReference>() // make test fail
|
||||||
}
|
}
|
||||||
|
@ -3,73 +3,71 @@ package prog8tests
|
|||||||
import com.github.michaelbull.result.Ok
|
import com.github.michaelbull.result.Ok
|
||||||
import com.github.michaelbull.result.expectError
|
import com.github.michaelbull.result.expectError
|
||||||
import com.github.michaelbull.result.getOrElse
|
import com.github.michaelbull.result.getOrElse
|
||||||
import io.kotest.assertions.throwables.shouldThrow
|
|
||||||
import io.kotest.assertions.withClue
|
import io.kotest.assertions.withClue
|
||||||
import io.kotest.core.spec.style.FunSpec
|
import io.kotest.core.spec.style.FunSpec
|
||||||
import io.kotest.matchers.shouldBe
|
import io.kotest.matchers.shouldBe
|
||||||
import prog8.compiler.target.cbm.Petscii
|
import prog8.compiler.target.cbm.Petscii
|
||||||
import java.io.CharConversionException
|
|
||||||
|
|
||||||
|
|
||||||
class TestPetscii: FunSpec({
|
class TestPetscii: FunSpec({
|
||||||
|
|
||||||
test("testZero") {
|
test("testZero") {
|
||||||
Petscii.encodePetscii("\u0000", true) shouldBe Ok(listOf<Short>(0))
|
Petscii.encodePetscii("\u0000", true) shouldBe Ok(listOf<UByte>(0u))
|
||||||
Petscii.encodePetscii("\u0000", false) shouldBe Ok(listOf<Short>(0))
|
Petscii.encodePetscii("\u0000", false) shouldBe Ok(listOf<UByte>(0u))
|
||||||
Petscii.decodePetscii(listOf(0), true) shouldBe "\u0000"
|
Petscii.decodePetscii(listOf(0u), true) shouldBe "\u0000"
|
||||||
Petscii.decodePetscii(listOf(0), false) shouldBe "\u0000"
|
Petscii.decodePetscii(listOf(0u), false) shouldBe "\u0000"
|
||||||
}
|
}
|
||||||
|
|
||||||
test("testLowercase") {
|
test("testLowercase") {
|
||||||
Petscii.encodePetscii("hello WORLD 123 @!£", true) shouldBe
|
Petscii.encodePetscii("hello WORLD 123 @!£", true) shouldBe
|
||||||
Ok(listOf<Short>(72, 69, 76, 76, 79, 32, 0xd7, 0xcf, 0xd2, 0xcc, 0xc4, 32, 49, 50, 51, 32, 64, 33, 0x5c))
|
Ok(listOf<UByte>(72u, 69u, 76u, 76u, 79u, 32u, 0xd7u, 0xcfu, 0xd2u, 0xccu, 0xc4u, 32u, 49u, 50u, 51u, 32u, 64u, 33u, 0x5cu))
|
||||||
Petscii.encodePetscii("\uf11a", true) shouldBe Ok(listOf<Short>(0x12)) // reverse vid
|
Petscii.encodePetscii("\uf11a", true) shouldBe Ok(listOf<UByte>(0x12u)) // reverse vid
|
||||||
Petscii.encodePetscii("✓", true) shouldBe Ok(listOf<Short>(0xfa))
|
Petscii.encodePetscii("✓", true) shouldBe Ok(listOf<UByte>(0xfau))
|
||||||
withClue("expect lowercase error fallback") {
|
withClue("expect lowercase error fallback") {
|
||||||
Petscii.encodePetscii("π", true) shouldBe Ok(listOf<Short>(255))
|
Petscii.encodePetscii("π", true) shouldBe Ok(listOf<UByte>(255u))
|
||||||
Petscii.encodePetscii("♥", true) shouldBe Ok(listOf<Short>(0xd3))
|
Petscii.encodePetscii("♥", true) shouldBe Ok(listOf<UByte>(0xd3u))
|
||||||
}
|
}
|
||||||
|
|
||||||
Petscii.decodePetscii(listOf(72, 0xd7, 0x5c, 0xfa, 0x12), true) shouldBe "hW£✓\uF11A"
|
Petscii.decodePetscii(listOf(72u, 0xd7u, 0x5cu, 0xfau, 0x12u), true) shouldBe "hW£✓\uF11A"
|
||||||
}
|
}
|
||||||
|
|
||||||
test("testUppercase") {
|
test("testUppercase") {
|
||||||
Petscii.encodePetscii("HELLO 123 @!£") shouldBe
|
Petscii.encodePetscii("HELLO 123 @!£") shouldBe
|
||||||
Ok(listOf<Short>(72, 69, 76, 76, 79, 32, 49, 50, 51, 32, 64, 33, 0x5c))
|
Ok(listOf<UByte>(72u, 69u, 76u, 76u, 79u, 32u, 49u, 50u, 51u, 32u, 64u, 33u, 0x5cu))
|
||||||
Petscii.encodePetscii("\uf11a") shouldBe Ok(listOf<Short>(0x12)) // reverse vid
|
Petscii.encodePetscii("\uf11a") shouldBe Ok(listOf<UByte>(0x12u)) // reverse vid
|
||||||
Petscii.encodePetscii("♥") shouldBe Ok(listOf<Short>(0xd3))
|
Petscii.encodePetscii("♥") shouldBe Ok(listOf<UByte>(0xd3u))
|
||||||
Petscii.encodePetscii("π") shouldBe Ok(listOf<Short>(0xff))
|
Petscii.encodePetscii("π") shouldBe Ok(listOf<UByte>(0xffu))
|
||||||
withClue("expecting fallback") {
|
withClue("expecting fallback") {
|
||||||
Petscii.encodePetscii("✓") shouldBe Ok(listOf<Short>(250))
|
Petscii.encodePetscii("✓") shouldBe Ok(listOf<UByte>(250u))
|
||||||
}
|
}
|
||||||
|
|
||||||
Petscii.decodePetscii(listOf(72, 0x5c, 0xd3, 0xff)) shouldBe "H£♥π"
|
Petscii.decodePetscii(listOf(72u, 0x5cu, 0xd3u, 0xffu)) shouldBe "H£♥π"
|
||||||
}
|
}
|
||||||
|
|
||||||
test("testScreencodeLowercase") {
|
test("testScreencodeLowercase") {
|
||||||
Petscii.encodeScreencode("hello WORLD 123 @!£", true) shouldBe
|
Petscii.encodeScreencode("hello WORLD 123 @!£", true) shouldBe
|
||||||
Ok(listOf<Short>(0x08, 0x05, 0x0c, 0x0c, 0x0f, 0x20, 0x57, 0x4f, 0x52, 0x4c, 0x44, 0x20, 0x31, 0x32, 0x33, 0x20, 0x00, 0x21, 0x1c))
|
Ok(listOf<UByte>(0x08u, 0x05u, 0x0cu, 0x0cu, 0x0fu, 0x20u, 0x57u, 0x4fu, 0x52u, 0x4cu, 0x44u, 0x20u, 0x31u, 0x32u, 0x33u, 0x20u, 0x00u, 0x21u, 0x1cu))
|
||||||
Petscii.encodeScreencode("✓", true) shouldBe Ok(listOf<Short>(0x7a))
|
Petscii.encodeScreencode("✓", true) shouldBe Ok(listOf<UByte>(0x7au))
|
||||||
withClue("expect fallback") {
|
withClue("expect fallback") {
|
||||||
Petscii.encodeScreencode("♥", true) shouldBe Ok(listOf<Short>(83))
|
Petscii.encodeScreencode("♥", true) shouldBe Ok(listOf<UByte>(83u))
|
||||||
Petscii.encodeScreencode("π", true) shouldBe Ok(listOf<Short>(94))
|
Petscii.encodeScreencode("π", true) shouldBe Ok(listOf<UByte>(94u))
|
||||||
}
|
}
|
||||||
|
|
||||||
Petscii.decodeScreencode(listOf(0x08, 0x57, 0x1c, 0x7a), true) shouldBe "hW£✓"
|
Petscii.decodeScreencode(listOf(0x08u, 0x57u, 0x1cu, 0x7au), true) shouldBe "hW£✓"
|
||||||
}
|
}
|
||||||
|
|
||||||
test("testScreencodeUppercase") {
|
test("testScreencodeUppercase") {
|
||||||
Petscii.encodeScreencode("WORLD 123 @!£") shouldBe
|
Petscii.encodeScreencode("WORLD 123 @!£") shouldBe
|
||||||
Ok(listOf<Short>(0x17, 0x0f, 0x12, 0x0c, 0x04, 0x20, 0x31, 0x32, 0x33, 0x20, 0x00, 0x21, 0x1c))
|
Ok(listOf<UByte>(0x17u, 0x0fu, 0x12u, 0x0cu, 0x04u, 0x20u, 0x31u, 0x32u, 0x33u, 0x20u, 0x00u, 0x21u, 0x1cu))
|
||||||
Petscii.encodeScreencode("♥") shouldBe Ok(listOf<Short>(0x53))
|
Petscii.encodeScreencode("♥") shouldBe Ok(listOf<UByte>(0x53u))
|
||||||
Petscii.encodeScreencode("π") shouldBe Ok(listOf<Short>(0x5e))
|
Petscii.encodeScreencode("π") shouldBe Ok(listOf<UByte>(0x5eu))
|
||||||
Petscii.encodeScreencode("HELLO") shouldBe Ok(listOf<Short>(8, 5, 12, 12, 15))
|
Petscii.encodeScreencode("HELLO") shouldBe Ok(listOf<UByte>(8u, 5u, 12u, 12u, 15u))
|
||||||
withClue("expecting fallback") {
|
withClue("expecting fallback") {
|
||||||
Petscii.encodeScreencode("hello") shouldBe Ok(listOf<Short>(8, 5, 12, 12, 15))
|
Petscii.encodeScreencode("hello") shouldBe Ok(listOf<UByte>(8u, 5u, 12u, 12u, 15u))
|
||||||
Petscii.encodeScreencode("✓") shouldBe Ok(listOf<Short>(122))
|
Petscii.encodeScreencode("✓") shouldBe Ok(listOf<UByte>(122u))
|
||||||
}
|
}
|
||||||
|
|
||||||
Petscii.decodeScreencode(listOf(0x17, 0x1c, 0x53, 0x5e)) shouldBe "W£♥π"
|
Petscii.decodeScreencode(listOf(0x17u, 0x1cu, 0x53u, 0x5eu)) shouldBe "W£♥π"
|
||||||
}
|
}
|
||||||
|
|
||||||
test("testErrorCases") {
|
test("testErrorCases") {
|
||||||
@ -77,22 +75,6 @@ class TestPetscii: FunSpec({
|
|||||||
Petscii.encodePetscii("~", false).expectError { "shouldn't be able to encode tilde" }
|
Petscii.encodePetscii("~", false).expectError { "shouldn't be able to encode tilde" }
|
||||||
Petscii.encodeScreencode("~", true).expectError { "shouldn't be able to encode tilde" }
|
Petscii.encodeScreencode("~", true).expectError { "shouldn't be able to encode tilde" }
|
||||||
Petscii.encodeScreencode("~", false).expectError { "shouldn't be able to encode tilde" }
|
Petscii.encodeScreencode("~", false).expectError { "shouldn't be able to encode tilde" }
|
||||||
|
|
||||||
shouldThrow<CharConversionException> { Petscii.decodePetscii(listOf<Short>(-1), true) }
|
|
||||||
shouldThrow<CharConversionException> { Petscii.decodePetscii(listOf<Short>(256), true) }
|
|
||||||
shouldThrow<CharConversionException> { Petscii.decodePetscii(listOf<Short>(-1), false) }
|
|
||||||
shouldThrow<CharConversionException> { Petscii.decodePetscii(listOf<Short>(256), false) }
|
|
||||||
shouldThrow<CharConversionException> { Petscii.decodeScreencode(listOf<Short>(-1), true) }
|
|
||||||
shouldThrow<CharConversionException> { Petscii.decodeScreencode(listOf<Short>(256), true) }
|
|
||||||
shouldThrow<CharConversionException> { Petscii.decodeScreencode(listOf<Short>(-1), false) }
|
|
||||||
shouldThrow<CharConversionException> { Petscii.decodeScreencode(listOf<Short>(256), false) }
|
|
||||||
|
|
||||||
Petscii.scr2petscii(-1).expectError { "-1 should error" }
|
|
||||||
Petscii.scr2petscii(256).expectError { "256 should error" }
|
|
||||||
Petscii.petscii2scr(-1, true).expectError { "-1 should error" }
|
|
||||||
Petscii.petscii2scr(256, true).expectError { "256 should error" }
|
|
||||||
Petscii.petscii2scr(-1, false).expectError { "-1 should error" }
|
|
||||||
Petscii.petscii2scr(256, false).expectError { "256 should error" }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test("testSpecialReplacements") {
|
test("testSpecialReplacements") {
|
||||||
@ -104,30 +86,30 @@ class TestPetscii: FunSpec({
|
|||||||
Petscii.encodePetscii("~", false).expectError { "shouldn't have translation for tilde" }
|
Petscii.encodePetscii("~", false).expectError { "shouldn't have translation for tilde" }
|
||||||
Petscii.encodePetscii("~", true).expectError { "shouldn't have translation for tilde" }
|
Petscii.encodePetscii("~", true).expectError { "shouldn't have translation for tilde" }
|
||||||
|
|
||||||
encodeP('^', false) shouldBe 94
|
encodeP('^', false) shouldBe 94u
|
||||||
encodeP('^', true) shouldBe 94
|
encodeP('^', true) shouldBe 94u
|
||||||
encodeS('^', false) shouldBe 30
|
encodeS('^', false) shouldBe 30u
|
||||||
encodeS('^', true) shouldBe 30
|
encodeS('^', true) shouldBe 30u
|
||||||
encodeP('_', false) shouldBe 228
|
encodeP('_', false) shouldBe 228u
|
||||||
encodeP('_', true) shouldBe 228
|
encodeP('_', true) shouldBe 228u
|
||||||
encodeS('_', false) shouldBe 100
|
encodeS('_', false) shouldBe 100u
|
||||||
encodeS('_', true) shouldBe 100
|
encodeS('_', true) shouldBe 100u
|
||||||
encodeP('{', false) shouldBe 243
|
encodeP('{', false) shouldBe 243u
|
||||||
encodeP('{', true) shouldBe 243
|
encodeP('{', true) shouldBe 243u
|
||||||
encodeS('{', false) shouldBe 115
|
encodeS('{', false) shouldBe 115u
|
||||||
encodeS('{', true) shouldBe 115
|
encodeS('{', true) shouldBe 115u
|
||||||
encodeP('}', false) shouldBe 235
|
encodeP('}', false) shouldBe 235u
|
||||||
encodeP('}', true) shouldBe 235
|
encodeP('}', true) shouldBe 235u
|
||||||
encodeS('}', false) shouldBe 107
|
encodeS('}', false) shouldBe 107u
|
||||||
encodeS('}', true) shouldBe 107
|
encodeS('}', true) shouldBe 107u
|
||||||
encodeP('|', false) shouldBe 221
|
encodeP('|', false) shouldBe 221u
|
||||||
encodeP('|', true) shouldBe 221
|
encodeP('|', true) shouldBe 221u
|
||||||
encodeS('|', false) shouldBe 93
|
encodeS('|', false) shouldBe 93u
|
||||||
encodeS('|', true) shouldBe 93
|
encodeS('|', true) shouldBe 93u
|
||||||
encodeP('\\', false) shouldBe 205
|
encodeP('\\', false) shouldBe 205u
|
||||||
encodeP('\\', true) shouldBe 205
|
encodeP('\\', true) shouldBe 205u
|
||||||
encodeS('\\', false) shouldBe 77
|
encodeS('\\', false) shouldBe 77u
|
||||||
encodeS('\\', true) shouldBe 77
|
encodeS('\\', true) shouldBe 77u
|
||||||
}
|
}
|
||||||
|
|
||||||
test("testBoxDrawingCharsEncoding") {
|
test("testBoxDrawingCharsEncoding") {
|
||||||
@ -135,59 +117,59 @@ class TestPetscii: FunSpec({
|
|||||||
fun encodeS(c: Char, lower: Boolean) = Petscii.encodeScreencode(c.toString(), lower).getOrElse { throw it }.single()
|
fun encodeS(c: Char, lower: Boolean) = Petscii.encodeScreencode(c.toString(), lower).getOrElse { throw it }.single()
|
||||||
|
|
||||||
// pipe char
|
// pipe char
|
||||||
encodeP('|', false) shouldBe 221
|
encodeP('|', false) shouldBe 221u
|
||||||
encodeP('|', true) shouldBe 221
|
encodeP('|', true) shouldBe 221u
|
||||||
encodeS('|', false) shouldBe 93
|
encodeS('|', false) shouldBe 93u
|
||||||
encodeS('|', true) shouldBe 93
|
encodeS('|', true) shouldBe 93u
|
||||||
// ... same as '│', 0x7D -> BOX DRAWINGS LIGHT VERTICAL
|
// ... same as '│', 0x7D -> BOX DRAWINGS LIGHT VERTICAL
|
||||||
encodeP('│', false) shouldBe 221
|
encodeP('│', false) shouldBe 221u
|
||||||
encodeP('│', true) shouldBe 221
|
encodeP('│', true) shouldBe 221u
|
||||||
encodeS('│', false) shouldBe 93
|
encodeS('│', false) shouldBe 93u
|
||||||
encodeS('│', true) shouldBe 93
|
encodeS('│', true) shouldBe 93u
|
||||||
|
|
||||||
// underscore
|
// underscore
|
||||||
encodeP('_', false) shouldBe 228
|
encodeP('_', false) shouldBe 228u
|
||||||
encodeP('_', true) shouldBe 228
|
encodeP('_', true) shouldBe 228u
|
||||||
encodeS('_', false) shouldBe 100
|
encodeS('_', false) shouldBe 100u
|
||||||
encodeS('_', true) shouldBe 100
|
encodeS('_', true) shouldBe 100u
|
||||||
// ... same as '▁', 0xE4 LOWER ONE EIGHTH BLOCK
|
// ... same as '▁', 0xE4 LOWER ONE EIGHTH BLOCK
|
||||||
encodeP('▁', false) shouldBe 228
|
encodeP('▁', false) shouldBe 228u
|
||||||
encodeP('▁', true) shouldBe 228
|
encodeP('▁', true) shouldBe 228u
|
||||||
encodeS('▁', false) shouldBe 100
|
encodeS('▁', false) shouldBe 100u
|
||||||
encodeS('▁', true) shouldBe 100
|
encodeS('▁', true) shouldBe 100u
|
||||||
|
|
||||||
// ─ 0xC0 -> BOX DRAWINGS LIGHT HORIZONTAL
|
// ─ 0xC0 -> BOX DRAWINGS LIGHT HORIZONTAL
|
||||||
encodeP('─', false) shouldBe 192
|
encodeP('─', false) shouldBe 192u
|
||||||
encodeP('─', true) shouldBe 192
|
encodeP('─', true) shouldBe 192u
|
||||||
encodeS('─', false) shouldBe 64
|
encodeS('─', false) shouldBe 64u
|
||||||
encodeS('─', true) shouldBe 64
|
encodeS('─', true) shouldBe 64u
|
||||||
// │ 0x62 -> BOX DRAWINGS LIGHT VERTICAL
|
// │ 0x62 -> BOX DRAWINGS LIGHT VERTICAL
|
||||||
encodeP('│', false) shouldBe 221
|
encodeP('│', false) shouldBe 221u
|
||||||
encodeP('│', true) shouldBe 221
|
encodeP('│', true) shouldBe 221u
|
||||||
encodeS('│', false) shouldBe 93
|
encodeS('│', false) shouldBe 93u
|
||||||
encodeS('│', true) shouldBe 93
|
encodeS('│', true) shouldBe 93u
|
||||||
}
|
}
|
||||||
|
|
||||||
test("testBoxDrawingCharsDecoding") {
|
test("testBoxDrawingCharsDecoding") {
|
||||||
// ─ 0xC0 -> BOX DRAWINGS LIGHT HORIZONTAL
|
// ─ 0xC0 -> BOX DRAWINGS LIGHT HORIZONTAL
|
||||||
Petscii.decodePetscii(listOf(195), false).single() shouldBe '\uf13b' //"BOX DRAWINGS LIGHT HORIZONTAL ONE EIGHTH UP (CUS)"
|
Petscii.decodePetscii(listOf(195u), false).single() shouldBe '\uf13b' //"BOX DRAWINGS LIGHT HORIZONTAL ONE EIGHTH UP (CUS)"
|
||||||
Petscii.decodePetscii(listOf(195), true).single() shouldBe 'C'
|
Petscii.decodePetscii(listOf(195u), true).single() shouldBe 'C'
|
||||||
Petscii.decodePetscii(listOf(192), false).single() shouldBe '─'
|
Petscii.decodePetscii(listOf(192u), false).single() shouldBe '─'
|
||||||
Petscii.decodePetscii(listOf(192), true).single() shouldBe '─'
|
Petscii.decodePetscii(listOf(192u), true).single() shouldBe '─'
|
||||||
Petscii.decodeScreencode(listOf(67), false).single() shouldBe '\uf13b' //"BOX DRAWINGS LIGHT HORIZONTAL ONE EIGHTH UP (CUS)"
|
Petscii.decodeScreencode(listOf(67u), false).single() shouldBe '\uf13b' //"BOX DRAWINGS LIGHT HORIZONTAL ONE EIGHTH UP (CUS)"
|
||||||
Petscii.decodeScreencode(listOf(67), true).single() shouldBe 'C'
|
Petscii.decodeScreencode(listOf(67u), true).single() shouldBe 'C'
|
||||||
Petscii.decodeScreencode(listOf(64), false).single() shouldBe '─'
|
Petscii.decodeScreencode(listOf(64u), false).single() shouldBe '─'
|
||||||
Petscii.decodeScreencode(listOf(64), true).single() shouldBe '─'
|
Petscii.decodeScreencode(listOf(64u), true).single() shouldBe '─'
|
||||||
|
|
||||||
// │ 0x62 -> BOX DRAWINGS LIGHT VERTICAL
|
// │ 0x62 -> BOX DRAWINGS LIGHT VERTICAL
|
||||||
Petscii.decodePetscii(listOf(125), false).single() shouldBe '│'
|
Petscii.decodePetscii(listOf(125u), false).single() shouldBe '│'
|
||||||
Petscii.decodePetscii(listOf(125), true).single() shouldBe '│'
|
Petscii.decodePetscii(listOf(125u), true).single() shouldBe '│'
|
||||||
Petscii.decodePetscii(listOf(221), false).single() shouldBe '│'
|
Petscii.decodePetscii(listOf(221u), false).single() shouldBe '│'
|
||||||
Petscii.decodePetscii(listOf(221), true).single() shouldBe '│'
|
Petscii.decodePetscii(listOf(221u), true).single() shouldBe '│'
|
||||||
Petscii.decodeScreencode(listOf(93), false).single() shouldBe '│'
|
Petscii.decodeScreencode(listOf(93u), false).single() shouldBe '│'
|
||||||
Petscii.decodeScreencode(listOf(93), true).single() shouldBe '│'
|
Petscii.decodeScreencode(listOf(93u), true).single() shouldBe '│'
|
||||||
Petscii.decodeScreencode(listOf(66), false).single() shouldBe '\uf13c' // "BOX DRAWINGS LIGHT VERTICAL ONE EIGHTH LEFT (CUS)"
|
Petscii.decodeScreencode(listOf(66u), false).single() shouldBe '\uf13c' // "BOX DRAWINGS LIGHT VERTICAL ONE EIGHTH LEFT (CUS)"
|
||||||
Petscii.decodeScreencode(listOf(66), true).single() shouldBe 'B'
|
Petscii.decodeScreencode(listOf(66u), true).single() shouldBe 'B'
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@ -23,11 +23,11 @@ class TestAbstractZeropage: FunSpec({
|
|||||||
override val machine: IMachineDefinition
|
override val machine: IMachineDefinition
|
||||||
get() = throw NotImplementedError("dummy")
|
get() = throw NotImplementedError("dummy")
|
||||||
|
|
||||||
override fun encodeString(str: String, altEncoding: Boolean): List<Short> {
|
override fun encodeString(str: String, altEncoding: Boolean): List<UByte> {
|
||||||
throw NotImplementedError("dummy")
|
throw NotImplementedError("dummy")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun decodeString(bytes: List<Short>, altEncoding: Boolean): String {
|
override fun decodeString(bytes: List<UByte>, altEncoding: Boolean): String {
|
||||||
throw NotImplementedError("dummy")
|
throw NotImplementedError("dummy")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,11 +26,11 @@ internal val DummyMemsizer = object : IMemSizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal val DummyStringEncoder = object : IStringEncoding {
|
internal val DummyStringEncoder = object : IStringEncoding {
|
||||||
override fun encodeString(str: String, altEncoding: Boolean): List<Short> {
|
override fun encodeString(str: String, altEncoding: Boolean): List<UByte> {
|
||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun decodeString(bytes: List<Short>, altEncoding: Boolean): String {
|
override fun decodeString(bytes: List<UByte>, altEncoding: Boolean): String {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,12 +113,8 @@ class PrefixExpression(val operator: String, var expression: Expression, overrid
|
|||||||
"not" -> NumericLiteralValue.fromBoolean(constval.number == 0.0, constval.position)
|
"not" -> NumericLiteralValue.fromBoolean(constval.number == 0.0, constval.position)
|
||||||
else -> throw FatalAstException("invalid operator")
|
else -> throw FatalAstException("invalid operator")
|
||||||
}
|
}
|
||||||
return if(converted==null)
|
converted.linkParents(this.parent)
|
||||||
null
|
return converted
|
||||||
else {
|
|
||||||
converted.linkParents(this.parent)
|
|
||||||
converted
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
override fun accept(visitor: IAstVisitor) = visitor.visit(this)
|
override fun accept(visitor: IAstVisitor) = visitor.visit(this)
|
||||||
override fun accept(visitor: AstWalker, parent: Node)= visitor.visit(this, parent)
|
override fun accept(visitor: AstWalker, parent: Node)= visitor.visit(this, parent)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package prog8.compilerinterface
|
package prog8.compilerinterface
|
||||||
|
|
||||||
interface IStringEncoding {
|
interface IStringEncoding {
|
||||||
fun encodeString(str: String, altEncoding: Boolean): List<Short>
|
fun encodeString(str: String, altEncoding: Boolean): List<UByte>
|
||||||
fun decodeString(bytes: List<Short>, altEncoding: Boolean): String
|
fun decodeString(bytes: List<UByte>, altEncoding: Boolean): String
|
||||||
}
|
}
|
||||||
|
@ -26,19 +26,19 @@ internal val DummyMemsizer = object : IMemSizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal val DummyStringEncoder = object : IStringEncoding {
|
internal val DummyStringEncoder = object : IStringEncoding {
|
||||||
override fun encodeString(str: String, altEncoding: Boolean): List<Short> {
|
override fun encodeString(str: String, altEncoding: Boolean): List<UByte> {
|
||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun decodeString(bytes: List<Short>, altEncoding: Boolean): String {
|
override fun decodeString(bytes: List<UByte>, altEncoding: Boolean): String {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val AsciiStringEncoder = object : IStringEncoding {
|
internal val AsciiStringEncoder = object : IStringEncoding {
|
||||||
override fun encodeString(str: String, altEncoding: Boolean): List<Short> = str.map { it.code.toShort() }
|
override fun encodeString(str: String, altEncoding: Boolean): List<UByte> = str.map { it.code.toUByte() }
|
||||||
|
|
||||||
override fun decodeString(bytes: List<Short>, altEncoding: Boolean): String {
|
override fun decodeString(bytes: List<UByte>, altEncoding: Boolean): String {
|
||||||
return bytes.joinToString()
|
return bytes.joinToString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,6 @@ package prog8.compilerinterface
|
|||||||
interface ICompilationTarget: IStringEncoding, IMemSizer {
|
interface ICompilationTarget: IStringEncoding, IMemSizer {
|
||||||
val name: String
|
val name: String
|
||||||
val machine: IMachineDefinition
|
val machine: IMachineDefinition
|
||||||
override fun encodeString(str: String, altEncoding: Boolean): List<Short>
|
override fun encodeString(str: String, altEncoding: Boolean): List<UByte>
|
||||||
override fun decodeString(bytes: List<Short>, altEncoding: Boolean): String
|
override fun decodeString(bytes: List<UByte>, altEncoding: Boolean): String
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,50 @@ main {
|
|||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
|
||||||
|
ubyte xx = 1
|
||||||
|
ubyte yy = 2
|
||||||
|
byte b1
|
||||||
|
byte b2=10
|
||||||
|
|
||||||
|
; result should be: 29 42 40 87 75 35
|
||||||
|
|
||||||
|
xx=6
|
||||||
|
yy=8
|
||||||
|
yy = (xx+5)+(yy+10)
|
||||||
|
txt.print_ub(yy) ; 29
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
xx=6
|
||||||
|
yy=8
|
||||||
|
yy = (xx*3)+(yy*3)
|
||||||
|
txt.print_ub(yy) ; 42
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
b1=13
|
||||||
|
b2=5
|
||||||
|
b2 = (b1*5)-(b2*5)
|
||||||
|
txt.print_b(b2) ; 40
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
b1=100
|
||||||
|
b2=8
|
||||||
|
b2 = (b1+5)-(b2+10)
|
||||||
|
txt.print_b(b2) ; 87
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
b1=50
|
||||||
|
b2=40
|
||||||
|
b2 = (b1-5)+(b2-10)
|
||||||
|
txt.print_b(b2) ; 75
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
b1=50
|
||||||
|
b2=20
|
||||||
|
b2 = (b1-5)-(b2-10)
|
||||||
|
txt.print_b(b2) ; 35
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
repeat {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user