From 1dfc1d323131abdbdb442b5ae39e8899d07ac6e0 Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Thu, 4 Sep 2025 13:14:27 -0400 Subject: [PATCH] Factor out `isBinDigit` and `parseHexDigit` utility functions --- include/util.hpp | 3 +++ src/asm/lexer.cpp | 31 ++++++++++++------------------- src/gfx/pal_spec.cpp | 19 +++---------------- src/link/lexer.cpp | 14 +------------- src/util.cpp | 13 +++++++++++++ 5 files changed, 32 insertions(+), 48 deletions(-) diff --git a/include/util.hpp b/include/util.hpp index de10995c..f87cb343 100644 --- a/include/util.hpp +++ b/include/util.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -25,6 +26,8 @@ bool isAlphanumeric(int c); bool startsIdentifier(int c); bool continuesIdentifier(int c); +uint8_t parseHexDigit(int c); + char const *printChar(int c); struct Uppercase { diff --git a/src/asm/lexer.cpp b/src/asm/lexer.cpp index 3deedb71..6e85c7b6 100644 --- a/src/asm/lexer.cpp +++ b/src/asm/lexer.cpp @@ -1009,6 +1009,10 @@ static bool isValidDigit(char c) { return isAlphanumeric(c) || c == '.' || c == '#' || c == '@'; } +static bool isBinDigit(int c) { + return c == '0' || c == '1' || c == options.binDigits[0] || c == options.binDigits[1]; +} + static bool checkDigitErrors(char const *digits, size_t n, char const *type) { for (size_t i = 0; i < n; ++i) { char c = digits[i]; @@ -1074,10 +1078,7 @@ static uint32_t readBinaryNumber(char const *prefix) { if (value > (UINT32_MAX - bit) / 2) { warning(WARNING_LARGE_CONSTANT, "Integer constant is too large"); // Discard any additional digits - skipChars([](int d) { - return d == '0' || d == '1' || d == options.binDigits[0] - || d == options.binDigits[1] || d == '_'; - }); + skipChars([](int d) { return isBinDigit(d) || d == '_'; }); return 0; } value = value * 2 + bit; @@ -1107,11 +1108,10 @@ static uint32_t readOctalNumber(char const *prefix) { continue; } - if (isOctDigit(c)) { - c = c - '0'; - } else { + if (!isOctDigit(c)) { break; } + c = c - '0'; empty = false; nonDigit = false; @@ -1148,11 +1148,10 @@ static uint32_t readDecimalNumber(int initial) { continue; } - if (isDigit(c)) { - c = c - '0'; - } else { + if (!isDigit(c)) { break; } + c = c - '0'; nonDigit = false; if (value > (UINT32_MAX - c) / 10) { @@ -1185,15 +1184,10 @@ static uint32_t readHexNumber(char const *prefix) { continue; } - if (c >= 'a' && c <= 'f') { - c = c - 'a' + 10; - } else if (c >= 'A' && c <= 'F') { - c = c - 'A' + 10; - } else if (isDigit(c)) { - c = c - '0'; - } else { + if (!isHexDigit(c)) { break; } + c = parseHexDigit(c); empty = false; nonDigit = false; @@ -1834,8 +1828,7 @@ static Token yylex_NORMAL() { case '%': // Either %=, MOD, or a binary constant c = peek(); - if (c == '0' || c == '1' || c == options.binDigits[0] || c == options.binDigits[1] - || c == '_') { + if (isBinDigit(c) || c == '_') { return Token(T_(NUMBER), readBinaryNumber("'%'")); } return oneOrTwo('=', T_(POP_MODEQ), T_(OP_MOD)); diff --git a/src/gfx/pal_spec.cpp b/src/gfx/pal_spec.cpp index 56c5eaec..534ac57c 100644 --- a/src/gfx/pal_spec.cpp +++ b/src/gfx/pal_spec.cpp @@ -37,24 +37,11 @@ static void skipBlankSpace(Str const &str, size_t &pos) { pos = std::min(str.find_first_not_of(" \t"sv, pos), str.length()); } -static constexpr uint8_t nibble(char c) { - if (c >= 'a') { - assume(c <= 'f'); - return c - 'a' + 10; - } else if (c >= 'A') { - assume(c <= 'F'); - return c - 'A' + 10; - } else { - assume(isDigit(c)); - return c - '0'; - } +static uint8_t toHex(char c1, char c2) { + return parseHexDigit(c1) * 16 + parseHexDigit(c2); } -static constexpr uint8_t toHex(char c1, char c2) { - return nibble(c1) * 16 + nibble(c2); -} - -static constexpr uint8_t singleToHex(char c) { +static uint8_t singleToHex(char c) { return toHex(c, c); } diff --git a/src/link/lexer.cpp b/src/link/lexer.cpp index ec602231..dc42a671 100644 --- a/src/link/lexer.cpp +++ b/src/link/lexer.cpp @@ -108,7 +108,7 @@ static yy::parser::symbol_type parseDecNumber(int c) { } static bool isBinDigit(int c) { - return c >= '0' && c <= '1'; + return c == '0' || c == '1'; } static yy::parser::symbol_type parseBinNumber(char const *prefix) { @@ -149,18 +149,6 @@ static yy::parser::symbol_type parseOctNumber(char const *prefix) { return yy::parser::make_number(number); } -static uint8_t parseHexDigit(int c) { - if (isDigit(c)) { - return c - '0'; - } else if (c >= 'A' && c <= 'F') { - return c - 'A' + 10; - } else if (c >= 'a' && c <= 'f') { - return c - 'a' + 10; - } else { - unreachable_(); // LCOV_EXCL_LINE - } -} - static yy::parser::symbol_type parseHexNumber(char const *prefix) { LexerStackEntry &context = lexerStack.back(); int c = context.file.sgetc(); diff --git a/src/util.cpp b/src/util.cpp index 90410fbe..c24d3249 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -5,6 +5,8 @@ #include #include +#include "helpers.hpp" // assume + bool isNewline(int c) { return c == '\r' || c == '\n'; } @@ -51,6 +53,17 @@ bool continuesIdentifier(int c) { return startsIdentifier(c) || isDigit(c) || c == '#' || c == '$' || c == '@'; } +uint8_t parseHexDigit(int c) { + if (c >= 'A' && c <= 'F') { + return c - 'A' + 10; + } else if (c >= 'a' && c <= 'f') { + return c - 'a' + 10; + } else { + assume(isDigit(c)); + return c - '0'; + } +} + char const *printChar(int c) { // "'A'" + '\0': 4 bytes // "'\\n'" + '\0': 5 bytes