Reduce deep nesting some more

This commit is contained in:
Rangi42
2025-07-19 13:44:58 -04:00
parent 7086b8aeff
commit bf69043a1d
6 changed files with 167 additions and 174 deletions

View File

@@ -131,8 +131,8 @@ std::string Diagnostics<L, W>::processWarningFlag(char const *flag) {
auto [flagState, param] = getInitialWarningState(rootFlag); auto [flagState, param] = getInitialWarningState(rootFlag);
// Try to match the flag against a parametric warning // Try to match the flag against a parametric warning
// If there was an equals sign, it will have set `param`; if not, `param` will be 0, which // If there was an equals sign, it will have set `param`; if not, `param` will be 0,
// applies to all levels // which applies to all levels
for (ParamWarning<W> const &paramWarning : paramWarnings) { for (ParamWarning<W> const &paramWarning : paramWarnings) {
W baseID = paramWarning.firstID; W baseID = paramWarning.firstID;
uint8_t maxParam = paramWarning.lastID - baseID + 1; uint8_t maxParam = paramWarning.lastID - baseID + 1;
@@ -173,8 +173,11 @@ std::string Diagnostics<L, W>::processWarningFlag(char const *flag) {
return rootFlag; return rootFlag;
} }
// Try to match against a non-parametric warning, unless there was an equals sign if (param.has_value()) {
if (!param.has_value()) { warnx("Unknown warning flag parameter \"%s\"", rootFlag.c_str());
return rootFlag;
}
// Try to match against a "meta" warning // Try to match against a "meta" warning
for (WarningFlag<L> const &metaWarning : metaWarnings) { for (WarningFlag<L> const &metaWarning : metaWarnings) {
if (rootFlag != metaWarning.name) { if (rootFlag != metaWarning.name) {
@@ -190,16 +193,15 @@ std::string Diagnostics<L, W>::processWarningFlag(char const *flag) {
return rootFlag; return rootFlag;
} }
// Try to match the flag against a "normal" flag // Try to match against a "normal" flag
for (W id : EnumSeq(W::NB_PLAIN_WARNINGS)) { for (W id : EnumSeq(W::NB_PLAIN_WARNINGS)) {
if (rootFlag == warningFlags[id].name) { if (rootFlag == warningFlags[id].name) {
state.flagStates[id].update(flagState); state.flagStates[id].update(flagState);
return rootFlag; return rootFlag;
} }
} }
}
warnx("Unknown warning flag \"%s\"", flag); warnx("Unknown warning flag \"%s\"", rootFlag.c_str());
return rootFlag; return rootFlag;
} }

View File

@@ -41,11 +41,9 @@ struct Charmap {
auto [nodeIdx, mapping] = std::move(prefixes.top()); auto [nodeIdx, mapping] = std::move(prefixes.top());
prefixes.pop(); prefixes.pop();
CharmapNode const &node = nodes[nodeIdx]; CharmapNode const &node = nodes[nodeIdx];
if (node.isTerminal()) { if (node.isTerminal() && !callback(nodeIdx, mapping)) {
if (!callback(nodeIdx, mapping)) {
return false; return false;
} }
}
for (unsigned c = 0; c < std::size(node.next); c++) { for (unsigned c = 0; c < std::size(node.next); c++) {
if (size_t nextIdx = node.next[c]; nextIdx) { if (size_t nextIdx = node.next[c]; nextIdx) {
prefixes.push({nextIdx, mapping + static_cast<char>(c)}); prefixes.push({nextIdx, mapping + static_cast<char>(c)});

View File

@@ -641,7 +641,6 @@ static uint32_t readBracketedMacroArgNum() {
} }
std::string symName; std::string symName;
for (; continuesIdentifier(c); c = peek()) { for (; continuesIdentifier(c); c = peek()) {
symName += c; symName += c;
shiftChar(); shiftChar();
@@ -883,14 +882,21 @@ static void shiftChar() {
static int nextChar() { static int nextChar() {
int c = peek(); int c = peek();
// If not at EOF, advance read position
if (c != EOF) { if (c != EOF) {
shiftChar(); shiftChar();
} }
return c; return c;
} }
template<typename P>
static int skipChars(P predicate) {
int c = peek();
for (; predicate(c); c = peek()) {
shiftChar();
}
return c;
}
static void handleCRLF(int c) { static void handleCRLF(int c) {
if (c == '\r' && peek() == '\n') { if (c == '\r' && peek() == '\n') {
shiftChar(); shiftChar();
@@ -1032,10 +1038,7 @@ static uint32_t readFractionalPart(uint32_t integer) {
if (divisor > (UINT32_MAX - (c - '0')) / 10) { if (divisor > (UINT32_MAX - (c - '0')) / 10) {
warning(WARNING_LARGE_CONSTANT, "Precision of fixed-point constant is too large"); warning(WARNING_LARGE_CONSTANT, "Precision of fixed-point constant is too large");
// Discard any additional digits // Discard any additional digits
shiftChar(); skipChars([](int d) { return (d >= '0' && d <= '9') || d == '_'; });
while (c = peek(), (c >= '0' && c <= '9') || c == '_') {
shiftChar();
}
break; break;
} }
value = value * 10 + (c - '0'); value = value * 10 + (c - '0');
@@ -1443,8 +1446,24 @@ static void appendExpandedString(std::string &str, std::string const &expanded)
static void appendCharInLiteral(std::string &str, int c) { static void appendCharInLiteral(std::string &str, int c) {
bool rawMode = lexerState->mode == LEXER_RAW; bool rawMode = lexerState->mode == LEXER_RAW;
switch (c) { // Symbol interpolation
case '\\': // Character escape or macro arg if (c == '{') {
// We'll be exiting the string/character scope, so re-enable expansions
// (Not interpolations, since they're handled by the function itself...)
lexerState->disableMacroArgs = false;
if (std::shared_ptr<std::string> interpolation = readInterpolation(0); interpolation) {
appendExpandedString(str, *interpolation);
}
lexerState->disableMacroArgs = true;
return;
}
// Regular characters will just get copied
if (c != '\\') {
str += c;
return;
}
c = peek(); c = peek();
switch (c) { switch (c) {
// Character escape // Character escape
@@ -1518,22 +1537,6 @@ static void appendCharInLiteral(std::string &str, int c) {
shiftChar(); shiftChar();
break; break;
} }
break;
case '{': // Symbol interpolation
// We'll be exiting the string/character scope, so re-enable expansions
// (Not interpolations, since they're handled by the function itself...)
lexerState->disableMacroArgs = false;
if (std::shared_ptr<std::string> interpolation = readInterpolation(0); interpolation) {
appendExpandedString(str, *interpolation);
}
lexerState->disableMacroArgs = true;
break;
default: // Regular characters will just get copied
str += c;
break;
}
} }
static void readString(std::string &str, bool rawString) { static void readString(std::string &str, bool rawString) {
@@ -1583,8 +1586,17 @@ static void readString(std::string &str, bool rawString) {
continue; continue;
} }
if (c != '"') {
// Append the character or handle special ones
if (rawString) {
str += c;
} else {
appendCharInLiteral(str, c);
}
continue;
}
// Close the string and return if it's terminated // Close the string and return if it's terminated
if (c == '"') {
if (!multiline) { if (!multiline) {
if (rawMode) { if (rawMode) {
str += c; str += c;
@@ -1607,14 +1619,6 @@ static void readString(std::string &str, bool rawString) {
} }
return; return;
} }
// Append the character or handle special ones
if (rawString) {
str += c;
} else {
appendCharInLiteral(str, c);
}
}
} }
static void readCharacter(std::string &str) { static void readCharacter(std::string &str) {
@@ -1629,28 +1633,26 @@ static void readCharacter(std::string &str) {
} }
for (;;) { for (;;) {
int c = peek(); switch (int c = peek(); c) {
case '\r':
case '\n':
case EOF:
// '\r', '\n' or EOF ends a character early // '\r', '\n' or EOF ends a character early
if (c == EOF || c == '\r' || c == '\n') {
error("Unterminated character"); error("Unterminated character");
return; return;
} case '\'':
// We'll be staying in the character, so we can safely consume the char
shiftChar();
// Close the character and return if it's terminated // Close the character and return if it's terminated
if (c == '\'') { shiftChar();
if (rawMode) { if (rawMode) {
str += c; str += c;
} }
return; return;
} default:
// Append the character or handle special ones // Append the character or handle special ones
shiftChar();
appendCharInLiteral(str, c); appendCharInLiteral(str, c);
} }
}
} }
// Lexer core // Lexer core
@@ -2347,14 +2349,7 @@ static Token yylex_SKIP_TO_ENDR() {
} }
} }
// Skip whitespace c = skipChars(isWhitespace);
for (;;) {
c = peek();
if (!isWhitespace(c)) {
break;
}
shiftChar();
}
if (!startsIdentifier(c)) { if (!startsIdentifier(c)) {
continue; continue;
@@ -2489,19 +2484,18 @@ Capture lexer_CaptureRept() {
case T_(POP_REPT): case T_(POP_REPT):
case T_(POP_FOR): case T_(POP_FOR):
depth++; depth++;
// Ignore the rest of that line break; // Ignore the rest of that line
break;
case T_(POP_ENDR): case T_(POP_ENDR):
if (!depth) { if (depth) {
depth--;
break; // Ignore the rest of that line
}
endCapture(capture); endCapture(capture);
// The final ENDR has been captured, but we don't want it! // The final ENDR has been captured, but we don't want it!
// We know we have read exactly "ENDR", not e.g. an EQUS // We know we have read exactly "ENDR", not e.g. an EQUS
capture.span.size -= literal_strlen("ENDR"); capture.span.size -= literal_strlen("ENDR");
return capture; return capture;
}
depth--;
break;
default: default:
break; break;

View File

@@ -1032,8 +1032,7 @@ static void
// This should be guaranteed from the size cap... // This should be guaranteed from the size cap...
static_assert(0x10000 * BANK_SIZE <= SSIZE_MAX, "Max input file size too large for OS"); static_assert(0x10000 * BANK_SIZE <= SSIZE_MAX, "Max input file size too large for OS");
// Compute number of banks and ROMX len from file size // Compute number of banks and ROMX len from file size
nbBanks = (fileSize + (BANK_SIZE - 1)) / BANK_SIZE; nbBanks = (fileSize + (BANK_SIZE - 1)) / BANK_SIZE; // ceil(fileSize / BANK_SIZE)
// = ceil(totalRomxLen / BANK_SIZE)
totalRomxLen = fileSize >= BANK_SIZE ? fileSize - BANK_SIZE : 0; totalRomxLen = fileSize >= BANK_SIZE ? fileSize - BANK_SIZE : 0;
} else if (rom0Len == BANK_SIZE) { } else if (rom0Len == BANK_SIZE) {
// Copy ROMX when reading a pipe, and we're not at EOF yet // Copy ROMX when reading a pipe, and we're not at EOF yet

View File

@@ -20,8 +20,8 @@
// The solvers here are picked from the paper at https://arxiv.org/abs/1605.00558: // The solvers here are picked from the paper at https://arxiv.org/abs/1605.00558:
// "Algorithms for the Pagination Problem, a Bin Packing with Overlapping Items" // "Algorithms for the Pagination Problem, a Bin Packing with Overlapping Items"
// Their formulation of the problem consists in packing "tiles" into "pages"; here is a // Their formulation of the problem consists in packing "tiles" into "pages".
// correspondence table for our application of it: // Here is a correspondence table for our application of it:
// Paper | RGBGFX // Paper | RGBGFX
// ------+------- // ------+-------
// Tile | Proto-palette // Tile | Proto-palette