Use automatic allocation for IF stacks and expansions

Switch to using `std::deque` for IF stacks (supports `.clear()`)
This commit is contained in:
Rangi42
2024-02-26 14:09:07 -05:00
committed by Sylvie
parent 31836967fa
commit af055ecd27
2 changed files with 23 additions and 31 deletions

View File

@@ -4,7 +4,6 @@
#define RGBDS_ASM_LEXER_H #define RGBDS_ASM_LEXER_H
#include <deque> #include <deque>
#include <stack>
#include "platform.hpp" // SSIZE_MAX #include "platform.hpp" // SSIZE_MAX
@@ -74,7 +73,7 @@ struct LexerState {
uint32_t colNo; uint32_t colNo;
int lastToken; int lastToken;
std::stack<struct IfStackEntry> *ifStack; std::deque<struct IfStackEntry> ifStack;
bool capturing; // Whether the text being lexed should be captured bool capturing; // Whether the text being lexed should be captured
size_t captureSize; // Amount of text captured size_t captureSize; // Amount of text captured
@@ -85,7 +84,7 @@ struct LexerState {
bool disableInterpolation; bool disableInterpolation;
size_t macroArgScanDistance; // Max distance already scanned for macro args size_t macroArgScanDistance; // Max distance already scanned for macro args
bool expandStrings; bool expandStrings;
std::deque<struct Expansion> *expansions; // Front is the innermost current expansion std::deque<struct Expansion> expansions; // Front is the innermost current expansion
}; };
extern struct LexerState *lexerState; extern struct LexerState *lexerState;

View File

