mirror of
https://github.com/irmen/prog8.git
synced 2024-12-23 09:32:43 +00:00
fix sort and reverse on strings on 6502 codegen
This commit is contained in:
parent
dd1592b03b
commit
7c1d5cadd7
@ -1,5 +1,6 @@
|
||||
package prog8.codegen.cpu6502
|
||||
|
||||
import prog8.code.StStaticVariable
|
||||
import prog8.code.ast.*
|
||||
import prog8.code.core.*
|
||||
import prog8.codegen.cpu6502.assignment.*
|
||||
@ -337,6 +338,16 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
lda #$numElements
|
||||
jsr prog8_lib.func_reverse_w""")
|
||||
}
|
||||
DataType.STR -> {
|
||||
val stringLength = (symbol as StStaticVariable).length!!-1
|
||||
asmgen.out("""
|
||||
lda #<$varName
|
||||
ldy #>$varName
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda #$stringLength
|
||||
jsr prog8_lib.func_reverse_b""")
|
||||
}
|
||||
DataType.ARRAY_F -> {
|
||||
asmgen.out("""
|
||||
lda #<$varName
|
||||
@ -381,6 +392,16 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
lda #$numElements""")
|
||||
asmgen.out(if (decl.type == DataType.ARRAY_UW) " jsr prog8_lib.func_sort_uw" else " jsr prog8_lib.func_sort_w")
|
||||
}
|
||||
DataType.STR -> {
|
||||
val stringLength = (symbol as StStaticVariable).length!!-1
|
||||
asmgen.out("""
|
||||
lda #<$varName
|
||||
ldy #>$varName
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda #$stringLength
|
||||
jsr prog8_lib.func_sort_ub""")
|
||||
}
|
||||
DataType.ARRAY_F -> throw AssemblyError("sorting of floating point array is not supported")
|
||||
else -> throw AssemblyError("weird type")
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.PUSH, IRDataType.WORD, reg1 = tr.resultReg)
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = tr.resultReg, immediate = array.length)
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = tr.resultReg, immediate = if(array.dt==DataType.STR) array.length!!-1 else array.length)
|
||||
it += IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1 = tr.resultReg)
|
||||
it += IRInstruction(Opcode.SYSCALL, immediate = syscall.number)
|
||||
}
|
||||
@ -298,7 +298,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.PUSH, IRDataType.WORD, reg1 = tr.resultReg)
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = tr.resultReg, immediate = array.length)
|
||||
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = tr.resultReg, immediate = if(array.dt==DataType.STR) array.length!!-1 else array.length)
|
||||
it += IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1 = tr.resultReg)
|
||||
it += IRInstruction(Opcode.SYSCALL, immediate = syscall.number)
|
||||
}
|
||||
|
@ -127,6 +127,8 @@ sub input_chars (uword buffer) -> ubyte {
|
||||
%ir {{
|
||||
loadm.w r65535,txt.input_chars.buffer
|
||||
push.w r65535
|
||||
load.b r65535,80
|
||||
push.b r65535
|
||||
syscall 6
|
||||
pop.b r0
|
||||
returnreg.b r0
|
||||
|
@ -3,8 +3,6 @@ TODO
|
||||
|
||||
For next minor release
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
test vm array reverse, sort, string containment, string input, float array containment (how translated? there is no syscall)
|
||||
|
||||
...
|
||||
|
||||
|
||||
@ -35,6 +33,9 @@ Future Things and Ideas
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Compiler:
|
||||
|
||||
- ir: investigate passing parameters to function calls using fixed set of regs r60000,r60001, etc.
|
||||
these have to be offset somehow by the subroutine number (?) somehow to have a unique list of them per subroutine.
|
||||
also only if we can optimize the subroutine to replace the parameter variables to those registers.
|
||||
- ir: can we determine for the loop variable in forloops if it could be kept in a (virtual) register instead of a real variable? Need to be able to check if the variable is used by another statement beside just the for loop.
|
||||
- ir: mechanism to determine for chunks which registers are getting input values from "outside"
|
||||
- ir: mechanism to determine for chunks which registers are passing values out? (i.e. are used again in another chunk)
|
||||
|
@ -1,7 +1,6 @@
|
||||
%import textio
|
||||
%import conv
|
||||
%import math
|
||||
%import test_stack
|
||||
%zeropage basicsafe
|
||||
|
||||
; The classic number guessing game.
|
||||
@ -61,8 +60,6 @@ main {
|
||||
txt.print("Thanks for playing, ")
|
||||
txt.print(name)
|
||||
txt.print(".\n")
|
||||
|
||||
; test_stack.test()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,18 @@
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
math.rndseed(11111,22222)
|
||||
str name = "irmen"
|
||||
reverse(name)
|
||||
txt.print(name)
|
||||
txt.nl()
|
||||
sort(name)
|
||||
txt.print(name)
|
||||
txt.nl()
|
||||
txt.print_ub('@' in name)
|
||||
txt.nl()
|
||||
txt.print_ub('i' in name)
|
||||
txt.nl()
|
||||
sys.wait(60)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,21 +5,21 @@ package prog8.intermediate
|
||||
// Note that in the VM these are translated into whatever the corresponding Syscall number in the VM is.
|
||||
|
||||
enum class IMSyscall(val number: Int) {
|
||||
SORT_UBYTE(10000),
|
||||
SORT_BYTE(10001),
|
||||
SORT_UWORD(10002),
|
||||
SORT_WORD(10003),
|
||||
ANY_BYTE(10004),
|
||||
ANY_WORD(10005),
|
||||
ANY_FLOAT(10006),
|
||||
ALL_BYTE(10007),
|
||||
ALL_WORD(10008),
|
||||
ALL_FLOAT(10009),
|
||||
REVERSE_BYTES(10010),
|
||||
REVERSE_WORDS(10011),
|
||||
REVERSE_FLOATS(10012),
|
||||
COMPARE_STRINGS(10013),
|
||||
STRING_CONTAINS(10014),
|
||||
BYTEARRAY_CONTAINS(10015),
|
||||
WORDARRAY_CONTAINS(10016)
|
||||
SORT_UBYTE(0x1000),
|
||||
SORT_BYTE(0x1001),
|
||||
SORT_UWORD(0x1002),
|
||||
SORT_WORD(0x1003),
|
||||
ANY_BYTE(0x1004),
|
||||
ANY_WORD(0x1005),
|
||||
ANY_FLOAT(0x1006),
|
||||
ALL_BYTE(0x1007),
|
||||
ALL_WORD(0x1008),
|
||||
ALL_FLOAT(0x1009),
|
||||
REVERSE_BYTES(0x100a),
|
||||
REVERSE_WORDS(0x100b),
|
||||
REVERSE_FLOATS(0x100c),
|
||||
COMPARE_STRINGS(0x100d),
|
||||
STRING_CONTAINS(0x100e),
|
||||
BYTEARRAY_CONTAINS(0x100f),
|
||||
WORDARRAY_CONTAINS(0x1010)
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ object SysCalls {
|
||||
if(maxlen>0)
|
||||
input = input.substring(0, min(input.length, maxlen))
|
||||
vm.memory.setString(vm.valueStack.popw().toInt(), input, true)
|
||||
vm.valueStack.pushw(input.length.toUShort())
|
||||
vm.valueStack.push(input.length.toUByte())
|
||||
}
|
||||
Syscall.SLEEP -> {
|
||||
val duration = vm.valueStack.popw().toLong()
|
||||
|
@ -2299,7 +2299,7 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
val y = valueStack.popw()
|
||||
val x = valueStack.popw()
|
||||
val color = Color(window!!.getpixel(x.toInt(), y.toInt()))
|
||||
registers.setUB(0, color.green.toUByte())
|
||||
valueStack.push(color.green.toUByte()) // gets called from a syscall, return value via stack.
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user