char encodings now use UByte type instead of short

This commit is contained in:
Irmen de Jong 2021-11-21 00:07:17 +01:00
parent 2491509c6a
commit c0035ba1a2
14 changed files with 201 additions and 179 deletions

View File

@ -13,14 +13,14 @@ import prog8.compilerinterface.ICompilationTarget
object C64Target: ICompilationTarget {
override val name = "c64"
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)
return coded.fold(
failure = { throw 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)
override fun memorySize(dt: DataType): Int {

View File

@ -13,14 +13,14 @@ import prog8.compilerinterface.ICompilationTarget
object Cx16Target: ICompilationTarget {
override val name = "cx16"
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)
return coded.fold(
failure = { throw 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)
override fun memorySize(dt: DataType): Int {

View File

@ -1065,15 +1065,15 @@ object Petscii {
else -> chr
}
fun encodePetscii(text: String, lowercase: Boolean = false): Result<List<Short>, CharConversionException> {
fun encodeChar(chr3: Char, lowercase: Boolean): Short {
fun encodePetscii(text: String, lowercase: Boolean = false): Result<List<UByte>, CharConversionException> {
fun encodeChar(chr3: Char, lowercase: Boolean): UByte {
val chr = replaceSpecial(chr3)
val screencode = if(lowercase) encodingPetsciiLowercase[chr] else encodingPetsciiUppercase[chr]
return screencode?.toShort() ?: when (chr) {
'\u0000' -> 0.toShort()
return screencode?.toUByte() ?: when (chr) {
'\u0000' -> 0u
in '\u8000'..'\u80ff' -> {
// special case: take the lower 8 bit hex value directly
(chr.code - 0x8000).toShort()
(chr.code - 0x8000).toUByte()
}
else -> {
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 {
val code = it.toInt()
if(code<0 || code>= decodingPetsciiLowercase.size)
@ -1104,15 +1104,15 @@ object Petscii {
}.joinToString("")
}
fun encodeScreencode(text: String, lowercase: Boolean = false): Result<List<Short>, CharConversionException> {
fun encodeChar(chr3: Char, lowercase: Boolean): Short {
fun encodeScreencode(text: String, lowercase: Boolean = false): Result<List<UByte>, CharConversionException> {
fun encodeChar(chr3: Char, lowercase: Boolean): UByte {
val chr = replaceSpecial(chr3)
val screencode = if(lowercase) encodingScreencodeLowercase[chr] else encodingScreencodeUppercase[chr]
return screencode?.toShort() ?: when (chr) {
'\u0000' -> 0.toShort()
return screencode?.toUByte() ?: when (chr) {
'\u0000' -> 0u
in '\u8000'..'\u80ff' -> {
// special case: take the lower 8 bit hex value directly
(chr.code - 0x8000).toShort()
(chr.code - 0x8000).toUByte()
}
else -> {
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 {
val code = it.toInt()
if(code<0 || code>= decodingScreencodeLowercase.size)
@ -1143,38 +1143,37 @@ object Petscii {
}.joinToString("")
}
fun petscii2scr(petscii_code: Short, inverseVideo: Boolean): Result<Short, CharConversionException> {
val code = when {
petscii_code < 0 -> return Err(CharConversionException("petscii code out of range"))
petscii_code <= 0x1f -> petscii_code + 128
petscii_code <= 0x3f -> petscii_code.toInt()
petscii_code <= 0x5f -> petscii_code - 64
petscii_code <= 0x7f -> petscii_code - 32
petscii_code <= 0x9f -> petscii_code + 64
petscii_code <= 0xbf -> petscii_code - 64
petscii_code <= 0xfe -> petscii_code - 128
petscii_code == 255.toShort() -> 95
fun petscii2scr(petscii_code: UByte, inverseVideo: Boolean): Result<UByte, CharConversionException> {
val code: UInt = when {
petscii_code <= 0x1fu -> petscii_code + 128u
petscii_code <= 0x3fu -> petscii_code.toUInt()
petscii_code <= 0x5fu -> petscii_code - 64u
petscii_code <= 0x7fu -> petscii_code - 32u
petscii_code <= 0x9fu -> petscii_code + 64u
petscii_code <= 0xbfu -> petscii_code - 64u
petscii_code <= 0xfeu -> petscii_code - 128u
petscii_code == 255.toUByte() -> 95u
else -> return Err(CharConversionException("petscii code out of range"))
}
if(inverseVideo)
return Ok((code or 0x80).toShort())
return Ok(code.toShort())
if(inverseVideo) {
return Ok((code or 0x80u).toUByte())
}
return Ok(code.toUByte())
}
fun scr2petscii(screencode: Short): Result<Short, CharConversionException> {
val petscii = when {
screencode < 0 -> return Err(CharConversionException("screencode out of range"))
screencode <= 0x1f -> screencode + 64
screencode <= 0x3f -> screencode.toInt()
screencode <= 0x5d -> screencode +123
screencode == 0x5e.toShort() -> 255
screencode == 0x5f.toShort() -> 223
screencode <= 0x7f -> screencode + 64
screencode <= 0xbf -> screencode - 128
screencode <= 0xfe -> screencode - 64
screencode == 255.toShort() -> 191
fun scr2petscii(screencode: UByte): Result<UByte, CharConversionException> {
val petscii: UInt = when {
screencode <= 0x1fu -> screencode + 64u
screencode <= 0x3fu -> screencode.toUInt()
screencode <= 0x5du -> screencode +123u
screencode == 0x5e.toUByte() -> 255u
screencode == 0x5f.toUByte() -> 223u
screencode <= 0x7fu -> screencode + 64u
screencode <= 0xbfu -> screencode - 128u
screencode <= 0xfeu -> screencode - 64u
screencode == 255.toUByte() -> 191u
else -> return Err(CharConversionException("screencode out of range"))
}
return Ok(petscii.toShort())
return Ok(petscii.toUByte())
}
}

View File

@ -297,7 +297,7 @@ class AsmGen(private val program: Program,
DataType.FLOAT -> out("$name\t.byte 0,0,0,0,0 ; float")
DataType.STR -> {
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 -> {
val data = makeArrayFillDataUnsigned(decl)
@ -393,7 +393,7 @@ class AsmGen(private val program: Program,
.filter {it.datatype == DataType.STR }
.map {
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) {
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 altEncoding = if(sv.altEncoding) "@" else ""
out("${strdecl.name}\t; ${strdecl.datatype} $altEncoding\"${escape(sv.value).replace("\u0000", "<NULL>")}\"")

View File

@ -27,11 +27,11 @@ internal val DummyMemsizer = object : IMemSizer {
}
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()
}
override fun decodeString(bytes: List<Short>, altEncoding: Boolean): String {
override fun decodeString(bytes: List<UByte>, altEncoding: Boolean): String {
return ""
}
}

View File

@ -43,7 +43,7 @@ class TestCompilerOnCharLit: FunSpec({
}
val arg = funCall.args[0] as NumericLiteralValue
arg.type shouldBe DataType.UBYTE
arg.number shouldBe platform.encodeString("\n", false)[0]
arg.number shouldBe platform.encodeString("\n", false)[0].toDouble()
}
test("testCharVarAsRomsubArg") {
@ -83,7 +83,7 @@ class TestCompilerOnCharLit: FunSpec({
}
val initializerValue = assignInitialValue.value as NumericLiteralValue
initializerValue.type shouldBe DataType.UBYTE
initializerValue.number shouldBe platform.encodeString("\n", false)[0]
initializerValue.number shouldBe platform.encodeString("\n", false)[0].toDouble()
}
test("testCharConstAsRomsubArg") {
@ -111,7 +111,7 @@ class TestCompilerOnCharLit: FunSpec({
(decl.value as NumericLiteralValue).number shouldBe platform.encodeString("\n", false)[0]
}
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
}

View File

@ -3,73 +3,71 @@ package prog8tests
import com.github.michaelbull.result.Ok
import com.github.michaelbull.result.expectError
import com.github.michaelbull.result.getOrElse
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.assertions.withClue
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import prog8.compiler.target.cbm.Petscii
import java.io.CharConversionException
class TestPetscii: FunSpec({
test("testZero") {
Petscii.encodePetscii("\u0000", true) shouldBe Ok(listOf<Short>(0))
Petscii.encodePetscii("\u0000", false) shouldBe Ok(listOf<Short>(0))
Petscii.decodePetscii(listOf(0), true) shouldBe "\u0000"
Petscii.decodePetscii(listOf(0), false) shouldBe "\u0000"
Petscii.encodePetscii("\u0000", true) shouldBe Ok(listOf<UByte>(0u))
Petscii.encodePetscii("\u0000", false) shouldBe Ok(listOf<UByte>(0u))
Petscii.decodePetscii(listOf(0u), true) shouldBe "\u0000"
Petscii.decodePetscii(listOf(0u), false) shouldBe "\u0000"
}
test("testLowercase") {
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))
Petscii.encodePetscii("\uf11a", true) shouldBe Ok(listOf<Short>(0x12)) // reverse vid
Petscii.encodePetscii("", true) shouldBe Ok(listOf<Short>(0xfa))
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<UByte>(0x12u)) // reverse vid
Petscii.encodePetscii("", true) shouldBe Ok(listOf<UByte>(0xfau))
withClue("expect lowercase error fallback") {
Petscii.encodePetscii("π", true) shouldBe Ok(listOf<Short>(255))
Petscii.encodePetscii("", true) shouldBe Ok(listOf<Short>(0xd3))
Petscii.encodePetscii("π", true) shouldBe Ok(listOf<UByte>(255u))
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") {
Petscii.encodePetscii("HELLO 123 @!£") shouldBe
Ok(listOf<Short>(72, 69, 76, 76, 79, 32, 49, 50, 51, 32, 64, 33, 0x5c))
Petscii.encodePetscii("\uf11a") shouldBe Ok(listOf<Short>(0x12)) // reverse vid
Petscii.encodePetscii("") shouldBe Ok(listOf<Short>(0xd3))
Petscii.encodePetscii("π") shouldBe Ok(listOf<Short>(0xff))
Ok(listOf<UByte>(72u, 69u, 76u, 76u, 79u, 32u, 49u, 50u, 51u, 32u, 64u, 33u, 0x5cu))
Petscii.encodePetscii("\uf11a") shouldBe Ok(listOf<UByte>(0x12u)) // reverse vid
Petscii.encodePetscii("") shouldBe Ok(listOf<UByte>(0xd3u))
Petscii.encodePetscii("π") shouldBe Ok(listOf<UByte>(0xffu))
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") {
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))
Petscii.encodeScreencode("", true) shouldBe Ok(listOf<Short>(0x7a))
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<UByte>(0x7au))
withClue("expect fallback") {
Petscii.encodeScreencode("", true) shouldBe Ok(listOf<Short>(83))
Petscii.encodeScreencode("π", true) shouldBe Ok(listOf<Short>(94))
Petscii.encodeScreencode("", true) shouldBe Ok(listOf<UByte>(83u))
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") {
Petscii.encodeScreencode("WORLD 123 @!£") shouldBe
Ok(listOf<Short>(0x17, 0x0f, 0x12, 0x0c, 0x04, 0x20, 0x31, 0x32, 0x33, 0x20, 0x00, 0x21, 0x1c))
Petscii.encodeScreencode("") shouldBe Ok(listOf<Short>(0x53))
Petscii.encodeScreencode("π") shouldBe Ok(listOf<Short>(0x5e))
Petscii.encodeScreencode("HELLO") shouldBe Ok(listOf<Short>(8, 5, 12, 12, 15))
Ok(listOf<UByte>(0x17u, 0x0fu, 0x12u, 0x0cu, 0x04u, 0x20u, 0x31u, 0x32u, 0x33u, 0x20u, 0x00u, 0x21u, 0x1cu))
Petscii.encodeScreencode("") shouldBe Ok(listOf<UByte>(0x53u))
Petscii.encodeScreencode("π") shouldBe Ok(listOf<UByte>(0x5eu))
Petscii.encodeScreencode("HELLO") shouldBe Ok(listOf<UByte>(8u, 5u, 12u, 12u, 15u))
withClue("expecting fallback") {
Petscii.encodeScreencode("hello") shouldBe Ok(listOf<Short>(8, 5, 12, 12, 15))
Petscii.encodeScreencode("") shouldBe Ok(listOf<Short>(122))
Petscii.encodeScreencode("hello") shouldBe Ok(listOf<UByte>(8u, 5u, 12u, 12u, 15u))
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") {
@ -77,22 +75,6 @@ class TestPetscii: FunSpec({
Petscii.encodePetscii("~", false).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" }
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") {
@ -104,30 +86,30 @@ class TestPetscii: FunSpec({
Petscii.encodePetscii("~", false).expectError { "shouldn't have translation for tilde" }
Petscii.encodePetscii("~", true).expectError { "shouldn't have translation for tilde" }
encodeP('^', false) shouldBe 94
encodeP('^', true) shouldBe 94
encodeS('^', false) shouldBe 30
encodeS('^', true) shouldBe 30
encodeP('_', false) shouldBe 228
encodeP('_', true) shouldBe 228
encodeS('_', false) shouldBe 100
encodeS('_', true) shouldBe 100
encodeP('{', false) shouldBe 243
encodeP('{', true) shouldBe 243
encodeS('{', false) shouldBe 115
encodeS('{', true) shouldBe 115
encodeP('}', false) shouldBe 235
encodeP('}', true) shouldBe 235
encodeS('}', false) shouldBe 107
encodeS('}', true) shouldBe 107
encodeP('|', false) shouldBe 221
encodeP('|', true) shouldBe 221
encodeS('|', false) shouldBe 93
encodeS('|', true) shouldBe 93
encodeP('\\', false) shouldBe 205
encodeP('\\', true) shouldBe 205
encodeS('\\', false) shouldBe 77
encodeS('\\', true) shouldBe 77
encodeP('^', false) shouldBe 94u
encodeP('^', true) shouldBe 94u
encodeS('^', false) shouldBe 30u
encodeS('^', true) shouldBe 30u
encodeP('_', false) shouldBe 228u
encodeP('_', true) shouldBe 228u
encodeS('_', false) shouldBe 100u
encodeS('_', true) shouldBe 100u
encodeP('{', false) shouldBe 243u
encodeP('{', true) shouldBe 243u
encodeS('{', false) shouldBe 115u
encodeS('{', true) shouldBe 115u
encodeP('}', false) shouldBe 235u
encodeP('}', true) shouldBe 235u
encodeS('}', false) shouldBe 107u
encodeS('}', true) shouldBe 107u
encodeP('|', false) shouldBe 221u
encodeP('|', true) shouldBe 221u
encodeS('|', false) shouldBe 93u
encodeS('|', true) shouldBe 93u
encodeP('\\', false) shouldBe 205u
encodeP('\\', true) shouldBe 205u
encodeS('\\', false) shouldBe 77u
encodeS('\\', true) shouldBe 77u
}
test("testBoxDrawingCharsEncoding") {
@ -135,59 +117,59 @@ class TestPetscii: FunSpec({
fun encodeS(c: Char, lower: Boolean) = Petscii.encodeScreencode(c.toString(), lower).getOrElse { throw it }.single()
// pipe char
encodeP('|', false) shouldBe 221
encodeP('|', true) shouldBe 221
encodeS('|', false) shouldBe 93
encodeS('|', true) shouldBe 93
encodeP('|', false) shouldBe 221u
encodeP('|', true) shouldBe 221u
encodeS('|', false) shouldBe 93u
encodeS('|', true) shouldBe 93u
// ... same as '│', 0x7D -> BOX DRAWINGS LIGHT VERTICAL
encodeP('│', false) shouldBe 221
encodeP('│', true) shouldBe 221
encodeS('│', false) shouldBe 93
encodeS('│', true) shouldBe 93
encodeP('│', false) shouldBe 221u
encodeP('│', true) shouldBe 221u
encodeS('│', false) shouldBe 93u
encodeS('│', true) shouldBe 93u
// underscore
encodeP('_', false) shouldBe 228
encodeP('_', true) shouldBe 228
encodeS('_', false) shouldBe 100
encodeS('_', true) shouldBe 100
encodeP('_', false) shouldBe 228u
encodeP('_', true) shouldBe 228u
encodeS('_', false) shouldBe 100u
encodeS('_', true) shouldBe 100u
// ... same as '▁', 0xE4 LOWER ONE EIGHTH BLOCK
encodeP('▁', false) shouldBe 228
encodeP('▁', true) shouldBe 228
encodeS('▁', false) shouldBe 100
encodeS('▁', true) shouldBe 100
encodeP('▁', false) shouldBe 228u
encodeP('▁', true) shouldBe 228u
encodeS('▁', false) shouldBe 100u
encodeS('▁', true) shouldBe 100u
// ─ 0xC0 -> BOX DRAWINGS LIGHT HORIZONTAL
encodeP('─', false) shouldBe 192
encodeP('─', true) shouldBe 192
encodeS('─', false) shouldBe 64
encodeS('─', true) shouldBe 64
encodeP('─', false) shouldBe 192u
encodeP('─', true) shouldBe 192u
encodeS('─', false) shouldBe 64u
encodeS('─', true) shouldBe 64u
// │ 0x62 -> BOX DRAWINGS LIGHT VERTICAL
encodeP('│', false) shouldBe 221
encodeP('│', true) shouldBe 221
encodeS('│', false) shouldBe 93
encodeS('│', true) shouldBe 93
encodeP('│', false) shouldBe 221u
encodeP('│', true) shouldBe 221u
encodeS('│', false) shouldBe 93u
encodeS('│', true) shouldBe 93u
}
test("testBoxDrawingCharsDecoding") {
// ─ 0xC0 -> BOX DRAWINGS LIGHT HORIZONTAL
Petscii.decodePetscii(listOf(195), false).single() shouldBe '\uf13b' //"BOX DRAWINGS LIGHT HORIZONTAL ONE EIGHTH UP (CUS)"
Petscii.decodePetscii(listOf(195), true).single() shouldBe 'C'
Petscii.decodePetscii(listOf(192), false).single() shouldBe '─'
Petscii.decodePetscii(listOf(192), true).single() shouldBe '─'
Petscii.decodeScreencode(listOf(67), false).single() shouldBe '\uf13b' //"BOX DRAWINGS LIGHT HORIZONTAL ONE EIGHTH UP (CUS)"
Petscii.decodeScreencode(listOf(67), true).single() shouldBe 'C'
Petscii.decodeScreencode(listOf(64), false).single() shouldBe '─'
Petscii.decodeScreencode(listOf(64), true).single() shouldBe '─'
Petscii.decodePetscii(listOf(195u), false).single() shouldBe '\uf13b' //"BOX DRAWINGS LIGHT HORIZONTAL ONE EIGHTH UP (CUS)"
Petscii.decodePetscii(listOf(195u), true).single() shouldBe 'C'
Petscii.decodePetscii(listOf(192u), false).single() shouldBe '─'
Petscii.decodePetscii(listOf(192u), true).single() shouldBe '─'
Petscii.decodeScreencode(listOf(67u), false).single() shouldBe '\uf13b' //"BOX DRAWINGS LIGHT HORIZONTAL ONE EIGHTH UP (CUS)"
Petscii.decodeScreencode(listOf(67u), true).single() shouldBe 'C'
Petscii.decodeScreencode(listOf(64u), false).single() shouldBe '─'
Petscii.decodeScreencode(listOf(64u), true).single() shouldBe '─'
// │ 0x62 -> BOX DRAWINGS LIGHT VERTICAL
Petscii.decodePetscii(listOf(125), false).single() shouldBe '│'
Petscii.decodePetscii(listOf(125), true).single() shouldBe '│'
Petscii.decodePetscii(listOf(221), false).single() shouldBe '│'
Petscii.decodePetscii(listOf(221), true).single() shouldBe '│'
Petscii.decodeScreencode(listOf(93), false).single() shouldBe '│'
Petscii.decodeScreencode(listOf(93), true).single() shouldBe '│'
Petscii.decodeScreencode(listOf(66), false).single() shouldBe '\uf13c' // "BOX DRAWINGS LIGHT VERTICAL ONE EIGHTH LEFT (CUS)"
Petscii.decodeScreencode(listOf(66), true).single() shouldBe 'B'
Petscii.decodePetscii(listOf(125u), false).single() shouldBe '│'
Petscii.decodePetscii(listOf(125u), true).single() shouldBe '│'
Petscii.decodePetscii(listOf(221u), false).single() shouldBe '│'
Petscii.decodePetscii(listOf(221u), true).single() shouldBe '│'
Petscii.decodeScreencode(listOf(93u), false).single() shouldBe '│'
Petscii.decodeScreencode(listOf(93u), true).single() shouldBe '│'
Petscii.decodeScreencode(listOf(66u), false).single() shouldBe '\uf13c' // "BOX DRAWINGS LIGHT VERTICAL ONE EIGHTH LEFT (CUS)"
Petscii.decodeScreencode(listOf(66u), true).single() shouldBe 'B'
}
})

View File

@ -23,11 +23,11 @@ class TestAbstractZeropage: FunSpec({
override val machine: IMachineDefinition
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")
}
override fun decodeString(bytes: List<Short>, altEncoding: Boolean): String {
override fun decodeString(bytes: List<UByte>, altEncoding: Boolean): String {
throw NotImplementedError("dummy")
}

View File

@ -26,11 +26,11 @@ internal val DummyMemsizer = object : IMemSizer {
}
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()
}
override fun decodeString(bytes: List<Short>, altEncoding: Boolean): String {
override fun decodeString(bytes: List<UByte>, altEncoding: Boolean): String {
return ""
}
}

View File

@ -113,12 +113,8 @@ class PrefixExpression(val operator: String, var expression: Expression, overrid
"not" -> NumericLiteralValue.fromBoolean(constval.number == 0.0, constval.position)
else -> throw FatalAstException("invalid operator")
}
return if(converted==null)
null
else {
converted.linkParents(this.parent)
converted
}
converted.linkParents(this.parent)
return converted
}
override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun accept(visitor: AstWalker, parent: Node)= visitor.visit(this, parent)

View File

@ -1,6 +1,6 @@
package prog8.compilerinterface
interface IStringEncoding {
fun encodeString(str: String, altEncoding: Boolean): List<Short>
fun decodeString(bytes: List<Short>, altEncoding: Boolean): String
fun encodeString(str: String, altEncoding: Boolean): List<UByte>
fun decodeString(bytes: List<UByte>, altEncoding: Boolean): String
}

View File

@ -26,19 +26,19 @@ internal val DummyMemsizer = object : IMemSizer {
}
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()
}
override fun decodeString(bytes: List<Short>, altEncoding: Boolean): String {
override fun decodeString(bytes: List<UByte>, altEncoding: Boolean): String {
return ""
}
}
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()
}
}

View File

@ -3,6 +3,6 @@ package prog8.compilerinterface
interface ICompilationTarget: IStringEncoding, IMemSizer {
val name: String
val machine: IMachineDefinition
override fun encodeString(str: String, altEncoding: Boolean): List<Short>
override fun decodeString(bytes: List<Short>, altEncoding: Boolean): String
override fun encodeString(str: String, altEncoding: Boolean): List<UByte>
override fun decodeString(bytes: List<UByte>, altEncoding: Boolean): String
}

View File

@ -4,5 +4,50 @@ main {
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 {
}
}
}