mirror of
https://github.com/irmen/prog8.git
synced 2024-06-30 18:29:48 +00:00
added support for any() on split word arrays
This commit is contained in:
parent
828d83dbef
commit
80095f4962
|
@ -713,13 +713,57 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcAnyAll(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?, scope: IPtSubroutine?) {
|
private fun funcAnyAll(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?, scope: IPtSubroutine?) {
|
||||||
outputAddressAndLenghtOfArray(fcall.args[0])
|
|
||||||
val dt = fcall.args.single().type
|
val dt = fcall.args.single().type
|
||||||
|
val array = fcall.args[0] as PtIdentifier
|
||||||
when (dt) {
|
when (dt) {
|
||||||
DataType.ARRAY_B, DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_${fcall.name}_b_into_A | ldy #0")
|
DataType.ARRAY_B, DataType.ARRAY_UB, DataType.STR -> {
|
||||||
DataType.ARRAY_UW, DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_${fcall.name}_w_into_A | ldy #0")
|
outputAddressAndLengthOfArray(array)
|
||||||
DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${fcall.name}_f_into_A | ldy #0")
|
asmgen.out(" jsr prog8_lib.func_${fcall.name}_b_into_A")
|
||||||
in SplitWordArrayTypes -> TODO("split word any/all")
|
}
|
||||||
|
DataType.ARRAY_UW, DataType.ARRAY_W -> {
|
||||||
|
outputAddressAndLengthOfArray(array)
|
||||||
|
asmgen.out(" jsr prog8_lib.func_${fcall.name}_w_into_A")
|
||||||
|
}
|
||||||
|
DataType.ARRAY_F -> {
|
||||||
|
outputAddressAndLengthOfArray(array)
|
||||||
|
asmgen.out(" jsr floats.func_${fcall.name}_f_into_A")
|
||||||
|
}
|
||||||
|
in SplitWordArrayTypes -> {
|
||||||
|
val numElements = (asmgen.symbolTable.lookup(array.name) as StStaticVariable).length
|
||||||
|
when(fcall.name) {
|
||||||
|
"any" -> {
|
||||||
|
// any(lsb-array) or any(msb-array)
|
||||||
|
val arrayName = asmgen.asmVariableName(array)
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<${arrayName}_lsb
|
||||||
|
ldy #>${arrayName}_lsb
|
||||||
|
sta P8ZP_SCRATCH_W1
|
||||||
|
sty P8ZP_SCRATCH_W1+1
|
||||||
|
lda #$numElements
|
||||||
|
""")
|
||||||
|
asmgen.out(" jsr prog8_lib.func_${fcall.name}_b_into_A")
|
||||||
|
asmgen.out(" bne +") // shortcircuit
|
||||||
|
asmgen.out("""
|
||||||
|
pha
|
||||||
|
lda #<${arrayName}_msb
|
||||||
|
ldy #>${arrayName}_msb
|
||||||
|
sta P8ZP_SCRATCH_W1
|
||||||
|
sty P8ZP_SCRATCH_W1+1
|
||||||
|
lda #$numElements
|
||||||
|
""")
|
||||||
|
asmgen.out(" jsr prog8_lib.func_${fcall.name}_b_into_A")
|
||||||
|
asmgen.out("""
|
||||||
|
sta P8ZP_SCRATCH_REG
|
||||||
|
pla
|
||||||
|
ora P8ZP_SCRATCH_REG
|
||||||
|
+""")
|
||||||
|
}
|
||||||
|
"all" -> {
|
||||||
|
TODO("split words all")
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("weird call")
|
||||||
|
}
|
||||||
|
}
|
||||||
else -> throw AssemblyError("weird type $dt")
|
else -> throw AssemblyError("weird type $dt")
|
||||||
}
|
}
|
||||||
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, dt in SignedDatatypes, true)
|
assignAsmGen.assignRegisterByte(AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.A, false, fcall.position, scope, asmgen), CpuRegister.A, dt in SignedDatatypes, true)
|
||||||
|
@ -1226,9 +1270,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun outputAddressAndLenghtOfArray(arg: PtExpression) {
|
private fun outputAddressAndLengthOfArray(arg: PtIdentifier) {
|
||||||
// address in P8ZP_SCRATCH_W1, number of elements in A
|
// address goes in P8ZP_SCRATCH_W1, number of elements in A
|
||||||
arg as PtIdentifier
|
|
||||||
val symbol = asmgen.symbolTable.lookup(arg.name)
|
val symbol = asmgen.symbolTable.lookup(arg.name)
|
||||||
val numElements = when(symbol) {
|
val numElements = when(symbol) {
|
||||||
is StStaticVariable -> symbol.length!!
|
is StStaticVariable -> symbol.length!!
|
||||||
|
|
|
@ -148,9 +148,29 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||||
private fun funcAny(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
private fun funcAny(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||||
val arrayName = call.args[0] as PtIdentifier
|
val arrayName = call.args[0] as PtIdentifier
|
||||||
val arrayLength = codeGen.symbolTable.getLength(arrayName.name)
|
val arrayLength = codeGen.symbolTable.getLength(arrayName.name)
|
||||||
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
|
|
||||||
if(arrayName.type in SplitWordArrayTypes) {
|
if(arrayName.type in SplitWordArrayTypes) {
|
||||||
TODO("any(split words) array=$arrayName length=$arrayLength")
|
// any(lsb-array) or any(msb-array)
|
||||||
|
val lengthReg = codeGen.registers.nextFree()
|
||||||
|
addInstr(result, IRInstruction(Opcode.PREPARECALL, immediate = 2), null)
|
||||||
|
val trLsb = exprGen.translateExpression(PtIdentifier(arrayName.name+"_lsb", DataType.ARRAY_UB, call.position))
|
||||||
|
addToResult(result, trLsb, trLsb.resultReg, -1)
|
||||||
|
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = arrayLength), null)
|
||||||
|
result += codeGen.makeSyscall(IMSyscall.ANY_BYTE, listOf(IRDataType.WORD to trLsb.resultReg, IRDataType.BYTE to lengthReg), IRDataType.BYTE to trLsb.resultReg)
|
||||||
|
val shortcircuitLabel = codeGen.createLabelName()
|
||||||
|
result += IRCodeChunk(null, null).also {
|
||||||
|
it += IRInstruction(Opcode.CMPI, IRDataType.BYTE, reg1 = trLsb.resultReg, immediate = 0)
|
||||||
|
it += IRInstruction(Opcode.BSTNE, labelSymbol = shortcircuitLabel)
|
||||||
|
it += IRInstruction(Opcode.PREPARECALL, immediate = 2)
|
||||||
|
}
|
||||||
|
val trMsb = exprGen.translateExpression(PtIdentifier(arrayName.name+"_msb", DataType.ARRAY_UB, call.position))
|
||||||
|
addToResult(result, trMsb, trMsb.resultReg, -1)
|
||||||
|
addInstr(result, IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = lengthReg, immediate = arrayLength), null)
|
||||||
|
result += codeGen.makeSyscall(IMSyscall.ANY_BYTE, listOf(IRDataType.WORD to trMsb.resultReg, IRDataType.BYTE to lengthReg), IRDataType.BYTE to trMsb.resultReg)
|
||||||
|
addInstr(result, IRInstruction(Opcode.ORR, IRDataType.BYTE, reg1=trLsb.resultReg, reg2=trMsb.resultReg), null)
|
||||||
|
result += IRCodeChunk(shortcircuitLabel, null)
|
||||||
|
return ExpressionCodeResult(result, IRDataType.BYTE, trLsb.resultReg, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
val syscall =
|
val syscall =
|
||||||
|
@ -162,7 +182,6 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||||
DataType.ARRAY_F -> IMSyscall.ANY_FLOAT
|
DataType.ARRAY_F -> IMSyscall.ANY_FLOAT
|
||||||
else -> throw IllegalArgumentException("weird type")
|
else -> throw IllegalArgumentException("weird type")
|
||||||
}
|
}
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
|
||||||
addInstr(result, IRInstruction(Opcode.PREPARECALL, immediate = 2), null)
|
addInstr(result, IRInstruction(Opcode.PREPARECALL, immediate = 2), null)
|
||||||
val tr = exprGen.translateExpression(call.args[0])
|
val tr = exprGen.translateExpression(call.args[0])
|
||||||
addToResult(result, tr, tr.resultReg, -1)
|
addToResult(result, tr, tr.resultReg, -1)
|
||||||
|
@ -177,7 +196,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||||
val arrayLength = codeGen.symbolTable.getLength(arrayName.name)
|
val arrayLength = codeGen.symbolTable.getLength(arrayName.name)
|
||||||
|
|
||||||
if(arrayName.type in SplitWordArrayTypes) {
|
if(arrayName.type in SplitWordArrayTypes) {
|
||||||
TODO("all(split words) array=$arrayName length=$arrayLength")
|
// this is a bit complicated to calculate.... have to check all recombined (lsb,msb) words for $0000
|
||||||
|
TODO("all(split words $arrayName)")
|
||||||
}
|
}
|
||||||
|
|
||||||
val syscall =
|
val syscall =
|
||||||
|
|
|
@ -3,8 +3,7 @@ TODO
|
||||||
|
|
||||||
funcRor()/funcRol(): save carry flag before calculating array index otherwise it gets clobbered
|
funcRor()/funcRol(): save carry flag before calculating array index otherwise it gets clobbered
|
||||||
|
|
||||||
split words sort and reverse
|
- split words arrays reverse()
|
||||||
split words any and all
|
|
||||||
|
|
||||||
Mark had a compiler crash FatalAstException: invalid dt
|
Mark had a compiler crash FatalAstException: invalid dt
|
||||||
|
|
||||||
|
@ -50,6 +49,9 @@ Compiler:
|
||||||
- Zig-like try-based error handling where the V flag could indicate error condition? and/or BRK to jump into monitor on failure? (has to set BRK vector for that) But the V flag is also set on certain normal instructions
|
- Zig-like try-based error handling where the V flag could indicate error condition? and/or BRK to jump into monitor on failure? (has to set BRK vector for that) But the V flag is also set on certain normal instructions
|
||||||
- generate WASM to eventually run prog8 on a browser canvas? Use binaryen toolkit and/or my binaryen kotlin library?
|
- generate WASM to eventually run prog8 on a browser canvas? Use binaryen toolkit and/or my binaryen kotlin library?
|
||||||
- add Vic20 target?
|
- add Vic20 target?
|
||||||
|
- split words arrays all()
|
||||||
|
- split words arrays sort()
|
||||||
|
|
||||||
|
|
||||||
Libraries:
|
Libraries:
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,8 @@
|
||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
/*
|
; mem()
|
||||||
mem()
|
; bytes()
|
||||||
bytes()
|
|
||||||
*/
|
|
||||||
words()
|
words()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +29,11 @@ main {
|
||||||
sub bytes() {
|
sub bytes() {
|
||||||
ubyte[] wa = [$1a, $2b, $3c]
|
ubyte[] wa = [$1a, $2b, $3c]
|
||||||
|
|
||||||
|
txt.print_ub(all(wa))
|
||||||
|
txt.spc()
|
||||||
|
txt.print_ub(any(wa))
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
txt.print_ubbin(wa[2], true)
|
txt.print_ubbin(wa[2], true)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
rol(wa[2])
|
rol(wa[2])
|
||||||
|
@ -51,37 +54,66 @@ main {
|
||||||
sub words() {
|
sub words() {
|
||||||
uword[] wa = [$11aa, $22bb, $33cc]
|
uword[] wa = [$11aa, $22bb, $33cc]
|
||||||
uword[] @split swa = [$11aa, $22bb, $33cc]
|
uword[] @split swa = [$11aa, $22bb, $33cc]
|
||||||
|
uword[] waone = [$0000, $3300, $0000]
|
||||||
|
uword[] wazero = [$0000, $0000, $0000]
|
||||||
|
uword[] @split swaone = [$0000, $3300, $0000]
|
||||||
|
uword[] @split swazero = [$0000, $0000, $0000]
|
||||||
|
|
||||||
txt.print_uwbin(wa[2], true)
|
; txt.print_ub(all(wa)) ; 1
|
||||||
txt.nl()
|
; txt.spc()
|
||||||
rol(wa[2])
|
; txt.print_ub(any(wa)) ; 1
|
||||||
txt.print_uwbin(wa[2], true)
|
; txt.nl()
|
||||||
txt.nl()
|
; txt.print_ub(all(waone)) ; 0
|
||||||
rol2(wa[2])
|
; txt.spc()
|
||||||
txt.print_uwbin(wa[2], true)
|
; txt.print_ub(any(waone)) ; 1
|
||||||
txt.nl()
|
; txt.nl()
|
||||||
ror(wa[2])
|
;; txt.print_ub(all(swaone)) ; 0
|
||||||
txt.print_uwbin(wa[2], true)
|
;; txt.spc()
|
||||||
txt.nl()
|
txt.print_ub(any(swaone)) ; 1
|
||||||
ror2(wa[2])
|
|
||||||
txt.print_uwbin(wa[2], true)
|
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
;; txt.print_ub(all(swa)) ; 1
|
||||||
|
;; txt.spc()
|
||||||
|
; txt.print_ub(any(swa)) ; 1
|
||||||
|
; txt.nl()
|
||||||
|
; txt.print_ub(all(wazero)) ; 0
|
||||||
|
; txt.spc()
|
||||||
|
; txt.print_ub(any(wazero)) ; 0
|
||||||
|
; txt.nl()
|
||||||
|
;; txt.print_ub(all(swazero)) ; 0
|
||||||
|
;; txt.spc()
|
||||||
|
txt.print_ub(any(swazero)) ; 0
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
|
||||||
txt.print_uwbin(swa[2], true)
|
; txt.print_uwbin(wa[2], true)
|
||||||
txt.nl()
|
; txt.nl()
|
||||||
rol(swa[2])
|
; rol(wa[2])
|
||||||
txt.print_uwbin(swa[2], true)
|
; txt.print_uwbin(wa[2], true)
|
||||||
txt.nl()
|
; txt.nl()
|
||||||
rol2(swa[2])
|
; rol2(wa[2])
|
||||||
txt.print_uwbin(swa[2], true)
|
; txt.print_uwbin(wa[2], true)
|
||||||
txt.nl()
|
; txt.nl()
|
||||||
ror(swa[2])
|
; ror(wa[2])
|
||||||
txt.print_uwbin(swa[2], true)
|
; txt.print_uwbin(wa[2], true)
|
||||||
txt.nl()
|
; txt.nl()
|
||||||
ror2(swa[2])
|
; ror2(wa[2])
|
||||||
txt.print_uwbin(swa[2], true)
|
; txt.print_uwbin(wa[2], true)
|
||||||
txt.nl()
|
; txt.nl()
|
||||||
txt.nl()
|
; txt.nl()
|
||||||
|
;
|
||||||
|
; txt.print_uwbin(swa[2], true)
|
||||||
|
; txt.nl()
|
||||||
|
; rol(swa[2])
|
||||||
|
; txt.print_uwbin(swa[2], true)
|
||||||
|
; txt.nl()
|
||||||
|
; rol2(swa[2])
|
||||||
|
; txt.print_uwbin(swa[2], true)
|
||||||
|
; txt.nl()
|
||||||
|
; ror(swa[2])
|
||||||
|
; txt.print_uwbin(swa[2], true)
|
||||||
|
; txt.nl()
|
||||||
|
; ror2(swa[2])
|
||||||
|
; txt.print_uwbin(swa[2], true)
|
||||||
|
; txt.nl()
|
||||||
|
; txt.nl()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user