From c0035ba1a27cb997c7820df141822a6830f92934 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 21 Nov 2021 00:07:17 +0100 Subject: [PATCH] char encodings now use UByte type instead of short --- .../src/prog8/compiler/target/C64Target.kt | 4 +- .../src/prog8/compiler/target/Cx16Target.kt | 4 +- .../src/prog8/compiler/target/cbm/Petscii.kt | 77 ++++--- .../compiler/target/cpu6502/codegen/AsmGen.kt | 6 +- codeGeneration/test/helpers/Dummies.kt | 4 +- compiler/test/TestCompilerOnCharLit.kt | 6 +- compiler/test/TestPetscii.kt | 202 ++++++++---------- compiler/test/ZeropageTests.kt | 4 +- compiler/test/helpers/Dummies.kt | 4 +- .../prog8/ast/expressions/AstExpressions.kt | 8 +- .../compilerinterface/IStringEncoding.kt | 4 +- compilerAst/test/helpers/Dummies.kt | 8 +- .../compilerinterface/ICompilationTarget.kt | 4 +- examples/test.p8 | 45 ++++ 14 files changed, 201 insertions(+), 179 deletions(-) diff --git a/codeGeneration/src/prog8/compiler/target/C64Target.kt b/codeGeneration/src/prog8/compiler/target/C64Target.kt index dcb4a03b7..c16ecad57 100644 --- a/codeGeneration/src/prog8/compiler/target/C64Target.kt +++ b/codeGeneration/src/prog8/compiler/target/C64Target.kt @@ -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 { + override fun encodeString(str: String, altEncoding: Boolean): List { 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, altEncoding: Boolean) = + override fun decodeString(bytes: List, altEncoding: Boolean) = if (altEncoding) Petscii.decodeScreencode(bytes, true) else Petscii.decodePetscii(bytes, true) override fun memorySize(dt: DataType): Int { diff --git a/codeGeneration/src/prog8/compiler/target/Cx16Target.kt b/codeGeneration/src/prog8/compiler/target/Cx16Target.kt index 228eb67fb..959081946 100644 --- a/codeGeneration/src/prog8/compiler/target/Cx16Target.kt +++ b/codeGeneration/src/prog8/compiler/target/Cx16Target.kt @@ -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 { + override fun encodeString(str: String, altEncoding: Boolean): List { 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, altEncoding: Boolean) = + override fun decodeString(bytes: List, altEncoding: Boolean) = if (altEncoding) Petscii.decodeScreencode(bytes, true) else Petscii.decodePetscii(bytes, true) override fun memorySize(dt: DataType): Int { diff --git a/codeGeneration/src/prog8/compiler/target/cbm/Petscii.kt b/codeGeneration/src/prog8/compiler/target/cbm/Petscii.kt index bd71d66f3..07ad45b02 100644 --- a/codeGeneration/src/prog8/compiler/target/cbm/Petscii.kt +++ b/codeGeneration/src/prog8/compiler/target/cbm/Petscii.kt @@ -1065,15 +1065,15 @@ object Petscii { else -> chr } - fun encodePetscii(text: String, lowercase: Boolean = false): Result, CharConversionException> { - fun encodeChar(chr3: Char, lowercase: Boolean): Short { + fun encodePetscii(text: String, lowercase: Boolean = false): Result, 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, lowercase: Boolean = false): String { + fun decodePetscii(petscii: Iterable, 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, CharConversionException> { - fun encodeChar(chr3: Char, lowercase: Boolean): Short { + fun encodeScreencode(text: String, lowercase: Boolean = false): Result, 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, lowercase: Boolean = false): String { + fun decodeScreencode(screencode: Iterable, 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 { - 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 { + 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 { - 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 { + 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()) } } diff --git a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt index 687f9cc61..6b2ab6ce9 100644 --- a/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt +++ b/codeGeneration/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt @@ -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) { + private fun outputStringvar(strdecl: VarDecl, bytes: List) { val sv = strdecl.value as StringLiteralValue val altEncoding = if(sv.altEncoding) "@" else "" out("${strdecl.name}\t; ${strdecl.datatype} $altEncoding\"${escape(sv.value).replace("\u0000", "")}\"") diff --git a/codeGeneration/test/helpers/Dummies.kt b/codeGeneration/test/helpers/Dummies.kt index ccb9d10f3..412138f78 100644 --- a/codeGeneration/test/helpers/Dummies.kt +++ b/codeGeneration/test/helpers/Dummies.kt @@ -27,11 +27,11 @@ internal val DummyMemsizer = object : IMemSizer { } internal val DummyStringEncoder = object : IStringEncoding { - override fun encodeString(str: String, altEncoding: Boolean): List { + override fun encodeString(str: String, altEncoding: Boolean): List { return emptyList() } - override fun decodeString(bytes: List, altEncoding: Boolean): String { + override fun decodeString(bytes: List, altEncoding: Boolean): String { return "" } } diff --git a/compiler/test/TestCompilerOnCharLit.kt b/compiler/test/TestCompilerOnCharLit.kt index 5c02e0f48..f80f61ede 100644 --- a/compiler/test/TestCompilerOnCharLit.kt +++ b/compiler/test/TestCompilerOnCharLit.kt @@ -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() // make test fail } diff --git a/compiler/test/TestPetscii.kt b/compiler/test/TestPetscii.kt index a7a0bd6ef..6a93b3633 100644 --- a/compiler/test/TestPetscii.kt +++ b/compiler/test/TestPetscii.kt @@ -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(0)) - Petscii.encodePetscii("\u0000", false) shouldBe Ok(listOf(0)) - Petscii.decodePetscii(listOf(0), true) shouldBe "\u0000" - Petscii.decodePetscii(listOf(0), false) shouldBe "\u0000" + Petscii.encodePetscii("\u0000", true) shouldBe Ok(listOf(0u)) + Petscii.encodePetscii("\u0000", false) shouldBe Ok(listOf(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(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(0x12)) // reverse vid - Petscii.encodePetscii("✓", true) shouldBe Ok(listOf(0xfa)) + Ok(listOf(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(0x12u)) // reverse vid + Petscii.encodePetscii("✓", true) shouldBe Ok(listOf(0xfau)) withClue("expect lowercase error fallback") { - Petscii.encodePetscii("π", true) shouldBe Ok(listOf(255)) - Petscii.encodePetscii("♥", true) shouldBe Ok(listOf(0xd3)) + Petscii.encodePetscii("π", true) shouldBe Ok(listOf(255u)) + Petscii.encodePetscii("♥", true) shouldBe Ok(listOf(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(72, 69, 76, 76, 79, 32, 49, 50, 51, 32, 64, 33, 0x5c)) - Petscii.encodePetscii("\uf11a") shouldBe Ok(listOf(0x12)) // reverse vid - Petscii.encodePetscii("♥") shouldBe Ok(listOf(0xd3)) - Petscii.encodePetscii("π") shouldBe Ok(listOf(0xff)) + Ok(listOf(72u, 69u, 76u, 76u, 79u, 32u, 49u, 50u, 51u, 32u, 64u, 33u, 0x5cu)) + Petscii.encodePetscii("\uf11a") shouldBe Ok(listOf(0x12u)) // reverse vid + Petscii.encodePetscii("♥") shouldBe Ok(listOf(0xd3u)) + Petscii.encodePetscii("π") shouldBe Ok(listOf(0xffu)) withClue("expecting fallback") { - Petscii.encodePetscii("✓") shouldBe Ok(listOf(250)) + Petscii.encodePetscii("✓") shouldBe Ok(listOf(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(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(0x7a)) + Ok(listOf(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(0x7au)) withClue("expect fallback") { - Petscii.encodeScreencode("♥", true) shouldBe Ok(listOf(83)) - Petscii.encodeScreencode("π", true) shouldBe Ok(listOf(94)) + Petscii.encodeScreencode("♥", true) shouldBe Ok(listOf(83u)) + Petscii.encodeScreencode("π", true) shouldBe Ok(listOf(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(0x17, 0x0f, 0x12, 0x0c, 0x04, 0x20, 0x31, 0x32, 0x33, 0x20, 0x00, 0x21, 0x1c)) - Petscii.encodeScreencode("♥") shouldBe Ok(listOf(0x53)) - Petscii.encodeScreencode("π") shouldBe Ok(listOf(0x5e)) - Petscii.encodeScreencode("HELLO") shouldBe Ok(listOf(8, 5, 12, 12, 15)) + Ok(listOf(0x17u, 0x0fu, 0x12u, 0x0cu, 0x04u, 0x20u, 0x31u, 0x32u, 0x33u, 0x20u, 0x00u, 0x21u, 0x1cu)) + Petscii.encodeScreencode("♥") shouldBe Ok(listOf(0x53u)) + Petscii.encodeScreencode("π") shouldBe Ok(listOf(0x5eu)) + Petscii.encodeScreencode("HELLO") shouldBe Ok(listOf(8u, 5u, 12u, 12u, 15u)) withClue("expecting fallback") { - Petscii.encodeScreencode("hello") shouldBe Ok(listOf(8, 5, 12, 12, 15)) - Petscii.encodeScreencode("✓") shouldBe Ok(listOf(122)) + Petscii.encodeScreencode("hello") shouldBe Ok(listOf(8u, 5u, 12u, 12u, 15u)) + Petscii.encodeScreencode("✓") shouldBe Ok(listOf(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 { Petscii.decodePetscii(listOf(-1), true) } - shouldThrow { Petscii.decodePetscii(listOf(256), true) } - shouldThrow { Petscii.decodePetscii(listOf(-1), false) } - shouldThrow { Petscii.decodePetscii(listOf(256), false) } - shouldThrow { Petscii.decodeScreencode(listOf(-1), true) } - shouldThrow { Petscii.decodeScreencode(listOf(256), true) } - shouldThrow { Petscii.decodeScreencode(listOf(-1), false) } - shouldThrow { Petscii.decodeScreencode(listOf(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' } }) diff --git a/compiler/test/ZeropageTests.kt b/compiler/test/ZeropageTests.kt index 7c5bb1bfb..e95f113a0 100644 --- a/compiler/test/ZeropageTests.kt +++ b/compiler/test/ZeropageTests.kt @@ -23,11 +23,11 @@ class TestAbstractZeropage: FunSpec({ override val machine: IMachineDefinition get() = throw NotImplementedError("dummy") - override fun encodeString(str: String, altEncoding: Boolean): List { + override fun encodeString(str: String, altEncoding: Boolean): List { throw NotImplementedError("dummy") } - override fun decodeString(bytes: List, altEncoding: Boolean): String { + override fun decodeString(bytes: List, altEncoding: Boolean): String { throw NotImplementedError("dummy") } diff --git a/compiler/test/helpers/Dummies.kt b/compiler/test/helpers/Dummies.kt index 9a8128584..d6c40dc51 100644 --- a/compiler/test/helpers/Dummies.kt +++ b/compiler/test/helpers/Dummies.kt @@ -26,11 +26,11 @@ internal val DummyMemsizer = object : IMemSizer { } internal val DummyStringEncoder = object : IStringEncoding { - override fun encodeString(str: String, altEncoding: Boolean): List { + override fun encodeString(str: String, altEncoding: Boolean): List { return emptyList() } - override fun decodeString(bytes: List, altEncoding: Boolean): String { + override fun decodeString(bytes: List, altEncoding: Boolean): String { return "" } } diff --git a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt index 11f50a5fb..5d8024995 100644 --- a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt +++ b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt @@ -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) diff --git a/compilerAst/src/prog8/compilerinterface/IStringEncoding.kt b/compilerAst/src/prog8/compilerinterface/IStringEncoding.kt index 1d91a63f0..bb526cfbb 100644 --- a/compilerAst/src/prog8/compilerinterface/IStringEncoding.kt +++ b/compilerAst/src/prog8/compilerinterface/IStringEncoding.kt @@ -1,6 +1,6 @@ package prog8.compilerinterface interface IStringEncoding { - fun encodeString(str: String, altEncoding: Boolean): List - fun decodeString(bytes: List, altEncoding: Boolean): String + fun encodeString(str: String, altEncoding: Boolean): List + fun decodeString(bytes: List, altEncoding: Boolean): String } diff --git a/compilerAst/test/helpers/Dummies.kt b/compilerAst/test/helpers/Dummies.kt index fa59a2d51..92ab96752 100644 --- a/compilerAst/test/helpers/Dummies.kt +++ b/compilerAst/test/helpers/Dummies.kt @@ -26,19 +26,19 @@ internal val DummyMemsizer = object : IMemSizer { } internal val DummyStringEncoder = object : IStringEncoding { - override fun encodeString(str: String, altEncoding: Boolean): List { + override fun encodeString(str: String, altEncoding: Boolean): List { return emptyList() } - override fun decodeString(bytes: List, altEncoding: Boolean): String { + override fun decodeString(bytes: List, altEncoding: Boolean): String { return "" } } internal val AsciiStringEncoder = object : IStringEncoding { - override fun encodeString(str: String, altEncoding: Boolean): List = str.map { it.code.toShort() } + override fun encodeString(str: String, altEncoding: Boolean): List = str.map { it.code.toUByte() } - override fun decodeString(bytes: List, altEncoding: Boolean): String { + override fun decodeString(bytes: List, altEncoding: Boolean): String { return bytes.joinToString() } } diff --git a/compilerInterfaces/src/prog8/compilerinterface/ICompilationTarget.kt b/compilerInterfaces/src/prog8/compilerinterface/ICompilationTarget.kt index f6a782c3b..a0590cfdf 100644 --- a/compilerInterfaces/src/prog8/compilerinterface/ICompilationTarget.kt +++ b/compilerInterfaces/src/prog8/compilerinterface/ICompilationTarget.kt @@ -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 - override fun decodeString(bytes: List, altEncoding: Boolean): String + override fun encodeString(str: String, altEncoding: Boolean): List + override fun decodeString(bytes: List, altEncoding: Boolean): String } diff --git a/examples/test.p8 b/examples/test.p8 index ad777465f..ee39eeeca 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -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 { + } } }