added string.rfind()

This commit is contained in:
Irmen de Jong 2024-08-22 22:54:38 +02:00
parent 8f6eaeac2c
commit b566ea5c3f
5 changed files with 89 additions and 43 deletions

View File

@ -13,6 +13,7 @@
; NOTE: For sake of speed, NO BOUNDS CHECKING is performed in most routines!
; You'll have to make sure yourself that you're not writing outside of bitmap boundaries!
;
; NOTE: the bitmap screen data is positioned in vram at $0:0000
;
; SCREEN MODE LIST:
; mode 0 = reset back to default text mode

View File

@ -134,11 +134,11 @@ _startloop dey
; need to copy the the cx16 virtual registers to zeropage to make this run on C64...
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
stx P8ZP_SCRATCH_B1
stx _comparemod+1
ldy #0
- lda (P8ZP_SCRATCH_W1),y
beq _notfound
cmp P8ZP_SCRATCH_B1
_comparemod cmp #0 ; modified
beq _found
iny
bne -
@ -151,6 +151,37 @@ _found tya
}}
}
asmsub rfind(uword string @AY, ubyte character @X) -> ubyte @A, bool @Pc {
; Locates the first position of the given character in the string, starting from the right.
; returns Carry set if found + index in A, or Carry clear if not found (and A will be 255, an invalid index).
%asm {{
stx _comparemod+1
sta _str
sty _str+1
jsr string.length
dey
lda _str
sta P8ZP_SCRATCH_W1
lda _str+1
sta P8ZP_SCRATCH_W1+1
- lda (P8ZP_SCRATCH_W1),y
_comparemod cmp #0 ; modified
beq _found
dey
cpy #255
bne -
_notfound lda #255
clc
rts
_found tya
sec
rts
_str .word 0
}}
}
asmsub contains(uword string @AY, ubyte character @X) -> bool @Pc {
; Just return true/false if the character is in the given string or not.
%asm {{

View File

@ -68,6 +68,21 @@ string {
return 255
}
sub rfind(uword stringptr, ubyte character) -> ubyte {
; Locates the first position of the given character in the string, starting from the right.
; returns Carry set if found + index in A, or Carry clear if not found (and A will be 255, an invalid index).
; NOTE: because this isn't an asmsub, there's only a SINGLE return value here. On the c64/cx16 targets etc there are 2 return values.
ubyte ix
for ix in string.length(stringptr)-1 downto 0 {
if stringptr[ix]==character {
sys.set_carry()
return ix
}
}
sys.clear_carry()
return 255
}
sub contains(str st, ubyte character) -> bool {
void find(st, character)
if_cs

View File

@ -483,14 +483,15 @@ Provides string manipulation routines.
Also, you have to make sure yourself that start and length are within bounds of the strings.
Modifies in-place, doesn't return a value (so can't be used in an expression).
``find (string, char) -> ubyte index + carry bit``
Locates the first position of the given character in the string, returns carry bit set if found
and the index in the string. Or 0+carry bit clear if the character was not found.
``find (string, char) -> ubyte index, bool found``
Locates the first index of the given character in the string, and a boolean (in Carry flag)
to say if it was found at all. If the character is not found, index 255 (and false) is returned.
You can consider this a safer way of checking if a character occurs
in a string than using an `in` containment check - because the find routine
properly stops at the first 0-byte string terminator it encounters.
Simply call this and only act on the carry status with ``if_cc`` for example.
Much like the difference between len(str) and length(str).
in a string than using an `in` containment check - because this find routine
properly stops at the first 0-byte string terminator it encounters in case the string was modified.
``rfind (string, char) -> ubyte index, bool found``
Like ``find``, but now looking from the *right* of the string instead.
``contains (string, char) -> bool``
Just returns true if the character is in the given string, or false if it's not.

View File

@ -1,48 +1,46 @@
%import textio
%import string
%option no_sysinit
%zeropage basicsafe
main {
sub start() {
ubyte @shared v1,v2,v3
v1 = %10011001
v2 = %10101010
v3 = %00111100
str name = "zn.iff.jpg"
v1 &= %00011111
v1++
txt.print_ubbin(v1, true)
txt.nl()
ubyte index
bool found
v1 &= ~v2
v1++
txt.print_ubbin(v1, true)
index, found = string.find(name, '.')
if found {
txt.print_ub(index)
txt.nl()
} else {
txt.print(". not found\n")
}
v1 |= 100
v1++
txt.print_ubbin(v1, true)
index, found = string.find(name, '@')
if found {
txt.print_ub(index)
txt.nl()
} else {
txt.print("@ not found\n")
}
v1 |= v2
v1++
txt.print_ubbin(v1, true)
index, found = string.rfind(name, '.')
if found {
txt.print_ub(index)
txt.nl()
} else {
txt.print(". not r found\n")
}
v1 |= v2 & v3
v1++
txt.print_ubbin(v1, true)
txt.nl()
v1 &= v2|v3
v1++
txt.print_ubbin(v1, true)
txt.nl()
v1 &= ~(v2|v3)
v1++
txt.print_ubbin(v1, true)
index, found = string.rfind(name, '@')
if found {
txt.print_ub(index)
txt.nl()
} else {
txt.print("@ not r found\n")
}
}
}