From fc9b61422511cc1ed0856fc17fd2242efa7825ed Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Sun, 3 Aug 2025 08:44:06 -0400 Subject: [PATCH] Allow the index of `CHARVAL` to be optional Fixes #1773 --- include/asm/actions.hpp | 1 + man/rgbasm.5 | 2 +- src/asm/actions.cpp | 12 ++++++++++++ src/asm/parser.y | 3 +++ test/asm/charval.asm | 6 ++++++ test/asm/charval.err | 16 ++++++++++------ 6 files changed, 33 insertions(+), 7 deletions(-) diff --git a/include/asm/actions.hpp b/include/asm/actions.hpp index 17470997..60b4f61f 100644 --- a/include/asm/actions.hpp +++ b/include/asm/actions.hpp @@ -33,6 +33,7 @@ std::optional act_ReadFile(std::string const &name, uint32_t maxLen uint32_t act_CharToNum(std::string const &str); uint32_t act_StringToNum(std::vector const &str); +int32_t act_CharVal(std::string const &str); int32_t act_CharVal(std::string const &str, int32_t negIdx); uint8_t act_StringByte(std::string const &str, int32_t negIdx); diff --git a/man/rgbasm.5 b/man/rgbasm.5 index 83d3a046..f7049c71 100644 --- a/man/rgbasm.5 +++ b/man/rgbasm.5 @@ -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 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 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 .Pp Note that indexes count starting from 0 at the beginning, or from -1 at the end. diff --git a/src/asm/actions.cpp b/src/asm/actions.cpp index e6119b77..ba4a539c 100644 --- a/src/asm/actions.cpp +++ b/src/asm/actions.cpp @@ -216,6 +216,18 @@ static uint32_t adjustNegativePos(int32_t pos, size_t len, char const *functionN return static_cast(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) { if (size_t len = charmap_CharSize(str); len != 0) { uint32_t idx = adjustNegativeIndex(negIdx, len, "CHARVAL"); diff --git a/src/asm/parser.y b/src/asm/parser.y index bd9e756f..c25c20c2 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -1527,6 +1527,9 @@ relocexpr_no_str: | OP_CHARVAL LPAREN string COMMA iconst RPAREN { $$.makeNumber(act_CharVal($3, $5)); } + | OP_CHARVAL LPAREN string RPAREN { + $$.makeNumber(act_CharVal($3)); + } | OP_STRBYTE LPAREN string COMMA iconst RPAREN { $$.makeNumber(act_StringByte($3, $5)); } diff --git a/test/asm/charval.asm b/test/asm/charval.asm index 72e5431e..eecc7d2a 100644 --- a/test/asm/charval.asm +++ b/test/asm/charval.asm @@ -5,6 +5,9 @@ charmap "ghi", 5, 6, 7, 8, 9 charmap "jkl", 123, 456, 789 charmap "mno", 123456789 +assert charval("a") == 1 +assert charval("cdef") == 4 + assert charval("a", 0) == 1 assert charval("a", -1) == 1 assert charval("b", 0) == 2 @@ -16,6 +19,9 @@ assert charval("ghi", 2) == charval("ghi", -3) assert charval("jkl", -1) == 789 assert charval("mno", 0) == 123456789 +; errors +assert charval("b") == 0 +assert charval("ab") == 0 assert charval("abc", 0) == 0 assert charval("cd", 1) == 0 assert charval("xyz", 2) == 0 diff --git a/test/asm/charval.err b/test/asm/charval.err index 8087ed90..3080291a 100644 --- a/test/asm/charval.err +++ b/test/asm/charval.err @@ -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" -error: charval.asm(20): +error: charval.asm(26): CHARVAL: No character mapping for "cd" -error: charval.asm(21): +error: charval.asm(27): CHARVAL: No character mapping for "xyz" -warning: charval.asm(22): [-Wbuiltin-args] +warning: charval.asm(28): [-Wbuiltin-args] 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 -Assembly aborted with 3 errors! +Assembly aborted with 5 errors!