Implement new string functions (#1655)

`STRFIND`, `STRRFIND`, `STRCHAR`, `STRSLICE`, `CHARCMP`, `CHARSIZE`, and `REVCHAR`
This commit is contained in:
Rangi
2025-02-14 23:09:45 +01:00
committed by GitHub
parent ad4d9da4cf
commit 3feb75f84f
27 changed files with 584 additions and 134 deletions

27
test/asm/charcmp.asm Normal file
View File

@@ -0,0 +1,27 @@
charmap "a", 1
charmap "b", 2
charmap "c", 0
charmap "w", 3, 2, 1
charmap "x", 1, 2
charmap "y", 2, 1
charmap "z", 1, 2, 3
macro test
println strfmt("\"%#s\" <=> \"%#s\" == %d", \1, \2, charcmp(\1, \2))
endm
test "", ""
test "a", "a"
test "aa", "aaa"
test "aaa", "aa"
test "a", "b"
test "b", "a"
test "", "b"
test "c", ""
test "abc", "cba"
test "cabc", "cxc"
test "zy", "abw"
test "abab", "xx"
test "abab", "ww"
test "w", "z"
test "xcy", "zw"

15
test/asm/charcmp.out Normal file
View File

@@ -0,0 +1,15 @@
"" <=> "" == 0
"a" <=> "a" == 0
"aa" <=> "aaa" == -1
"aaa" <=> "aa" == 1
"a" <=> "b" == -1
"b" <=> "a" == 1
"" <=> "b" == -1
"c" <=> "" == 1
"abc" <=> "cba" == 1
"cabc" <=> "cxc" == 0
"zy" <=> "abw" == 0
"abab" <=> "xx" == 0
"abab" <=> "ww" == -1
"w" <=> "z" == 1
"xcy" <=> "zw" == -1

View File

@@ -1,28 +0,0 @@
opt Wno-unmapped-char
charmap "<NULL>", $00
charmap "A", $10
charmap "B", $20
charmap "C", $30
charmap "Bold", $88
SECTION "test", ROM0
DEF S EQUS "XBold<NULL>ABC"
assert CHARLEN("{S}") == 6
println CHARSUB("{S}", 2)
assert !STRCMP(CHARSUB("{S}", 2), "Bold")
assert CHARSUB("{S}", -5) == CHARSUB("{S}", CHARLEN("{S}") + 1 - 5)
assert CHARSUB("{S}", 2) == "Bold" && "Bold" == $88
assert CHARSUB("{S}", 1) == $58 ; ASCII "X"
db "{S}"
newcharmap ascii
assert CHARLEN("{S}") == 14
println CHARSUB("{S}", 2)
assert !STRCMP(CHARSUB("{S}", 2), "B")
assert CHARSUB("{S}", -5) == CHARSUB("{S}", CHARLEN("{S}") + 1 - 5)
assert CHARSUB("{S}", 2) == "B" && "B" == $42 ; ASCII "B"
assert CHARSUB("{S}", 1) == $58 ; ASCII "X"
db "{S}"

View File

@@ -0,0 +1,34 @@
opt Wno-unmapped-char
charmap "<NULL>", $00
charmap "A", $10
charmap "B", $20
charmap "C", $30
charmap "Bold", $88
SECTION "test", ROM0
DEF S EQUS "XBold<NULL>ABC"
assert CHARLEN("{S}") == 6
println STRCHAR("{S}", 1)
assert !STRCMP(STRCHAR("{S}", 1), "Bold")
assert STRCHAR("{S}", -5) == STRCHAR("{S}", CHARLEN("{S}") - 5)
assert STRCHAR("{S}", 1) == "Bold" && "Bold" == $88
assert STRCHAR("{S}", 0) == $58 ; ASCII "X"
db "{S}"
for n, CHARLEN("{S}")
assert STRCHAR("{S}", n) == CHARSUB("{S}", n + 1)
assert STRCHAR("{S}", -n - 1) == CHARSUB("{S}", -n - 1)
endr
newcharmap ascii
assert CHARLEN("{S}") == 14
println STRCHAR("{S}", 1)
assert !STRCMP(STRCHAR("{S}", 1), "B")
assert STRCHAR("{S}", -5) == STRCHAR("{S}", CHARLEN("{S}") - 5)
assert STRCHAR("{S}", 1) == "B" && "B" == $42 ; ASCII "B"
assert STRCHAR("{S}", 0) == $58 ; ASCII "X"
db "{S}"

20
test/asm/charsize.asm Normal file
View File

@@ -0,0 +1,20 @@
charmap "a", 1
charmap "b", 2, 3
charmap "cdef", 4
charmap "ghi", 5, 6, 7, 8, 9
charmap "jkl", 123, 456, 789
charmap "mno", 123456789
charmap "¡Pokémon!", 2, 3
assert charsize("a") == 1
assert charsize("b") == 2
assert charsize("cdef") == 1
assert charsize("ghi") == 5
assert charsize("jkl") == 3
assert charsize("mno") == 1
assert charsize("¡Pokémon!") == 2
assert charsize("") == 0
assert charsize("hello world") == 0
assert charsize("abcdef") == 0
assert charsize("é") == 0

9
test/asm/charsize.err Normal file
View File

@@ -0,0 +1,9 @@
error: charsize.asm(17):
CHARSIZE: No character mapping for ""
error: charsize.asm(18):
CHARSIZE: No character mapping for "hello world"
error: charsize.asm(19):
CHARSIZE: No character mapping for "abcdef"
error: charsize.asm(20):
CHARSIZE: No character mapping for "é"
error: Assembly aborted (4 errors)!

View File

@@ -1 +0,0 @@
DEF S EQUS CHARSUB("ABC", 4)

View File

@@ -1,2 +0,0 @@
warning: invalid-charsub.asm(1): [-Wbuiltin-args]
CHARSUB: Position 4 is past the end of the string

View File

@@ -0,0 +1,3 @@
DEF S EQUS STRCHAR("ABC", 3)
DEF T EQUS CHARSUB("ABC", 4)
DEF U EQUS CHARSUB("ABC", 0)

View File

@@ -0,0 +1,6 @@
warning: invalid-strchar-charsub.asm(1): [-Wbuiltin-args]
STRCHAR: Index 3 is past the end of the string
warning: invalid-strchar-charsub.asm(2): [-Wbuiltin-args]
CHARSUB: Position 4 is past the end of the string
warning: invalid-strchar-charsub.asm(3): [-Wbuiltin-args]
CHARSUB: Position starts at 1

View File

@@ -36,8 +36,8 @@ DEF n = STRLEN("{invalid}")
DEF r = CHARLEN("{invalid}")
println "\"{#s:invalid}\": {d:n} == {d:r}"
REDEF mid1 EQUS CHARSUB("{invalid}", 4)
REDEF mid2 EQUS CHARSUB("{invalid}", 7)
REDEF mid1 EQUS STRCHAR("{invalid}", 3)
REDEF mid2 EQUS STRCHAR("{invalid}", 6)
println "\"{#s:mid2}{#s:mid1}\""
; characters:

23
test/asm/revchar.asm Normal file
View File

@@ -0,0 +1,23 @@
charmap "a", 1
charmap "b", 2
charmap "c", 3
charmap "d", 3
charmap "eeeee", $12345678
charmap "x", 1, 2, 3
charmap "y", 4, 5, 6, 7, 8, $99999999
charmap "zed", $1234, $5678, $9abc, $def0
macro test
redef expected equs \1
shift
assert !strcmp(revchar(\#), "{expected}")
endm
test "a", 1
test "b", 2
test "eeeee", 305419896
test "x", 1, 2, 3
test "y", 4, 5, 6, 7, 8, $99999999
test "zed", 4660, 22136, 39612, 57072
test "", 3 ; multiple
test "", 4 ; none

5
test/asm/revchar.err Normal file
View File

@@ -0,0 +1,5 @@
error: revchar.asm(22) -> revchar.asm::test(13):
REVCHAR: Multiple character mappings to values
error: revchar.asm(23) -> revchar.asm::test(13):
REVCHAR: No character mapping to values
error: Assembly aborted (2 errors)!

View File

@@ -1,15 +1,28 @@
SECTION "Test", ROM0
assert STRFIND("foo bar baz", "bar") == STRRFIND("foo bar baz", "bar")
assert STRIN("foo bar baz", "bar") == STRRIN("foo bar baz", "bar")
assert STRFIND("foo bar bargain", "bar") == 4
assert STRIN("foo bar bargain", "bar") == 5
assert STRRFIND("foo bar bargain", "bar") == 8
assert STRRIN("foo bar bargain", "bar") == 9
assert STRFIND("foo bar", "qux") == -1
assert STRIN("foo bar", "qux") == 0
assert STRRFIND("foo bar", "qux") == -1
assert STRRIN("foo bar", "qux") == 0
assert STRFIND("foo", "foobar") == -1
assert STRIN("foo", "foobar") == 0
assert STRRFIND("foo", "foobar") == -1
assert STRRIN("foo", "foobar") == 0
assert STRFIND("foobar", "") == 0
assert STRIN("foobar", "") == 1
assert STRRFIND("foobar", "") == STRLEN("foobar")
assert STRRIN("foobar", "") == STRLEN("foobar") + 1

View File

@@ -0,0 +1,57 @@
MACRO xstrslice
PRINTLN "STRSLICE(\#): ", STRSLICE(\#)
ENDM
xstrslice "ABC", 0, 1
xstrslice "ABC", 1, 2
xstrslice "ABC", 2, 3
xstrslice "ABC", -3, -2
xstrslice "ABC", -2, -1
xstrslice "ABC", -1, -0 ; lol
xstrslice "ABC", -1, 3
xstrslice "ABC", 1
xstrslice "ABC", -2
xstrslice "ABC", 4
xstrslice "ABC", -4
xstrslice "ABC", 0, 2
xstrslice "ABC", 1, 3
xstrslice "ABC", 1, 31
xstrslice "ABC", 1, 300
xstrslice "ABC", -4, 300
xstrslice "ABC", 3, 3
xstrslice "ABC", 4, 4
xstrslice "ABC", 3, 4
xstrslice "カタカナ", 0, 2
xstrslice "カタカナ", 2, 4
xstrslice "カタカナ", 2, 12
xstrslice "g̈", 0, 1
xstrslice "g̈", 0, 2
MACRO xstrsub
PRINTLN "STRSUB(\#): ", STRSUB(\#)
ENDM
xstrsub "ABC", 1, 1
xstrsub "ABC", 2, 1
xstrsub "ABC", 3, 1
xstrsub "ABC", -3, 1
xstrsub "ABC", -2, 1
xstrsub "ABC", -1, 1
xstrsub "ABC", 2
xstrsub "ABC", 0
xstrsub "ABC", -2
xstrsub "ABC", 5
xstrsub "ABC", -5
xstrsub "ABC", 1, 2
xstrsub "ABC", 2, 2
xstrsub "ABC", 2, 32
xstrsub "ABC", 2, 300
xstrsub "ABC", -4, 300
xstrsub "ABC", 4, 0
xstrsub "ABC", 5, 0
xstrsub "ABC", 4, 1
xstrsub "カタカナ", 1, 2
xstrsub "カタカナ", 3, 2
xstrsub "カタカナ", 3, 10
xstrsub "g̈", 1, 1
xstrsub "g̈", 1, 2

View File

@@ -0,0 +1,40 @@
warning: strslice-strsub.asm(14) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Start index 4 is past the end of the string
warning: strslice-strsub.asm(15) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Index starts at 0
warning: strslice-strsub.asm(18) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Stop index 31 is past the end of the string
warning: strslice-strsub.asm(19) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Stop index 300 is past the end of the string
warning: strslice-strsub.asm(20) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Index starts at 0
warning: strslice-strsub.asm(20) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Stop index 300 is past the end of the string
warning: strslice-strsub.asm(22) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Start index 4 is past the end of the string
warning: strslice-strsub.asm(22) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Stop index 4 is past the end of the string
warning: strslice-strsub.asm(23) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Stop index 4 is past the end of the string
warning: strslice-strsub.asm(26) -> strslice-strsub.asm::xstrslice(2): [-Wbuiltin-args]
STRSLICE: Stop index 12 is past the end of the string
warning: strslice-strsub.asm(41) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Position starts at 1
warning: strslice-strsub.asm(43) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Position 5 is past the end of the string
warning: strslice-strsub.asm(44) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Position starts at 1
warning: strslice-strsub.asm(47) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Length too big: 32
warning: strslice-strsub.asm(48) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Length too big: 300
warning: strslice-strsub.asm(49) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Position starts at 1
warning: strslice-strsub.asm(49) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Length too big: 300
warning: strslice-strsub.asm(51) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Position 5 is past the end of the string
warning: strslice-strsub.asm(52) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Length too big: 1
warning: strslice-strsub.asm(55) -> strslice-strsub.asm::xstrsub(31): [-Wbuiltin-args]
STRSUB: Length too big: 10

View File

@@ -0,0 +1,48 @@
STRSLICE("ABC",0,1): A
STRSLICE("ABC",1,2): B
STRSLICE("ABC",2,3): C
STRSLICE("ABC",-3,-2): A
STRSLICE("ABC",-2,-1): B
STRSLICE("ABC",-1,-0):
STRSLICE("ABC",-1,3): C
STRSLICE("ABC",1): B
STRSLICE("ABC",-2): B
STRSLICE("ABC",4):
STRSLICE("ABC",-4): AB
STRSLICE("ABC",0,2): AB
STRSLICE("ABC",1,3): BC
STRSLICE("ABC",1,31): BC
STRSLICE("ABC",1,300): BC
STRSLICE("ABC",-4,300): ABC
STRSLICE("ABC",3,3):
STRSLICE("ABC",4,4):
STRSLICE("ABC",3,4):
STRSLICE("カタカナ",0,2): カタ
STRSLICE("カタカナ",2,4): カナ
STRSLICE("カタカナ",2,12): カナ
STRSLICE("g̈",0,1): g
STRSLICE("g̈",0,2): g̈
STRSUB("ABC",1,1): A
STRSUB("ABC",2,1): B
STRSUB("ABC",3,1): C
STRSUB("ABC",-3,1): A
STRSUB("ABC",-2,1): B
STRSUB("ABC",-1,1): C
STRSUB("ABC",2): BC
STRSUB("ABC",0): ABC
STRSUB("ABC",-2): BC
STRSUB("ABC",5):
STRSUB("ABC",-5): ABC
STRSUB("ABC",1,2): AB
STRSUB("ABC",2,2): BC
STRSUB("ABC",2,32): BC
STRSUB("ABC",2,300): BC
STRSUB("ABC",-4,300): ABC
STRSUB("ABC",4,0):
STRSUB("ABC",5,0):
STRSUB("ABC",4,1):
STRSUB("カタカナ",1,2): カタ
STRSUB("カタカナ",3,2): カナ
STRSUB("カタカナ",3,10): カナ
STRSUB("g̈",1,1): g
STRSUB("g̈",1,2): g̈

View File

@@ -1,30 +0,0 @@
SECTION "sec", ROM0
MACRO xstrsub
PRINTLN STRSUB(\#)
ENDM
xstrsub "ABC", 1, 1
xstrsub "ABC", 2, 1
xstrsub "ABC", 3, 1
xstrsub "ABC", -3, 1
xstrsub "ABC", -2, 1
xstrsub "ABC", -1, 1
xstrsub "ABC", 2
xstrsub "ABC", 0
xstrsub "ABC", -2
xstrsub "ABC", 5
xstrsub "ABC", -5
xstrsub "ABC", 1, 2
xstrsub "ABC", 2, 2
xstrsub "ABC", 2, 32
xstrsub "ABC", 2, 300
xstrsub "ABC", -4, 300
xstrsub "ABC", 4, 0
xstrsub "ABC", 5, 0
xstrsub "ABC", 4, 1
xstrsub "カタカナ", 1, 2
xstrsub "カタカナ", 3, 2
xstrsub "カタカナ", 3, 10
xstrsub "g̈", 1, 1
xstrsub "g̈", 1, 2

View File

@@ -1,20 +0,0 @@
warning: strsub.asm(14) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Position starts at 1
warning: strsub.asm(16) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Position 5 is past the end of the string
warning: strsub.asm(17) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Position starts at 1
warning: strsub.asm(20) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Length too big: 32
warning: strsub.asm(21) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Length too big: 300
warning: strsub.asm(22) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Position starts at 1
warning: strsub.asm(22) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Length too big: 300
warning: strsub.asm(24) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Position 5 is past the end of the string
warning: strsub.asm(25) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Length too big: 1
warning: strsub.asm(28) -> strsub.asm::xstrsub(4): [-Wbuiltin-args]
STRSUB: Length too big: 10

View File

@@ -1,24 +0,0 @@
A
B
C
A
B
C
BC
ABC
BC
ABC
AB
BC
BC
BC
ABC
カタ
カナ
カナ
g