mirror of
https://github.com/irmen/prog8.git
synced 2025-11-23 14:17:51 +00:00
support word size indexing on typed pointers
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,6 +240,7 @@ _after:
|
||||
override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
|
||||
// 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
|
||||
)
|
||||
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
|
||||
)
|
||||
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))
|
||||
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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -332,11 +332,11 @@ main {
|
||||
st.size shouldBe 27
|
||||
|
||||
val a_zz = (st[20] as Assignment).value
|
||||
a_zz shouldBe instanceOf<ArrayIndexedExpression>()
|
||||
a_zz shouldBe instanceOf<FunctionCallExpression>()
|
||||
val a_fl = (st[21] as Assignment).value
|
||||
a_fl shouldBe instanceOf<ArrayIndexedExpression>()
|
||||
a_fl shouldBe instanceOf<FunctionCallExpression>()
|
||||
val a_bb = (st[22] as Assignment).value
|
||||
a_bb shouldBe instanceOf<ArrayIndexedExpression>()
|
||||
a_bb shouldBe instanceOf<DirectMemoryRead>()
|
||||
val a_r0 = (st[23] as Assignment).value
|
||||
a_r0 shouldBe instanceOf<DirectMemoryRead>()
|
||||
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 {
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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)
|
||||
|
||||
246
examples/test.p8
246
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]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user