Allow the index of CHARVAL to be optional

Fixes #1773
This commit is contained in:
Rangi42
2025-08-03 08:44:06 -04:00
parent 543b7fa6c2
commit fc9b614225
6 changed files with 33 additions and 7 deletions

View File

@@ -33,6 +33,7 @@ std::optional<std::string> act_ReadFile(std::string const &name, uint32_t maxLen
uint32_t act_CharToNum(std::string const &str); uint32_t act_CharToNum(std::string const &str);
uint32_t act_StringToNum(std::vector<int32_t> const &str); uint32_t act_StringToNum(std::vector<int32_t> const &str);
int32_t act_CharVal(std::string const &str);
int32_t act_CharVal(std::string const &str, int32_t negIdx); int32_t act_CharVal(std::string const &str, int32_t negIdx);
uint8_t act_StringByte(std::string const &str, int32_t negIdx); uint8_t act_StringByte(std::string const &str, int32_t negIdx);

View File

@@ -615,7 +615,7 @@ The following functions operate on string expressions, but return integers.
.It Fn CHARLEN str Ta Returns the number of charmap entries in Ar str No with the current charmap. .It Fn CHARLEN str Ta Returns the number of charmap entries in Ar str No with the current charmap.
.It Fn CHARCMP str1 str2 Ta Compares Ar str1 No and Ar str2 No according to their charmap entry values with the current charmap. 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 CHARCMP str1 str2 Ta Compares Ar str1 No and Ar str2 No according to their charmap entry values with the current charmap. 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 CHARSIZE char Ta Returns how many values are in the charmap entry for Ar char No with the current charmap. .It Fn CHARSIZE char Ta Returns how many values are in the charmap entry for Ar char No with the current charmap.
.It Fn CHARVAL char idx Ta Returns the value at Ar idx No of the charmap entry for Ar char . .It Fn CHARVAL char idx Ta Returns the value at Ar idx No of the charmap entry for Ar char . If Ar idx No is not specified, Ar char No must have a single value, which is returned.
.El .El
.Pp .Pp
Note that indexes count starting from 0 at the beginning, or from -1 at the end. Note that indexes count starting from 0 at the beginning, or from -1 at the end.

View File

@@ -216,6 +216,18 @@ static uint32_t adjustNegativePos(int32_t pos, size_t len, char const *functionN
return static_cast<uint32_t>(pos); return static_cast<uint32_t>(pos);
} }
int32_t act_CharVal(std::string const &str) {
if (size_t len = charmap_CharSize(str); len == 0) {
error("CHARVAL: No character mapping for \"%s\"", str.c_str());
return 0;
} else if (len != 1) {
error("CHARVAL: Character mapping for \"%s\" must have a single value", str.c_str());
return 0;
} else {
return *charmap_CharValue(str, 0);
}
}
int32_t act_CharVal(std::string const &str, int32_t negIdx) { int32_t act_CharVal(std::string const &str, int32_t negIdx) {
if (size_t len = charmap_CharSize(str); len != 0) { if (size_t len = charmap_CharSize(str); len != 0) {
uint32_t idx = adjustNegativeIndex(negIdx, len, "CHARVAL"); uint32_t idx = adjustNegativeIndex(negIdx, len, "CHARVAL");

View File

@@ -1527,6 +1527,9 @@ relocexpr_no_str:
| OP_CHARVAL LPAREN string COMMA iconst RPAREN { | OP_CHARVAL LPAREN string COMMA iconst RPAREN {
$$.makeNumber(act_CharVal($3, $5)); $$.makeNumber(act_CharVal($3, $5));
} }
| OP_CHARVAL LPAREN string RPAREN {
$$.makeNumber(act_CharVal($3));
}
| OP_STRBYTE LPAREN string COMMA iconst RPAREN { | OP_STRBYTE LPAREN string COMMA iconst RPAREN {
$$.makeNumber(act_StringByte($3, $5)); $$.makeNumber(act_StringByte($3, $5));
} }

View File

@@ -5,6 +5,9 @@ charmap "ghi", 5, 6, 7, 8, 9
charmap "jkl", 123, 456, 789 charmap "jkl", 123, 456, 789
charmap "mno", 123456789 charmap "mno", 123456789
assert charval("a") == 1
assert charval("cdef") == 4
assert charval("a", 0) == 1 assert charval("a", 0) == 1
assert charval("a", -1) == 1 assert charval("a", -1) == 1
assert charval("b", 0) == 2 assert charval("b", 0) == 2
@@ -16,6 +19,9 @@ assert charval("ghi", 2) == charval("ghi", -3)
assert charval("jkl", -1) == 789 assert charval("jkl", -1) == 789
assert charval("mno", 0) == 123456789 assert charval("mno", 0) == 123456789
; errors
assert charval("b") == 0
assert charval("ab") == 0
assert charval("abc", 0) == 0 assert charval("abc", 0) == 0
assert charval("cd", 1) == 0 assert charval("cd", 1) == 0
assert charval("xyz", 2) == 0 assert charval("xyz", 2) == 0

View File

@@ -1,11 +1,15 @@
error: charval.asm(19): error: charval.asm(23):
CHARVAL: Character mapping for "b" must have a single value
error: charval.asm(24):
CHARVAL: No character mapping for "ab"
error: charval.asm(25):
CHARVAL: No character mapping for "abc" CHARVAL: No character mapping for "abc"
error: charval.asm(20): error: charval.asm(26):
CHARVAL: No character mapping for "cd" CHARVAL: No character mapping for "cd"
error: charval.asm(21): error: charval.asm(27):
CHARVAL: No character mapping for "xyz" CHARVAL: No character mapping for "xyz"
warning: charval.asm(22): [-Wbuiltin-args] warning: charval.asm(28): [-Wbuiltin-args]
CHARVAL: Index starts at 0 CHARVAL: Index starts at 0
warning: charval.asm(23): [-Wbuiltin-args] warning: charval.asm(29): [-Wbuiltin-args]
CHARVAL: Index 10 is past the end of the character mapping CHARVAL: Index 10 is past the end of the character mapping
Assembly aborted with 3 errors! Assembly aborted with 5 errors!