@@ -10,7 +10,6 @@
#include <limits.h> #include <limits.h>
#include <math.h> #include <math.h>
#include <new> #include <new>
#include <stack>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -294,9 +293,7 @@ static void initState(struct LexerState &state)
state.atLineStart = true; // yylex() will init colNo due to this state.atLineStart = true; // yylex() will init colNo due to this
state.lastToken = T_EOF; state.lastToken = T_EOF;
state.ifStack = new(std::nothrow) std::stack<struct IfStackEntry>(); state.ifStack.clear();
if (!state.ifStack)
fatalerror("Unable to allocate new IF stack: %s\n", strerror(errno));
state.capturing = false; state.capturing = false;
state.captureBuf = NULL; state.captureBuf = NULL;
@@ -306,9 +303,7 @@ static void initState(struct LexerState &state)
state.macroArgScanDistance = 0; state.macroArgScanDistance = 0;
state.expandStrings = true; state.expandStrings = true;
state.expansions = new(std::nothrow) std::deque<struct Expansion>(); state.expansions.clear();
if (!state.expansions)
fatalerror("Unable to allocate new expansion stack: %s\n", strerror(errno));
} }
static void nextLine(void) static void nextLine(void)
@@ -319,40 +314,40 @@ static void nextLine(void)
uint32_t lexer_GetIFDepth(void) uint32_t lexer_GetIFDepth(void)
{ {
return lexerState->ifStack->size(); return lexerState->ifStack.size();
} }
void lexer_IncIFDepth(void) void lexer_IncIFDepth(void)
{ {
lexerState->ifStack->push({ .ranIfBlock = false, .reachedElseBlock = false }); lexerState->ifStack.push_front({ .ranIfBlock = false, .reachedElseBlock = false });
} }
void lexer_DecIFDepth(void) void lexer_DecIFDepth(void)
{ {
if (lexerState->ifStack->empty()) if (lexerState->ifStack.empty())
fatalerror("Found ENDC outside an IF construct\n"); fatalerror("Found ENDC outside an IF construct\n");
lexerState->ifStack->pop(); lexerState->ifStack.pop_front();
} }
bool lexer_RanIFBlock(void) bool lexer_RanIFBlock(void)
{ {
return lexerState->ifStack->top().ranIfBlock; return lexerState->ifStack.front().ranIfBlock;
} }
bool lexer_ReachedELSEBlock(void) bool lexer_ReachedELSEBlock(void)
{ {
return lexerState->ifStack->top().reachedElseBlock; return lexerState->ifStack.front().reachedElseBlock;
} }
void lexer_RunIFBlock(void) void lexer_RunIFBlock(void)
{ {
lexerState->ifStack->top().ranIfBlock = true; lexerState->ifStack.front().ranIfBlock = true;
} }
void lexer_ReachELSEBlock(void) void lexer_ReachELSEBlock(void)
{ {
lexerState->ifStack->top().reachedElseBlock = true; lexerState->ifStack.front().reachedElseBlock = true;
} }
bool lexer_OpenFile(struct LexerState &state, char const *path) bool lexer_OpenFile(struct LexerState &state, char const *path)
@@ -461,8 +456,6 @@ void lexer_DeleteState(struct LexerState &state)
close(state.cbuf.fd); close(state.cbuf.fd);
else if (state.isFile && !state.mmap.isReferenced) else if (state.isFile && !state.mmap.isReferenced)
munmap(state.mmap.ptr, state.mmap.size); munmap(state.mmap.ptr, state.mmap.size);
delete state.ifStack;
delete state.expansions;
} }
struct KeywordDictNode { struct KeywordDictNode {
@@ -560,7 +553,7 @@ static void beginExpansion(char const *str, bool owned, char const *name)
if (name) if (name)
lexer_CheckRecursionDepth(); lexer_CheckRecursionDepth();
lexerState->expansions->push_front({ lexerState->expansions.push_front({
.name = name ? strdup(name) : NULL, .name = name ? strdup(name) : NULL,
.contents = { .unowned = str }, .contents = { .unowned = str },
.size = size, .size = size,
@@ -571,7 +564,7 @@ static void beginExpansion(char const *str, bool owned, char const *name)
void lexer_CheckRecursionDepth(void) void lexer_CheckRecursionDepth(void)
{ {
if (lexerState->expansions->size() > maxRecursionDepth + 1) if (lexerState->expansions.size() > maxRecursionDepth + 1)
fatalerror("Recursion limit (%zu) exceeded\n", maxRecursionDepth); fatalerror("Recursion limit (%zu) exceeded\n", maxRecursionDepth);
} }
@@ -706,7 +699,7 @@ static size_t readInternal(size_t bufIndex, size_t nbChars)
// We only need one character of lookahead, for macro arguments // We only need one character of lookahead, for macro arguments
static int peekInternal(uint8_t distance) static int peekInternal(uint8_t distance)
{ {
for (struct Expansion &exp : *lexerState->expansions) { for (struct Expansion &exp : lexerState->expansions) {
// An expansion that has reached its end will have `exp->offset` == `exp->size`, // An expansion that has reached its end will have `exp->offset` == `exp->size`,
// and `peekInternal` will continue with its parent // and `peekInternal` will continue with its parent
assert(exp.offset <= exp.size); assert(exp.offset <= exp.size);
@@ -825,9 +818,9 @@ static void shiftChar(void)
lexerState->macroArgScanDistance--; lexerState->macroArgScanDistance--;
restart: restart:
if (!lexerState->expansions->empty()) { if (!lexerState->expansions.empty()) {
// Advance within the current expansion // Advance within the current expansion
struct Expansion &expansion = lexerState->expansions->front(); struct Expansion &expansion = lexerState->expansions.front();
assert(expansion.offset <= expansion.size); assert(expansion.offset <= expansion.size);
expansion.offset++; expansion.offset++;
@@ -835,7 +828,7 @@ restart:
// When advancing would go past an expansion's end, free it, // When advancing would go past an expansion's end, free it,
// move up to its parent, and try again to advance // move up to its parent, and try again to advance
freeExpansion(expansion); freeExpansion(expansion);
lexerState->expansions->pop_front(); lexerState->expansions.pop_front();
goto restart; goto restart;
} }
} else { } else {
@@ -892,7 +885,7 @@ void lexer_DumpStringExpansions(void)
if (!lexerState) if (!lexerState)
return; return;
for (struct Expansion &exp : *lexerState->expansions) { for (struct Expansion &exp : lexerState->expansions) {
// Only register EQUS expansions, not string args // Only register EQUS expansions, not string args
if (exp.name) if (exp.name)
fprintf(stderr, "while expanding symbol \"%s\"\n", exp.name); fprintf(stderr, "while expanding symbol \"%s\"\n", exp.name);
@@ -916,7 +909,7 @@ static void discardBlockComment(void)
handleCRLF(c); handleCRLF(c);
// fallthrough // fallthrough
case '\n': case '\n':
if (lexerState->expansions->empty()) if (lexerState->expansions.empty())
nextLine(); nextLine();
continue; continue;
case '/': case '/':
@@ -969,7 +962,7 @@ static void readLineContinuation(void)
shiftChar(); shiftChar();
// Handle CRLF before nextLine() since shiftChar updates colNo // Handle CRLF before nextLine() since shiftChar updates colNo
handleCRLF(c); handleCRLF(c);
if (lexerState->expansions->empty()) if (lexerState->expansions.empty())
nextLine(); nextLine();
break; break;
} else if (c == ';') { } else if (c == ';') {
@@ -2322,7 +2315,7 @@ int yylex(void)
if (lexerState->lastToken == T_EOB && yywrap()) if (lexerState->lastToken == T_EOB && yywrap())
return T_EOF; return T_EOF;
// Newlines read within an expansion should not increase the line count // Newlines read within an expansion should not increase the line count
if (lexerState->atLineStart && lexerState->expansions->empty()) if (lexerState->atLineStart && lexerState->expansions.empty())
nextLine(); nextLine();
static int (* const lexerModeFuncs[NB_LEXER_MODES])(void) = { static int (* const lexerModeFuncs[NB_LEXER_MODES])(void) = {
@@ -2353,7 +2346,7 @@ static void startCapture(struct CaptureBody *capture)
capture->lineNo = lexer_GetLineNo(); capture->lineNo = lexer_GetLineNo();
if (lexerState->isMmapped && lexerState->expansions->empty()) { if (lexerState->isMmapped && lexerState->expansions.empty()) {
capture->body = &lexerState->mmap.ptr[lexerState->mmap.offset]; capture->body = &lexerState->mmap.ptr[lexerState->mmap.offset];
} else { } else {
lexerState->captureCapacity = 128; // The initial size will be twice that lexerState->captureCapacity = 128; // The initial size will be twice that