mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-24 03:52:08 +00:00
Implement CHARVAL function (#1701)
This commit is contained in:
@@ -189,7 +189,7 @@ bool charmap_HasChar(std::string const &mapping) {
|
||||
return charmap.nodes[nodeIdx].isTerminal();
|
||||
}
|
||||
|
||||
size_t charmap_CharSize(std::string const &mapping) {
|
||||
static CharmapNode const *charmapEntry(std::string const &mapping) {
|
||||
Charmap const &charmap = *currentCharmap;
|
||||
size_t nodeIdx = 0;
|
||||
|
||||
@@ -197,12 +197,24 @@ size_t charmap_CharSize(std::string const &mapping) {
|
||||
nodeIdx = charmap.nodes[nodeIdx].next[static_cast<uint8_t>(c)];
|
||||
|
||||
if (!nodeIdx) {
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CharmapNode const &node = charmap.nodes[nodeIdx];
|
||||
return node.isTerminal() ? node.value.size() : 0;
|
||||
return &charmap.nodes[nodeIdx];
|
||||
}
|
||||
|
||||
size_t charmap_CharSize(std::string const &mapping) {
|
||||
CharmapNode const *node = charmapEntry(mapping);
|
||||
return node && node->isTerminal() ? node->value.size() : 0;
|
||||
}
|
||||
|
||||
std::optional<int32_t> charmap_CharValue(std::string const &mapping, size_t idx) {
|
||||
if (CharmapNode const *node = charmapEntry(mapping);
|
||||
node && node->isTerminal() && idx < node->value.size()) {
|
||||
return node->value[idx];
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::vector<int32_t> charmap_Convert(std::string const &input) {
|
||||
|
||||
@@ -259,6 +259,7 @@ static std::unordered_map<std::string, int, CaseInsensitive, CaseInsensitive> ke
|
||||
{"CHARLEN", T_(OP_CHARLEN) },
|
||||
{"CHARSIZE", T_(OP_CHARSIZE) },
|
||||
{"CHARSUB", T_(OP_CHARSUB) },
|
||||
{"CHARVAL", T_(OP_CHARVAL) },
|
||||
{"INCHARMAP", T_(OP_INCHARMAP) },
|
||||
{"REVCHAR", T_(OP_REVCHAR) },
|
||||
|
||||
|
||||
@@ -287,6 +287,7 @@
|
||||
%token OP_CHARLEN "CHARLEN"
|
||||
%token OP_CHARSIZE "CHARSIZE"
|
||||
%token OP_CHARSUB "CHARSUB"
|
||||
%token OP_CHARVAL "CHARVAL"
|
||||
%token OP_COS "COS"
|
||||
%token OP_DEF "DEF"
|
||||
%token OP_FDIV "FDIV"
|
||||
@@ -1580,6 +1581,24 @@ relocexpr_no_str:
|
||||
}
|
||||
$$.makeNumber(charSize);
|
||||
}
|
||||
| OP_CHARVAL LPAREN string COMMA iconst RPAREN {
|
||||
if (size_t len = charmap_CharSize($3); len != 0) {
|
||||
uint32_t idx = adjustNegativeIndex($5, len, "CHARVAL");
|
||||
if (std::optional<int32_t> val = charmap_CharValue($3, idx); val.has_value()) {
|
||||
$$.makeNumber(*val);
|
||||
} else {
|
||||
warning(
|
||||
WARNING_BUILTIN_ARG,
|
||||
"CHARVAL: Index %" PRIu32 " is past the end of the character mapping\n",
|
||||
idx
|
||||
);
|
||||
$$.makeNumber(0);
|
||||
}
|
||||
} else {
|
||||
::error("CHARVAL: No character mapping for \"%s\"\n", $3.c_str());
|
||||
$$.makeNumber(0);
|
||||
}
|
||||
}
|
||||
| LPAREN relocexpr RPAREN {
|
||||
$$ = std::move($2);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user