any and all

This commit is contained in:
Irmen de Jong 2018-12-17 01:59:04 +01:00
parent 13a5a06ffb
commit 178a46ad7f
4 changed files with 213 additions and 34 deletions

View File

@ -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')
}
}

View File

@ -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()

View File

@ -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()

View File

@ -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