diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index 734cf4230..bc21a37d8 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -719,6 +719,8 @@ class AsmGen6502Internal ( val reg = register.toString().lowercase() val indexnum = expr.index.asConstInteger() if (indexnum != null) { + if(indexnum > 255) + throw AssemblyError("array index $indexnum is larger than a byte ${expr.position}") val indexValue = if(expr.splitWords) indexnum else @@ -727,6 +729,9 @@ class AsmGen6502Internal ( return } + if(!expr.index.type.isByte) + throw AssemblyError("array index $indexnum is larger than a byte ${expr.position}") + if(expr.splitWords) { assignExpressionToRegister(expr.index, RegisterOrPair.fromCpuRegister(register)) return @@ -806,15 +811,15 @@ class AsmGen6502Internal ( when(target.kind) { TargetStorageKind.VARIABLE -> { if (isTargetCpu(CpuType.CPU6502)) - out("lda #0 | sta ${target.asmVarname}") + out(" lda #0 | sta ${target.asmVarname}") else - out("stz ${target.asmVarname}") + out(" stz ${target.asmVarname}") } TargetStorageKind.MEMORY -> { val address = target.memory!!.address.asConstInteger() if(address!=null) { if (isTargetCpu(CpuType.CPU6502)) - out("lda #0 | sta ${address.toHex()}") + out(" lda #0 | sta ${address.toHex()}") else out(" stz ${address.toHex()}") return diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index 75c3051c0..7fc54fe76 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -3606,7 +3606,9 @@ $endLabel""") if(indexVar!=null) { asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta ${target.asmVarname},y") } else { - require(target.array.index.type.isByteOrBool) + require(target.array.index.type.isByte) { + "wot" + } asmgen.saveRegisterStack(register, false) asmgen.assignExpressionToRegister(target.array.index, RegisterOrPair.Y) asmgen.out(" pla | sta ${target.asmVarname},y") diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 2fce476f8..ca2268806 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -1594,8 +1594,15 @@ internal class AstChecker(private val program: Program, } else { if (leftDt.isBool || rightDt.isBool) { - if(expr.operator!="==" && expr.operator!="!=") - errors.err("operator requires numeric operands", expr.right.position) + if(expr.operator!="==" && expr.operator!="!=") { + val msg = when(expr.operator) { + "^" -> "operator requires numeric operands, did you mean logical 'xor'?" + "&" -> "operator requires numeric operands, did you mean logical 'and'?" + "|" -> "operator requires numeric operands, did you mean logical 'or'?" + else -> "operator requires numeric operands" + } + errors.err(msg, expr.right.position) + } } } } diff --git a/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt b/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt index 25922aab7..83162340d 100644 --- a/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt +++ b/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt @@ -240,6 +240,7 @@ _after: override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable { // replace pointervar[word] by @(pointervar+word) to avoid the // "array indexing is limited to byte size 0..255" error for pointervariables. + // (uses pokew or pokef if the ointer is a word or float pointer). if(arrayIndexedExpression.pointerderef!=null) { return noModifications @@ -247,7 +248,7 @@ _after: val indexExpr = arrayIndexedExpression.indexer.indexExpr val arrayVar = arrayIndexedExpression.plainarrayvar!!.targetVarDecl() - if(arrayVar!=null && (arrayVar.datatype.isUnsignedWord || (arrayVar.datatype.isPointer && arrayVar.datatype.sub==BaseDataType.UBYTE))) { + if(arrayVar!=null && (arrayVar.datatype.isUnsignedWord || arrayVar.datatype.isPointer)) { val wordIndex = TypecastExpression(indexExpr, DataType.UWORD, true, indexExpr.position) val address = BinaryExpression( arrayIndexedExpression.plainarrayvar!!.copy(), @@ -255,22 +256,58 @@ _after: wordIndex, arrayIndexedExpression.position ) - return if (parent is AssignTarget) { - // assignment to array - val memwrite = DirectMemoryWrite(address, arrayIndexedExpression.position) - val newtarget = AssignTarget( - null, - null, - memwrite, - null, - false, - position = arrayIndexedExpression.position - ) - listOf(IAstModification.ReplaceNode(parent, newtarget, parent.parent)) - } else { - // read from array - val memread = DirectMemoryRead(address, arrayIndexedExpression.position) - listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent)) + if(arrayVar.datatype.isUnsignedWord || arrayVar.datatype.sub?.isByte==true) { + return if (parent is AssignTarget) { + // assignment to array + val memwrite = DirectMemoryWrite(address, arrayIndexedExpression.position) + val newtarget = AssignTarget(null, null, memwrite, null, false, position = arrayIndexedExpression.position) + listOf(IAstModification.ReplaceNode(parent, newtarget, parent.parent)) + } else { + // read from array + val memread = DirectMemoryRead(address, arrayIndexedExpression.position) + val replacement = if(arrayVar.datatype.sub?.isSigned==true) + TypecastExpression(memread, DataType.BYTE, true, memread.position) + else + memread + listOf(IAstModification.ReplaceNode(arrayIndexedExpression, replacement, parent)) + } + } else if(arrayVar.datatype.sub?.isWord==true) { + // use peekw/pokew + if(parent is AssignTarget) { + val assignment = parent.parent as Assignment + val args = mutableListOf(address, assignment.value) + val poke = FunctionCallStatement(IdentifierReference(listOf("pokew"), arrayIndexedExpression.position), args, false, arrayIndexedExpression.position) + return listOf(IAstModification.ReplaceNode(assignment, poke, assignment.parent)) + } else { + val peek = FunctionCallExpression(IdentifierReference(listOf("peekw"), arrayIndexedExpression.position), mutableListOf(address), arrayIndexedExpression.position) + val replacement = if(arrayVar.datatype.sub?.isSigned==true) + TypecastExpression(peek, DataType.WORD, true, peek.position) + else + peek + return listOf(IAstModification.ReplaceNode(arrayIndexedExpression, replacement, parent)) + } + } else if(arrayVar.datatype.sub==BaseDataType.BOOL) { + // use peekbool/pokebool + if(parent is AssignTarget) { + val assignment = parent.parent as Assignment + val args = mutableListOf(address, assignment.value) + val poke = FunctionCallStatement(IdentifierReference(listOf("pokebool"), arrayIndexedExpression.position), args, false, arrayIndexedExpression.position) + return listOf(IAstModification.ReplaceNode(assignment, poke, assignment.parent)) + } else { + val peek = FunctionCallExpression(IdentifierReference(listOf("peekbool"), arrayIndexedExpression.position), mutableListOf(address), arrayIndexedExpression.position) + return listOf(IAstModification.ReplaceNode(arrayIndexedExpression, peek, parent)) + } + } else if(arrayVar.datatype.sub==BaseDataType.FLOAT) { + // use peekf/pokef + if(parent is AssignTarget) { + val assignment = parent.parent as Assignment + val args = mutableListOf(address, assignment.value) + val poke = FunctionCallStatement(IdentifierReference(listOf("pokef"), arrayIndexedExpression.position), args, false, arrayIndexedExpression.position) + return listOf(IAstModification.ReplaceNode(assignment, poke, assignment.parent)) + } else { + val peek = FunctionCallExpression(IdentifierReference(listOf("peekf"), arrayIndexedExpression.position), mutableListOf(address), arrayIndexedExpression.position) + return listOf(IAstModification.ReplaceNode(arrayIndexedExpression, peek, parent)) + } } } else if(arrayVar!=null && (arrayVar.type==VarDeclType.MEMORY || arrayVar.datatype.isString || arrayVar.datatype.isPointer || arrayVar.datatype.isArray)) { return noModifications diff --git a/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt b/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt index 44d7e965d..3b483a160 100644 --- a/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt +++ b/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt @@ -840,7 +840,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro // don't multiply simply shift offset = PtBinaryExpression("<<", DataType.UWORD, expr.position) offset.add(transformExpression(expr.right)) - offset.add(PtNumber(BaseDataType.UWORD, log2(structSize.toDouble()), expr.position)) + offset.add(PtNumber(BaseDataType.UBYTE, log2(structSize.toDouble()), expr.position)) } else { offset = PtBinaryExpression("*", DataType.UWORD, expr.position) diff --git a/compiler/test/TestPointers.kt b/compiler/test/TestPointers.kt index a998d6a70..0e7af3909 100644 --- a/compiler/test/TestPointers.kt +++ b/compiler/test/TestPointers.kt @@ -332,11 +332,11 @@ main { st.size shouldBe 27 val a_zz = (st[20] as Assignment).value - a_zz shouldBe instanceOf() + a_zz shouldBe instanceOf() val a_fl = (st[21] as Assignment).value - a_fl shouldBe instanceOf() + a_fl shouldBe instanceOf() val a_bb = (st[22] as Assignment).value - a_bb shouldBe instanceOf() + a_bb shouldBe instanceOf() val a_r0 = (st[23] as Assignment).value a_r0 shouldBe instanceOf() val a_r1 = (st[24] as Assignment).value @@ -885,28 +885,6 @@ main { compileText(Cx16Target(), false, src, outputDir) shouldNotBe null } - test("uword as pointer versus pointer to uword difference") { - val src=""" -main { - sub start() { - uword @shared ptr1 - ^^uword @shared ptr2 - - ptr1[2] = 1 - ptr2[2] = 1 - } -}""" - - compileText(C64Target(), false, src, outputDir) shouldNotBe null - val result = compileText(VMTarget(), false, src, outputDir)!! - val st = result.codegenAst!!.entrypoint()!!.children - st.size shouldBe 8 - val a1 = st[5] as PtAssignment - val a2 = st[6] as PtAssignment - a1.target.memory shouldNotBe null - a2.target.array shouldNotBe null - } - test("array indexing on non pointer fields give correct error messages") { val src=""" main { @@ -1021,15 +999,15 @@ main { val dr7 = (st[17] as Assignment).target.pointerDereference!! val dr8 = (st[18] as Assignment).target.pointerDereference!! - val dr9 = (st[19] as Assignment).value as PtrDereference + val dr9 = (st[19] as Assignment).value as FunctionCallExpression val dr10 = (st[20] as Assignment).value as PtrDereference val dr11 = (st[21] as Assignment).target.pointerDereference!! - val dr12 = (st[22] as Assignment).target.pointerDereference!! + (st[22] as FunctionCallStatement).target.nameInSource shouldBe listOf("pokew") val dr13 = (st[23] as Assignment).value as PtrDereference - val dr14 = (st[24] as Assignment).value as PtrDereference + ((st[24] as Assignment).value as FunctionCallExpression).target.nameInSource shouldBe listOf("peekf") val dr15 = (st[25] as Assignment).target.pointerDereference!! - val dr16 = (st[26] as Assignment).target.pointerDereference!! + (st[26] as FunctionCallStatement).target.nameInSource shouldBe listOf("pokef") dr0.chain shouldBe listOf("l1", "s") dr0.derefLast shouldBe true @@ -1051,23 +1029,16 @@ main { dr8.chain shouldBe listOf("l1", "s") dr8.derefLast shouldBe true - dr9.chain shouldBe listOf("wptr") - dr9.derefLast shouldBe true + dr9.target.nameInSource shouldBe listOf("peekw") dr10.chain shouldBe listOf("wptr") dr10.derefLast shouldBe true dr11.chain shouldBe listOf("wptr") dr11.derefLast shouldBe true - dr12.chain shouldBe listOf("wptr") - dr12.derefLast shouldBe true dr13.chain shouldBe listOf("fptr") dr13.derefLast shouldBe true - dr14.chain shouldBe listOf("fptr") - dr14.derefLast shouldBe true dr15.chain shouldBe listOf("fptr") dr15.derefLast shouldBe true - dr16.chain shouldBe listOf("fptr") - dr16.derefLast shouldBe true } test("global and local pointer vars") { @@ -1721,6 +1692,84 @@ main { compileText(Cx16Target(), false, src, outputDir) shouldNotBe null } + test("array indexing on a pointer with a word size index works") { + val src=""" +%import floats + +main { + sub start() { + ^^ubyte @shared ptr1 = $4000 + ^^uword @shared ptr2 = $4000 + ^^float @shared ptr3 = $4000 + ^^bool @shared ptr4 = $4000 + uword @shared untyped = $4000 + float @shared fl + bool @shared bb, bb2 + + untyped[$1000] = 0 + ptr1[$1000] = 0 + ptr2[$1000] = 0 + ptr3[$1000] = 0 + ptr4[$1000] = false + untyped[$1000] = 99 + ptr1[$1000] = 99 + ptr2[$1000] = 99 + ptr3[$1000] = 99 + ptr4[$1000] = true + untyped[$1000] = cx16.r0L + ptr1[$1000] = cx16.r0L + ptr2[$1000] = cx16.r0L + ptr3[$1000] = fl + ptr4[$1000] = bb + untyped[$1000] = cx16.r0L+1 + ptr1[$1000] = cx16.r0L+1 + ptr2[$1000] = cx16.r0L+1 + ptr3[$1000] = fl+1.1 + ptr4[$1000] = bb xor bb2 + + untyped[$1000 + cx16.r0] = 0 + ptr1[$1000 + cx16.r0] = 0 + ptr2[$1000 + cx16.r0] = 0 + ptr3[$1000 + cx16.r0] = 0 + ptr4[$1000 + cx16.r0] = false + untyped[$1000 + cx16.r0] = 99 + ptr1[$1000 + cx16.r0] = 99 + ptr2[$1000 + cx16.r0] = 99 + ptr3[$1000 + cx16.r0] = 99 + ptr4[$1000 + cx16.r0] = true + untyped[$1000 + cx16.r0] = cx16.r0L + ptr1[$1000 + cx16.r0] = cx16.r0L + ptr2[$1000 + cx16.r0] = cx16.r0L + ptr3[$1000 + cx16.r0] = fl + ptr4[$1000 + cx16.r0] = bb + untyped[$1000 + cx16.r0] = cx16.r0L+1 + ptr1[$1000 + cx16.r0] = cx16.r0L+1 + ptr2[$1000 + cx16.r0] = cx16.r0L+1 + ptr3[$1000 + cx16.r0] = fl+1.1 + ptr4[$1000 + cx16.r0] = bb xor bb2 + + cx16.r0L = untyped[$1000] + cx16.r1L = ptr1[$1000] + cx16.r2 = ptr2[$1000] + fl = ptr3[$1000] + bb = ptr4[$1000] + cx16.r0L = untyped[cx16.r0] + cx16.r1L = ptr1[cx16.r0] + cx16.r2 = ptr2[cx16.r0] + fl = ptr3[cx16.r0] + bb = ptr4[cx16.r0] + cx16.r0L = untyped[cx16.r0+1] + cx16.r1L = ptr1[cx16.r0+1] + cx16.r2 = ptr2[cx16.r0+1] + fl = ptr3[cx16.r0+1] + bb = ptr4[cx16.r0+1] + } +}""" + + compileText(VMTarget(), false, src, outputDir) shouldNotBe null + compileText(C64Target(), false, src, outputDir) shouldNotBe null + } + test("correct type of address of split and nosplit arrays") { val src=""" main { diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 14f0a30dc..f4d4c9c7d 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,7 +2,6 @@ TODO ==== c64 (and cx16 as well) fileselector has 2 issues when using ^^ubyte (code size and compiler error about return statement) -cx16 life code size regression when using ^^ubyte pointer arithmetic precedence issue?: @@ -33,3 +32,5 @@ STRUCTS and TYPED POINTERS (6502 codegen specific) - optimize the float copying in assignIndexedPointer() (also word?) - implement some more struct instance assignments (via memcopy) in CodeDesugarer (see the TODO) (add to documentation as well, paragraph 'Structs') - try to optimize pointer arithmetic used in peek/poke a bit more so the routines in sorting module can use typed pointers without increasing code size +- should @(wordpointer) be equivalent to wordpointer^^ (that would require a LOT of code rewrite that now knows that @() is strictly byte based) ? + or do an implicit cast @(wpointer as ubyte^^) ? And/or add a warning about that? diff --git a/examples/cx16/life.p8 b/examples/cx16/life.p8 index 79bf1424b..ffa76572a 100644 --- a/examples/cx16/life.p8 +++ b/examples/cx16/life.p8 @@ -1,4 +1,7 @@ -; conway's game of life. +; Conway's game of life. +; the world is represented by a matrix of bytes (the cells) that can be 1 (alive) or 0 (dead) +; numeric byte is used because we need to count the number of neighbors and that would require casts if we used booleans. +; (but you totally could use booleans) %import math %import textio @@ -7,9 +10,9 @@ main { const ubyte WIDTH = 80 const ubyte HEIGHT = 60-4 const uword STRIDE = $0002+WIDTH - uword world1 = memory("world1", (WIDTH+2)*(HEIGHT+2), 0) - uword world2 = memory("world2", (WIDTH+2)*(HEIGHT+2), 0) - uword @requirezp active_world = world1 + ^^ubyte world1 = memory("world1", (WIDTH+2)*(HEIGHT+2), 0) + ^^ubyte world2 = memory("world2", (WIDTH+2)*(HEIGHT+2), 0) + ^^ubyte @requirezp active_world = world1 sub start() { ; cx16.set_screen_mode(3) @@ -91,7 +94,7 @@ main { const ubyte DYOFFSET = 2 ubyte[2] cell_chars = [sc:' ', sc:'●'] - uword @requirezp new_world = world1 + ^^ubyte @requirezp new_world = world1 if active_world == world1 new_world = world2 @@ -102,8 +105,8 @@ main { ; It's more readable to use active_world[offset] etc, but offset is a word value, and this produces ; inefficient assembly code because we can't use a register indexed mode in this case. Costly inside a loop. - uword @requirezp new_world_ptr = new_world + STRIDE+1-DXOFFSET - uword @requirezp active_world_ptr = active_world + STRIDE+1-DXOFFSET + ^^ubyte @requirezp new_world_ptr = new_world + STRIDE+1-DXOFFSET + ^^ubyte @requirezp active_world_ptr = active_world + STRIDE+1-DXOFFSET ubyte x ubyte y @@ -114,7 +117,7 @@ main { for x in DXOFFSET to WIDTH+DXOFFSET-1 { ; count the living neighbors ubyte cell = @(active_world_ptr + x) - uword @requirezp ptr = active_world_ptr + x - STRIDE - 1 + ^^ubyte @requirezp ptr = active_world_ptr + x - STRIDE - 1 ubyte neighbors = @(ptr) + @(ptr+1) + @(ptr+2) + @(ptr+STRIDE) + cell + @(ptr+STRIDE+2) + @(ptr+STRIDE*2) + @(ptr+STRIDE*2+1) + @(ptr+STRIDE*2+2) diff --git a/examples/test.p8 b/examples/test.p8 index 986210753..31ed3ac01 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,228 +1,32 @@ -%option no_sysinit -%zeropage kernalsafe -%import textio -%import compression -%import math -%import sorting -%import strings -%import diskio +%import floats main { + + struct List { + ^^uword s + ubyte n + ^^List next + } + sub start() { -; test_compression() -; test_sorting1() -; test_sorting2() -; test_math() -; test_syslib() -; test_strings() -; test_conv() - test_diskio() -; test_textio() + ubyte[10] array + uword @shared wordptr + ^^bool @shared boolptr + ^^float @shared floatptr + ^^byte @shared byteptr + ^^ubyte @shared ubyteptr + ^^List @shared listptr + ^^List @shared listptr2 - repeat {} - } + bool @shared zz + float @shared fl + byte @shared bb - sub test_diskio() { - txt.print("--diskio--\n") - sys.memset(target, len(target), 0) - diskio.delete("derp.bin") - void diskio.f_open_w("derp.bin") - repeat 12 - void diskio.f_write("derpderp123", 11) - diskio.f_close_w() - - void diskio.f_open("derp.bin") - diskio.f_read(target, 60) - txt.print(target) - txt.nl() - } - - ubyte[100] target - - sub test_conv() { - txt.print("--conv--\n") - txt.print_b(-111) - txt.spc() - txt.print_ub(222) - txt.spc() - txt.print_uw(22222) - txt.spc() - txt.print_w(-22222) - txt.nl() - txt.print_ubbin(222, true) - txt.spc() - txt.print_ubhex(222, true) - txt.spc() - txt.print_uwbin(2222, true) - txt.spc() - txt.print_uwhex(2222, true) - txt.nl() - txt.print_ub0(1) - txt.spc() - txt.print_uw0(123) - txt.nl() - } - - sub test_strings() { - txt.print("--strings--\n") - ubyte idx - bool found - idx, found = strings.rfind(source, '1') - txt.print_ub(idx) - txt.nl() - } - - sub test_textio() { - txt.print("--textio--\n") - txt.print("enter some input: ") - void txt.input_chars(&target) - txt.print(target) - txt.nl() - } - - sub test_syslib() { - txt.print("--syslib--\n") - sys.internal_stringcopy(source, target) - txt.print(target) - txt.nl() - sys.memset(target, sizeof(target), 0) - txt.print(target) - txt.nl() - sys.memcopy(source, target, len(source)) - txt.print(target) - txt.nl() - sys.memsetw(&target as ^^uword, 20, $5051) - txt.print(target) - txt.nl() - txt.print_b(sys.memcmp(source, target, len(source))) - txt.nl() - } - - sub test_sorting1() { - txt.print("--sorting (shell)--\n") - ubyte[] bytes1 = [77,33,44,99,11,55] - ubyte[] bytes2 = [77,33,44,99,11,55] - uword[] @nosplit values1 = [1,2,3,4,5,6] - uword[] @nosplit words1 = [777,333,444,999,111,555] - uword[] @nosplit words2 = [777,333,444,999,111,555] - uword[] @nosplit values2 = [1,2,3,4,5,6] - sorting.shellsort_ub(&bytes1, len(bytes1)) - sorting.shellsort_by_ub(&bytes2, &values1, len(bytes2)) - sorting.shellsort_uw(&words1, len(words1)) - sorting.shellsort_by_uw(&words2, &values2, len(words2)) - - for cx16.r0L in bytes1 { - txt.print_ub(cx16.r0L) - txt.spc() - } - txt.nl() - for cx16.r0L in bytes2 { - txt.print_ub(cx16.r0L) - txt.spc() - } - txt.nl() - for cx16.r0 in values1 { - txt.print_uw(cx16.r0) - txt.spc() - } - txt.nl() - for cx16.r0 in words1 { - txt.print_uw(cx16.r0) - txt.spc() - } - txt.nl() - for cx16.r0 in words2 { - txt.print_uw(cx16.r0) - txt.spc() - } - txt.nl() - for cx16.r0 in values2 { - txt.print_uw(cx16.r0) - txt.spc() - } - txt.nl() - - } - - sub test_sorting2() { - txt.print("--sorting (gnome)--\n") - ubyte[] bytes1 = [77,33,44,99,11,55] - ubyte[] bytes2 = [77,33,44,99,11,55] - uword[] @nosplit values1 = [1,2,3,4,5,6] - uword[] @nosplit words1 = [777,333,444,999,111,555] - uword[] @nosplit words2 = [777,333,444,999,111,555] - uword[] @nosplit values2 = [1,2,3,4,5,6] - sorting.gnomesort_ub(&bytes1, len(bytes1)) - sorting.gnomesort_by_ub(&bytes2, &values1, len(bytes2)) - sorting.gnomesort_uw(&words1, len(words1)) - sorting.gnomesort_by_uw(&words2, &values2, len(words2)) - - for cx16.r0L in bytes1 { - txt.print_ub(cx16.r0L) - txt.spc() - } - txt.nl() - for cx16.r0L in bytes2 { - txt.print_ub(cx16.r0L) - txt.spc() - } - txt.nl() - for cx16.r0 in values1 { - txt.print_uw(cx16.r0) - txt.spc() - } - txt.nl() - for cx16.r0 in words1 { - txt.print_uw(cx16.r0) - txt.spc() - } - txt.nl() - for cx16.r0 in words2 { - txt.print_uw(cx16.r0) - txt.spc() - } - txt.nl() - for cx16.r0 in values2 { - txt.print_uw(cx16.r0) - txt.spc() - } - txt.nl() - - } - - sub test_math() { - txt.print("--math--\n") - txt.print("expected 15567: ") - txt.print_uw(math.crc16(source, len(source))) - txt.print("\nexpected 8747,54089: ") - math.crc32(source, len(source)) - txt.print_uw(cx16.r14) - txt.chrout(',') - txt.print_uw(cx16.r15) - txt.nl() - } - - str source = petscii:"Lorem ipsuuuuuuuuuuuum dollllllllllllllloooooooor sit ametttttttttttttttt, cccccccccccccccconsecteeeeetuuuuuur aaaaaaaaa111111222222333333444444" - - sub test_compression() { - txt.print("--compression--\n") - - ubyte[256] compressed - ubyte[256] decompressed - - txt.print_uw(len(source)) - txt.nl() - - uword size = compression.encode_rle(source, len(source), compressed, true) - txt.print_uw(size) - txt.nl() - - size = compression.decode_rle(compressed, decompressed, sizeof(decompressed)) - txt.print_uw(size) - txt.nl() - txt.print(source) - txt.nl() - txt.print(decompressed) - txt.nl() + zz = boolptr[999] + fl = floatptr[999] + bb = byteptr[999] + cx16.r0L = ubyteptr[999] + cx16.r1L = wordptr[999] + cx16.r2L = array[9] } }