added string.findstr(). string.find() returns 255 if not found.

also fix string assignment bug for sub args.
This commit is contained in:
Irmen de Jong 2024-03-17 23:18:33 +01:00
parent fe2b67998c
commit d14c61b160
7 changed files with 122 additions and 61 deletions

View File

@ -76,4 +76,44 @@ string {
return s+cx16.r0L
}
sub startswith(str st, str prefix) -> bool {
ubyte prefix_len = string.length(prefix)
ubyte str_len = string.length(st)
if prefix_len > str_len
return false
cx16.r9L = st[prefix_len]
st[prefix_len] = 0
cx16.r9H = string.compare(st, prefix) as ubyte
st[prefix_len] = cx16.r9L
return cx16.r9H==0
}
sub endswith(str st, str suffix) -> bool {
ubyte suffix_len = string.length(suffix)
ubyte str_len = string.length(st)
if suffix_len > str_len
return false
return string.compare(st + str_len - suffix_len, suffix) == 0
}
sub findstr(str haystack, str needle) -> ubyte {
; searches for needle in haystack.
; returns index in haystack where it first occurs, and Carry set,
; or if needle doesn't occur in haystack it returns Carry clear and 255 (an invalid index.)
cx16.r2L = string.length(haystack)
cx16.r3L = string.length(needle)
if cx16.r3L <= cx16.r2L {
cx16.r2L = cx16.r2L-cx16.r3L+1
cx16.r3 = haystack
repeat cx16.r2L {
if string.startswith(cx16.r3, needle) {
sys.set_carry()
return cx16.r3-haystack as ubyte
}
cx16.r3++
}
}
sys.clear_carry()
return 255
}
}

View File

