From 178a46ad7f866c7288bef2ab28f9c598e5a4ed9a Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 17 Dec 2018 01:59:04 +0100 Subject: [PATCH] any and all --- compiler/examples/test.p8 | 60 +++++++++- compiler/src/prog8/compiler/Compiler.kt | 21 ++++ compiler/src/prog8/stackvm/StackVm.kt | 24 ++-- prog8lib/prog8lib.p8 | 142 +++++++++++++++++++++--- 4 files changed, 213 insertions(+), 34 deletions(-) diff --git a/compiler/examples/test.p8 b/compiler/examples/test.p8 index 852a58795..967801acf 100644 --- a/compiler/examples/test.p8 +++ b/compiler/examples/test.p8 @@ -18,12 +18,18 @@ float f3 ubyte[3] uba = [1,2,3] - byte[3] ba = [-1,2,3] - uword[3] uwa = [1000,2000,3000] + byte[3] ba = [-1,0,3] + uword[3] uwa = [1000,200,0] word[3] wa = -222 + ubyte[3] uba0 = 0 + byte[3] ba0 = 0 + uword[3] uwa0 = 0 + word[3] wa0 = 0 ;word[3] wa = [-1000.w,2000.w,3000.w] ; @todo array data type fix (float->word) ;word[3] wa = [1000,2000,3000] ; @todo array data type fix (uword->word) - float[3] fa = [-1000,44.555, 99.999] + float[3] fa0 = 0.0 + float[3] fa1 = [-1000,44.555, 99.999] + float[3] fa2 = [-1000,44.555, 0] str string = "hello" str_p pstring = "hello1" str_s sstring = "hello12" @@ -45,13 +51,59 @@ ub1 = any(wa) c64scr.print_ubyte_decimal(ub1) c64.CHROUT('\n') - ub1 = any(fa) + ub1 = any(fa1) c64scr.print_ubyte_decimal(ub1) c64.CHROUT('\n') + ub1 = any(fa2) + c64scr.print_ubyte_decimal(ub1) + c64.CHROUT('\n') + + ub1 = any(uba0) + c64scr.print_ubyte_decimal(ub1) + c64.CHROUT('\n') + ub1 = any(ba0) + c64scr.print_ubyte_decimal(ub1) + c64.CHROUT('\n') + ub1 = any(uwa0) + c64scr.print_ubyte_decimal(ub1) + c64.CHROUT('\n') + ub1 = any(wa0) + c64scr.print_ubyte_decimal(ub1) + c64.CHROUT('\n') + ub1 = any(fa0) + c64scr.print_ubyte_decimal(ub1) + c64.CHROUT('\n') + c64.CHROUT('x') c64scr.print_ubyte_decimal(X) c64.CHROUT('\n') + c64.CHROUT('x') + c64scr.print_ubyte_decimal(X) + c64.CHROUT('\n') + +; ub1 = all(uba) ; 1 ok +; c64scr.print_ubyte_decimal(ub1) +; c64.CHROUT('\n') +; ub1 = all(ba) ; 0 ok +; c64scr.print_ubyte_decimal(ub1) +; c64.CHROUT('\n') +; ub1 = all(uwa) ; 0 ok +; c64scr.print_ubyte_decimal(ub1) +; c64.CHROUT('\n') +; ub1 = all(wa) ; 1 ok +; c64scr.print_ubyte_decimal(ub1) +; c64.CHROUT('\n') +; ub1 = all(fa1) ; 1 ok +; c64scr.print_ubyte_decimal(ub1) +; c64.CHROUT('\n') +; ub1 = all(fa2) ; 0 ok +; c64scr.print_ubyte_decimal(ub1) +; c64.CHROUT('\n') +; c64.CHROUT('x') +; c64scr.print_ubyte_decimal(X) +; c64.CHROUT('\n') + } } diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index 4600c0442..9964d9e7c 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -682,6 +682,27 @@ private class StatementTranslator(private val prog: IntermediateProgram, else -> throw CompilerException("wrong datatype for len()") } } + "any", "all" -> { + // 1 array argument, type determines the exact syscall to use + val arg=args.single() as IdentifierReference + val target=arg.targetStatement(namespace) as VarDecl + val length=Value(DataType.UBYTE, target.arrayspec!!.size()!!) + when (arg.resultingDatatype(namespace, heap)) { + DataType.ARRAY_B, DataType.ARRAY_UB -> { + prog.instr(Opcode.PUSH_BYTE, length) + createSyscall("${funcname}_b") + } + DataType.ARRAY_W, DataType.ARRAY_UW -> { + prog.instr(Opcode.PUSH_BYTE, length) + createSyscall("${funcname}_w") + } + DataType.ARRAY_F -> { + prog.instr(Opcode.PUSH_BYTE, length) + createSyscall("${funcname}_f") + } + else -> throw CompilerException("wrong datatype for $funcname()") + } + } "flt" -> { // 1 argument, type determines the exact opcode to use val arg = args.single() diff --git a/compiler/src/prog8/stackvm/StackVm.kt b/compiler/src/prog8/stackvm/StackVm.kt index 35dbc368d..509f13be0 100644 --- a/compiler/src/prog8/stackvm/StackVm.kt +++ b/compiler/src/prog8/stackvm/StackVm.kt @@ -46,8 +46,6 @@ enum class Syscall(val callNr: Short) { FUNC_MIN(83), FUNC_AVG(84), FUNC_SUM(85), - FUNC_ANY(87), - FUNC_ALL(88), FUNC_RND(89), // push a random byte on the stack FUNC_RNDW(90), // push a random word on the stack FUNC_RNDF(91), // push a random float on the stack (between 0.0 and 1.0) @@ -61,7 +59,13 @@ enum class Syscall(val callNr: Short) { FUNC_LEN_STR(105), FUNC_LEN_STRP(106), FUNC_LEN_STRS(107), - FUNC_LEN_STRPS(108) + FUNC_LEN_STRPS(108), + FUNC_ANY_B(109), + FUNC_ANY_W(110), + FUNC_ANY_F(111), + FUNC_ALL_B(112), + FUNC_ALL_W(113), + FUNC_ALL_F(114) // note: not all builtin functions of the Prog8 language are present as functions: // some of them are straight opcodes (such as MSB, LSB, LSL, LSR, ROL_BYTE, ROR, ROL2, ROR2, and FLT)! @@ -1554,21 +1558,15 @@ class StackVm(private var traceOutputFile: String?) { else evalstack.push(Value(DataType.UWORD, value.array!!.sum())) } - Syscall.FUNC_ANY -> { + Syscall.FUNC_ANY_B, Syscall.FUNC_ANY_W, Syscall.FUNC_ANY_F -> { val iterable = evalstack.pop() val value = heap.get(iterable.heapId) - if (value.str != null) - evalstack.push(Value(DataType.UBYTE, if (Petscii.encodePetscii(value.str, true).any { c -> c != 0.toShort() }) 1 else 0)) - else - evalstack.push(Value(DataType.UBYTE, if (value.array!!.any { v -> v != 0 }) 1 else 0)) + evalstack.push(Value(DataType.UBYTE, if (value.array!!.any { v -> v != 0 }) 1 else 0)) } - Syscall.FUNC_ALL -> { + Syscall.FUNC_ALL_B, Syscall.FUNC_ALL_W, Syscall.FUNC_ALL_F -> { val iterable = evalstack.pop() val value = heap.get(iterable.heapId) - if (value.str != null) - evalstack.push(Value(DataType.UBYTE, if (Petscii.encodePetscii(value.str, true).all { c -> c != 0.toShort() }) 1 else 0)) - else - evalstack.push(Value(DataType.UBYTE, if (value.array!!.all { v -> v != 0 }) 1 else 0)) + evalstack.push(Value(DataType.UBYTE, if (value.array!!.all { v -> v != 0 }) 1 else 0)) } Syscall.FUNC_STR2BYTE -> { val strvar = evalstack.pop() diff --git a/prog8lib/prog8lib.p8 b/prog8lib/prog8lib.p8 index a30f43717..69de16e6a 100644 --- a/prog8lib/prog8lib.p8 +++ b/prog8lib/prog8lib.p8 @@ -896,23 +896,134 @@ func_sum .proc rts .warn "sum not implemented--what does it sum over???" .pend - -func_any .proc - rts - .warn "any not implemented--of what does it do any?" - .pend - -func_all .proc - rts - .warn "all not implemented--of what does it do all?" - .pend - -func_len_str .proc - ; -- push length of 0-terminated string on stack + +peek_address .proc + ; -- peek address on stack into SCRATCH_ZPWORD1 lda ESTACK_LO+1,x sta SCRATCH_ZPWORD1 lda ESTACK_HI+1,x sta SCRATCH_ZPWORD1+1 + rts + .pend + +func_any_b .proc + inx + lda ESTACK_LO,x ; array size +_entry sta _cmp_mod+1 ; self-modifying code + jsr peek_address + ldy #0 +- lda (SCRATCH_ZPWORD1),y + bne _got_any + iny +_cmp_mod cpy #255 ; modified + bne - + lda #0 + sta ESTACK_LO+1,x + rts +_got_any lda #1 + sta ESTACK_LO+1,x + rts + .pend + +func_any_w .proc + inx + lda ESTACK_LO,x ; array size + asl a ; times 2 because of word + jmp func_any_b._entry + .pend + +func_any_f .proc + inx + lda ESTACK_LO,x ; array size + sta SCRATCH_ZPB1 + asl a + asl a + clc + adc SCRATCH_ZPB1 ; times 5 because of float + jmp func_any_b._entry + .pend + +func_all_b .proc + inx + lda ESTACK_LO,x ; array size + sta _cmp_mod+1 ; self-modifying code + jsr peek_address + ldy #0 +- lda (SCRATCH_ZPWORD1),y + beq _got_not_all + iny +_cmp_mod cpy #255 ; modified + bne - + lda #1 + sta ESTACK_LO+1,x + rts +_got_not_all lda #0 + sta ESTACK_LO+1,x + rts + .pend + +func_all_w .proc + inx + lda ESTACK_LO,x ; array size + asl a ; times 2 because of word + sta _cmp_mod+1 ; self-modifying code + jsr peek_address + ldy #0 +- lda (SCRATCH_ZPWORD1),y + bne + + iny + lda (SCRATCH_ZPWORD1),y + bne + + lda #0 + sta ESTACK_LO+1,x + rts ++ iny +_cmp_mod cpy #255 ; modified + bne - + lda #1 + sta ESTACK_LO+1,x + rts + .pend + +func_all_f .proc + inx + lda ESTACK_LO,x ; array size + sta SCRATCH_ZPB1 + asl a + asl a + clc + adc SCRATCH_ZPB1 ; times 5 because of float + sta _cmp_mod+1 ; self-modifying code + jsr peek_address + ldy #0 +- lda (SCRATCH_ZPWORD1),y + bne + + iny + lda (SCRATCH_ZPWORD1),y + bne + + iny + lda (SCRATCH_ZPWORD1),y + bne + + iny + lda (SCRATCH_ZPWORD1),y + bne + + iny + lda (SCRATCH_ZPWORD1),y + bne + + lda #0 + sta ESTACK_LO+1,x + rts ++ iny +_cmp_mod cpy #255 ; modified + bne - + lda #1 + sta ESTACK_LO+1,x + rts + .pend + +func_len_str .proc + ; -- push length of 0-terminated string on stack + jsr peek_address ldy #0 - lda (SCRATCH_ZPWORD1),y beq + @@ -925,10 +1036,7 @@ func_len_str .proc func_len_strp .proc ; -- push length of pascal-string on stack - lda ESTACK_LO+1,x - sta SCRATCH_ZPWORD1 - lda ESTACK_HI+1,x - sta SCRATCH_ZPWORD1+1 + jsr peek_address ldy #0 lda (SCRATCH_ZPWORD1),y ; first byte is length sta ESTACK_LO+1,x