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 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 { asmsub find(uword string @AY, ubyte character @X) -> ubyte @A, bool @Pc {
; Locates the first position of the given character in the string, ; 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 {{ %asm {{
; need to copy the the cx16 virtual registers to zeropage to make this run on C64... ; need to copy the the cx16 virtual registers to zeropage to make this run on C64...
sta P8ZP_SCRATCH_W1 sta P8ZP_SCRATCH_W1
@ -142,7 +142,7 @@ _startloop dey
beq _found beq _found
iny iny
bne - bne -
_notfound lda #0 _notfound lda #255
clc clc
rts rts
_found tya _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 { asmsub pattern_match(str string @AY, str pattern @R0) clobbers(Y) -> bool @A {
%asm {{ %asm {{
; pattern matching of a string. ; 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 { asmsub hash(str string @R0) -> ubyte @A {
; experimental 8 bit hashing function. ; experimental 8 bit hashing function.
; hash(-1)=179; clear carry; hash(i) = ROL hash(i-1) XOR string[i] ; 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 { sub find(str st, ubyte character) -> ubyte {
; Locates the first position of the given character in the string, ; 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 ubyte ix
for ix in 0 to length(st)-1 { for ix in 0 to length(st)-1 {
if st[ix]==character { if st[ix]==character {
@ -64,7 +64,7 @@ string {
} }
} }
sys.clear_carry() sys.clear_carry()
return 0 return 255
} }
sub contains(str st, ubyte character) -> bool { sub contains(str st, ubyte character) -> bool {
@ -147,26 +147,6 @@ string {
return char 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 { sub hash(str st) -> ubyte {
; experimental 8 bit hashing function. ; experimental 8 bit hashing function.
; hash(-1)=179; hash(i) = ROL hash(i-1) XOR string[i] ; 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)) 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 copyStringValue(assignment)
}
}
return noModifications return noModifications
} }

View File

@ -238,7 +238,6 @@ Directives
Level: not at module scope. Level: not at module scope.
Declares that a piece of *assembly code* is inside the curly braces. 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. 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 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 ``}}``, that the assembly code itself contains either of those. If it does contain a ``}}``,
it will confuse the parser. 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 the assembly code. Sometimes you'll have to declare a variable in prog8 with `@shared` if it
is only used in such assembly code. 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:: .. caution::
Avoid using single-letter symbols in included assembly code, as they could be confused with CPU registers. 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`. Also, note that all prog8 symbols are prefixed in assembly code, see :ref:`symbol-prefixing`.

View File

@ -1,22 +1,78 @@
%import textio %import textio
%import string
%zeropage basicsafe %zeropage basicsafe
%option no_sysinit
main { main {
sub start() { sub start() {
ubyte[] ubarray = [11,22,33] str name = "irmen@de@jong"
uword[] uwarray = [1111,2222,3333] cx16.r0L = findstr(name, "de-")
uword[] @split suwarray = [1111,2222,3333] if_cs {
txt.print("found1. error. ")
ubarray[1] *= 10 } else {
uwarray[1] *= 10 txt.print("not found1. ok ")
suwarray[1] *= 10 }
txt.print_ub(cx16.r0L)
txt.print_ub(ubarray[1])
txt.nl() txt.nl()
txt.print_uw(uwarray[1])
txt.nl() 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() 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 kotlin.code.style=official
javaVersion=11 javaVersion=11
kotlinVersion=1.9.22 kotlinVersion=1.9.22
version=10.2 version=10.3-SNAPSHOT