Implement STRRIN, like STRIN but searching from the right

This commit is contained in:
Rangi
2020-12-09 20:08:26 -05:00
committed by Eldred Habert
parent 3e4c2fe712
commit 58739b0bf2
6 changed files with 40 additions and 2 deletions

View File

@@ -195,6 +195,7 @@ static struct KeywordMapping {
{"STRCMP", T_OP_STRCMP},
{"STRIN", T_OP_STRIN},
{"STRRIN", T_OP_STRRIN},
{"STRSUB", T_OP_STRSUB},
{"STRLEN", T_OP_STRLEN},
{"STRCAT", T_OP_STRCAT},
@@ -472,7 +473,7 @@ struct KeywordDictNode {
uint16_t children[0x60 - ' '];
struct KeywordMapping const *keyword;
/* Since the keyword structure is invariant, the min number of nodes is known at compile time */
} keywordDict[338] = {0}; /* Make sure to keep this correct when adding keywords! */
} keywordDict[341] = {0}; /* Make sure to keep this correct when adding keywords! */
/* Convert a char into its index into the dict */
static inline uint8_t dictIndex(char c)

View File

@@ -54,6 +54,21 @@ static uint32_t str2int2(uint8_t *s, int32_t length)
return r;
}
static char *strrstr(char *s1, char *s2)
{
size_t len1 = strlen(s1);
size_t len2 = strlen(s2);
if (len2 > len1)
return NULL;
for (char *p = s1 + len1 - len2; p >= s1; p--)
if (!strncmp(p, s2, len2))
return p;
return NULL;
}
static size_t strlenUTF8(const char *s)
{
size_t len = 0;
@@ -233,6 +248,7 @@ static inline void failAssertMsg(enum AssertionType type, char const *msg)
%left T_OP_STRCMP
%left T_OP_STRIN
%left T_OP_STRRIN
%left T_OP_STRSUB
%left T_OP_STRLEN
%left T_OP_STRCAT
@@ -999,6 +1015,11 @@ relocexpr_no_str : scoped_id { rpn_Symbol(&$$, $1); }
rpn_Number(&$$, p ? p - $3 + 1 : 0);
}
| T_OP_STRRIN T_LPAREN string T_COMMA string T_RPAREN {
char *p = strrstr($3, $5);
rpn_Number(&$$, p ? p - $3 + 1 : 0);
}
| T_OP_STRLEN T_LPAREN string T_RPAREN {
rpn_Number(&$$, strlenUTF8($3));
}

View File

@@ -282,7 +282,8 @@ Most of them return a string, however some of these functions actually return an
.It Fn STRLEN string Ta Returns the number of characters in Ar string .
.It Fn STRCAT str1 str2 Ta Appends Ar str2 No to Ar str1 .
.It Fn STRCMP str1 str2 Ta Returns -1 if Ar str1 No is alphabetically lower than Ar str2 No , zero if they match, 1 if Ar str1 No is greater than Ar str2 .
.It Fn STRIN str1 str2 Ta Returns the position of Ar str2 No in Ar str1 No or zero if it's not present Pq first character is position 1 .
.It Fn STRIN str1 str2 Ta Returns the first position of Ar str2 No in Ar str1 No or zero if it's not present Pq first character is position 1 .
.It Fn STRRIN str1 str2 Ta Returns the last position of Ar str2 No in Ar str1 No or zero if it's not present Pq first character is position 1 .
.It Fn STRSUB str pos len Ta Returns a substring from Ar str No starting at Ar pos Po first character is position 1 Pc and Ar len No characters long.
.It Fn STRUPR str Ta Converts all characters in Ar str No to capitals and returns the new string.
.It Fn STRLWR str Ta Converts all characters in Ar str No to lower case and returns the new string.

15
test/asm/strin-strrin.asm Normal file
View File

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

View File

View File