mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Factor out isBinDigit and parseHexDigit utility functions
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
@@ -25,6 +26,8 @@ bool isAlphanumeric(int c);
|
|||||||
bool startsIdentifier(int c);
|
bool startsIdentifier(int c);
|
||||||
bool continuesIdentifier(int c);
|
bool continuesIdentifier(int c);
|
||||||
|
|
||||||
|
uint8_t parseHexDigit(int c);
|
||||||
|
|
||||||
char const *printChar(int c);
|
char const *printChar(int c);
|
||||||
|
|
||||||
struct Uppercase {
|
struct Uppercase {
|
||||||
|
|||||||
@@ -1009,6 +1009,10 @@ static bool isValidDigit(char c) {
|
|||||||
return isAlphanumeric(c) || c == '.' || c == '#' || 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) {
|
static bool checkDigitErrors(char const *digits, size_t n, char const *type) {
|
||||||
for (size_t i = 0; i < n; ++i) {
|
for (size_t i = 0; i < n; ++i) {
|
||||||
char c = digits[i];
|
char c = digits[i];
|
||||||
@@ -1074,10 +1078,7 @@ static uint32_t readBinaryNumber(char const *prefix) {
|
|||||||
if (value > (UINT32_MAX - bit) / 2) {
|
if (value > (UINT32_MAX - bit) / 2) {
|
||||||
warning(WARNING_LARGE_CONSTANT, "Integer constant is too large");
|
warning(WARNING_LARGE_CONSTANT, "Integer constant is too large");
|
||||||
// Discard any additional digits
|
// Discard any additional digits
|
||||||
skipChars([](int d) {
|
skipChars([](int d) { return isBinDigit(d) || d == '_'; });
|
||||||
return d == '0' || d == '1' || d == options.binDigits[0]
|
|
||||||
|| d == options.binDigits[1] || d == '_';
|
|
||||||
});
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
value = value * 2 + bit;
|
value = value * 2 + bit;
|
||||||
@@ -1107,11 +1108,10 @@ static uint32_t readOctalNumber(char const *prefix) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isOctDigit(c)) {
|
if (!isOctDigit(c)) {
|
||||||
c = c - '0';
|
|
||||||
} else {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
c = c - '0';
|
||||||
empty = false;
|
empty = false;
|
||||||
nonDigit = false;
|
nonDigit = false;
|
||||||
|
|
||||||
@@ -1148,11 +1148,10 @@ static uint32_t readDecimalNumber(int initial) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDigit(c)) {
|
if (!isDigit(c)) {
|
||||||
c = c - '0';
|
|
||||||
} else {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
c = c - '0';
|
||||||
nonDigit = false;
|
nonDigit = false;
|
||||||
|
|
||||||
if (value > (UINT32_MAX - c) / 10) {
|
if (value > (UINT32_MAX - c) / 10) {
|
||||||
@@ -1185,15 +1184,10 @@ static uint32_t readHexNumber(char const *prefix) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c >= 'a' && c <= 'f') {
|
if (!isHexDigit(c)) {
|
||||||
c = c - 'a' + 10;
|
|
||||||
} else if (c >= 'A' && c <= 'F') {
|
|
||||||
c = c - 'A' + 10;
|
|
||||||
} else if (isDigit(c)) {
|
|
||||||
c = c - '0';
|
|
||||||
} else {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
c = parseHexDigit(c);
|
||||||
empty = false;
|
empty = false;
|
||||||
nonDigit = false;
|
nonDigit = false;
|
||||||
|
|
||||||
@@ -1834,8 +1828,7 @@ static Token yylex_NORMAL() {
|
|||||||
|
|
||||||
case '%': // Either %=, MOD, or a binary constant
|
case '%': // Either %=, MOD, or a binary constant
|
||||||
c = peek();
|
c = peek();
|
||||||
if (c == '0' || c == '1' || c == options.binDigits[0] || c == options.binDigits[1]
|
if (isBinDigit(c) || c == '_') {
|
||||||
|| c == '_') {
|
|
||||||
return Token(T_(NUMBER), readBinaryNumber("'%'"));
|
return Token(T_(NUMBER), readBinaryNumber("'%'"));
|
||||||
}
|
}
|
||||||
return oneOrTwo('=', T_(POP_MODEQ), T_(OP_MOD));
|
return oneOrTwo('=', T_(POP_MODEQ), T_(OP_MOD));
|
||||||
|
|||||||
@@ -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());
|
pos = std::min(str.find_first_not_of(" \t"sv, pos), str.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr uint8_t nibble(char c) {
|
static uint8_t toHex(char c1, char c2) {
|
||||||
if (c >= 'a') {
|
return parseHexDigit(c1) * 16 + parseHexDigit(c2);
|
||||||
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 constexpr uint8_t toHex(char c1, char c2) {
|
static uint8_t singleToHex(char c) {
|
||||||
return nibble(c1) * 16 + nibble(c2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr uint8_t singleToHex(char c) {
|
|
||||||
return toHex(c, c);
|
return toHex(c, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ static yy::parser::symbol_type parseDecNumber(int c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool isBinDigit(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) {
|
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);
|
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) {
|
static yy::parser::symbol_type parseHexNumber(char const *prefix) {
|
||||||
LexerStackEntry &context = lexerStack.back();
|
LexerStackEntry &context = lexerStack.back();
|
||||||
int c = context.file.sgetc();
|
int c = context.file.sgetc();
|
||||||
|
|||||||
13
src/util.cpp
13
src/util.cpp
@@ -5,6 +5,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "helpers.hpp" // assume
|
||||||
|
|
||||||
bool isNewline(int c) {
|
bool isNewline(int c) {
|
||||||
return c == '\r' || c == '\n';
|
return c == '\r' || c == '\n';
|
||||||
}
|
}
|
||||||
@@ -51,6 +53,17 @@ bool continuesIdentifier(int c) {
|
|||||||
return startsIdentifier(c) || isDigit(c) || c == '#' || c == '$' || 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) {
|
char const *printChar(int c) {
|
||||||
// "'A'" + '\0': 4 bytes
|
// "'A'" + '\0': 4 bytes
|
||||||
// "'\\n'" + '\0': 5 bytes
|
// "'\\n'" + '\0': 5 bytes
|
||||||
|
|||||||
Reference in New Issue
Block a user