@ -129,7 +129,7 @@ _startloop dey
asmsub find(uword string @AY, ubyte character @X) -> ubyte @A, bool @Pc {
; Locates the first position of the given character in the string,
; returns Carry set if found + index in A, or A=0 + Carry clear if not found.
; returns Carry set if found + index in A, or Carry clear if not found (and A will be 255, an invalid index).
%asm {{
; need to copy the the cx16 virtual registers to zeropage to make this run on C64...
sta P8ZP_SCRATCH_W1
@ -142,7 +142,7 @@ _startloop dey
beq _found
iny
bne -
_notfound lda #0
_notfound lda #255
clc
rts
_found tya
@ -277,26 +277,6 @@ _done rts
}}
}
sub startswith(str st, str prefix) -> bool {
ubyte prefix_len = length(prefix)
ubyte str_len = length(st)
if prefix_len > str_len
return false
cx16.r9L = st[prefix_len]
st[prefix_len] = 0
cx16.r9H = compare(st, prefix) as ubyte
st[prefix_len] = cx16.r9L
return cx16.r9H==0
}
sub endswith(str st, str suffix) -> bool {
ubyte suffix_len = length(suffix)
ubyte str_len = length(st)
if suffix_len > str_len
return false
return compare(st + str_len - suffix_len, suffix) == 0
}
asmsub pattern_match(str string @AY, str pattern @R0) clobbers(Y) -> bool @A {
%asm {{
; pattern matching of a string.
@ -366,7 +346,6 @@ fail clc ; yes, no match found, return with c=0
}}
}
asmsub hash(str string @R0) -> ubyte @A {
; experimental 8 bit hashing function.
; hash(-1)=179; clear carry; hash(i) = ROL hash(i-1) XOR string[i]

View File

@ -55,7 +55,7 @@ string {
sub find(str st, ubyte character) -> ubyte {
; Locates the first position of the given character in the string,
; returns Carry set if found + index in A, or Carry clear if not found.
; returns Carry set if found + index in A, or Carry clear if not found (and A will be 255, an invalid index).
ubyte ix
for ix in 0 to length(st)-1 {
if st[ix]==character {
@ -64,7 +64,7 @@ string {
}
}
sys.clear_carry()
return 0
return 255
}
sub contains(str st, ubyte character) -> bool {
@ -147,26 +147,6 @@ string {
return char
}
sub startswith(str st, str prefix) -> bool {
ubyte prefix_len = length(prefix)
ubyte str_len = length(st)
if prefix_len > str_len
return false
cx16.r9L = st[prefix_len]
st[prefix_len] = 0
cx16.r9H = compare(st, prefix) as ubyte
st[prefix_len] = cx16.r9L
return cx16.r9H==0
}
sub endswith(str st, str suffix) -> bool {
ubyte suffix_len = length(suffix)
ubyte str_len = length(st)
if suffix_len > str_len
return false
return compare(st + str_len - suffix_len, suffix) == 0
}
sub hash(str st) -> ubyte {
; experimental 8 bit hashing function.
; hash(-1)=179; hash(i) = ROL hash(i-1) XOR string[i]

View File

@ -214,8 +214,12 @@ internal class StatementReorderer(
}
}
if(valueType.isString && (targetType istype DataType.STR || targetType istype DataType.ARRAY_B || targetType istype DataType.ARRAY_UB))
return copyStringValue(assignment)
if(!assignment.isAugmentable) {
if (valueType.isString && (targetType istype DataType.STR || targetType istype DataType.ARRAY_B || targetType istype DataType.ARRAY_UB)) {
// replace string assignment by a call to stringcopy
return copyStringValue(assignment)
}
}
return noModifications
}

View File

@ -238,7 +238,6 @@ Directives
Level: not at module scope.
Declares that a piece of *assembly code* is inside the curly braces.
This code will be copied as-is into the generated output assembly source file.
The assembler syntax used should be for the 3rd party cross assembler tool that Prog8 uses (64tass).
Note that the start and end markers are both *double curly braces* to minimize the chance
that the assembly code itself contains either of those. If it does contain a ``}}``,
it will confuse the parser.
@ -247,6 +246,9 @@ Directives
the assembly code. Sometimes you'll have to declare a variable in prog8 with `@shared` if it
is only used in such assembly code.
.. note::
64tass syntax is required for the assembly code. As such, mnemonics need to be written in lowercase.
.. caution::
Avoid using single-letter symbols in included assembly code, as they could be confused with CPU registers.
Also, note that all prog8 symbols are prefixed in assembly code, see :ref:`symbol-prefixing`.

View File

@ -1,22 +1,78 @@
%import textio
%import string
%zeropage basicsafe
%option no_sysinit
main {
sub start() {
ubyte[] ubarray = [11,22,33]
uword[] uwarray = [1111,2222,3333]
uword[] @split suwarray = [1111,2222,3333]
ubarray[1] *= 10
uwarray[1] *= 10
suwarray[1] *= 10
txt.print_ub(ubarray[1])
str name = "irmen@de@jong"
cx16.r0L = findstr(name, "de-")
if_cs {
txt.print("found1. error. ")
} else {
txt.print("not found1. ok ")
}
txt.print_ub(cx16.r0L)
txt.nl()
txt.print_uw(uwarray[1])
txt.nl()
txt.print_uw(suwarray[1])
cx16.r0L = findstr(name, "de@")
if_cs {
txt.print("found2 (6?). ")
} else {
txt.print("not found2. error ")
}
txt.print_ub(cx16.r0L)
txt.nl()
txt.nl()
cx16.r0L = findstr(name, "irmen@de@jong")
if_cs {
txt.print("found3 (0?). ")
} else {
txt.print("not found3. error ")
}
txt.print_ub(cx16.r0L)
txt.nl()
txt.nl()
cx16.r0L = findstr(name, "irmen@de@jong1")
if_cs {
txt.print("found4. error. ")
} else {
txt.print("not found4. ok ")
}
txt.print_ub(cx16.r0L)
txt.nl()
txt.nl()
cx16.r0L = findstr(name, "jong")
if_cs {
txt.print("found5 (9?). ")
} else {
txt.print("not found5. error ")
}
txt.print_ub(cx16.r0L)
txt.nl()
txt.nl()
}
sub findstr(str haystack, str needle) -> ubyte {
; searches for needle in haystack.
; returns index in haystack where it first occurs, and Carry set,
; or if needle doesn't occur in haystack it returns Carry clear and 255 (an invalid index.)
txt.print_uwhex(haystack, true)
txt.spc()
txt.print(haystack)
txt.nl()
cx16.r2L = string.length(haystack)
cx16.r3L = string.length(needle)
if cx16.r3L <= cx16.r2L {
cx16.r2L = cx16.r2L-cx16.r3L+1
repeat cx16.r2L {
if string.startswith(haystack, needle) {
sys.set_carry()
return 13 as ubyte
}
haystack++
}
}
sys.clear_carry()
return 255
}
}

View File

@ -5,4 +5,4 @@ org.gradle.daemon=true
kotlin.code.style=official
javaVersion=11
kotlinVersion=1.9.22
version=10.2
version=10.3-SNAPSHOT