diff --git a/man/rgbasm.5 b/man/rgbasm.5 index 4f84a7a2..fb92d242 100644 --- a/man/rgbasm.5 +++ b/man/rgbasm.5 @@ -653,12 +653,14 @@ The following functions take varying operands, and return strings: .El .Pp The following functions operate on string expressions, but return integers: -.Bl -column "STRRFIND(str, sub)" +.Bl -column "STRSTARTS(str, prefix)" .It Sy Name Ta Sy Operation .It Fn STRLEN str Ta Returns the number of characters in Ar str . .It Fn STRCMP str1 str2 Ta Compares Ar str1 No and Ar str2 No according to ASCII ordering of their characters. Returns -1 if Ar str1 No is lower than Ar str2 Ns , 1 if Ar str1 No is greater than Ar str2 Ns , or 0 if they match. .It Fn STRFIND str sub Ta Returns the first index of Ar sub No in Ar str Ns , or -1 if it's not present. .It Fn STRRFIND str sub Ta Returns the last index of Ar sub No in Ar str Ns , or -1 if it's not present. +.It Fn STRSTARTS str prefix Ta Returns 1 if Ar str No starts with Ar prefix Ns , or 0 otherwise. +.It Fn STRENDS str suffix Ta Returns 1 if Ar str No ends with Ar suffix Ns , or 0 otherwise. .It Fn BYTELEN str Ta Returns the number of bytes in Ar str . Pq Non-ASCII characters can be multiple bytes. .It Fn STRBYTE str idx Ta Returns the byte value at Ar idx No in Ar str . .It Fn INCHARMAP str Ta Returns 1 if Ar str No has an entry in the current charmap, or 0 otherwise. diff --git a/src/asm/lexer.cpp b/src/asm/lexer.cpp index cd8082c8..8d6dc4b8 100644 --- a/src/asm/lexer.cpp +++ b/src/asm/lexer.cpp @@ -180,6 +180,7 @@ static UpperMap const keywords{ {"STRCAT", T_(OP_STRCAT) }, {"STRCHAR", T_(OP_STRCHAR) }, {"STRCMP", T_(OP_STRCMP) }, + {"STRENDS", T_(OP_STRENDS) }, {"STRFIND", T_(OP_STRFIND) }, {"STRFMT", T_(OP_STRFMT) }, {"STRIN", T_(OP_STRIN) }, @@ -189,6 +190,7 @@ static UpperMap const keywords{ {"STRRIN", T_(OP_STRRIN) }, {"STRRPL", T_(OP_STRRPL) }, {"STRSLICE", T_(OP_STRSLICE) }, + {"STRSTARTS", T_(OP_STRSTARTS) }, {"STRSUB", T_(OP_STRSUB) }, {"STRUPR", T_(OP_STRUPR) }, diff --git a/src/asm/parser.y b/src/asm/parser.y index dbe8c6e4..27613a86 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -296,6 +296,7 @@ %token OP_STRCAT "STRCAT" %token OP_STRCHAR "STRCHAR" %token OP_STRCMP "STRCMP" +%token OP_STRENDS "STRENDS" %token OP_STRFIND "STRFIND" %token OP_STRFMT "STRFMT" %token OP_STRIN "STRIN" @@ -305,6 +306,7 @@ %token OP_STRRIN "STRRIN" %token OP_STRRPL "STRRPL" %token OP_STRSLICE "STRSLICE" +%token OP_STRSTARTS "STRSTARTS" %token OP_STRSUB "STRSUB" %token OP_STRUPR "STRUPR" %token OP_TAN "TAN" @@ -1480,6 +1482,12 @@ relocexpr_no_str: size_t pos = $3.rfind($5); $$.makeNumber(pos != std::string::npos ? pos : -1); } + | OP_STRSTARTS LPAREN string COMMA string RPAREN { + $$.makeNumber($3.starts_with($5)); + } + | OP_STRENDS LPAREN string COMMA string RPAREN { + $$.makeNumber($3.ends_with($5)); + } | OP_STRIN LPAREN string COMMA string RPAREN { warning(WARNING_OBSOLETE, "`STRIN` is deprecated; use 0-indexed `STRFIND` instead"); size_t pos = $3.find($5); diff --git a/test/asm/strstarts-strends.asm b/test/asm/strstarts-strends.asm new file mode 100644 index 00000000..7b476553 --- /dev/null +++ b/test/asm/strstarts-strends.asm @@ -0,0 +1,13 @@ + + assert STRSTARTS("string", "str") + assert STRENDS("string", "ing") + assert !STRSTARTS("string", "stringing") + assert !STRENDS("string", "bowstring") + assert STRSTARTS("string", "string") + assert STRENDS("string", "string") + assert !STRSTARTS("", "prefix") + assert !STRENDS("", "suffix") + assert STRSTARTS("string", "") + assert STRENDS("string", "") + assert STRSTARTS("", "") + assert STRENDS("", "")